plugin/file: Rename do to walk and cleanup and document (#2987)

* plugin/file: Rename do to walk, cleanup and document

* This renames Do to Walk to be more inline with Go standards. Also make
  it return an error instead of a bool.
  Also give give walk access to rrs. Alternatively e.m could be
  exported, but just access the map of rrs should work as well. Another
  alternative would be adding a whole bunch of helper functions, but
  those need grab and return the data. Just having access to the rrs
  should be easiest for most Walks.
* It adds Type and TypeForWildcard to show the different functions
* *Removes* the identical RR check when inserting; this was only done
  for A, AAAA and MX and not finished; removed under the mantra garbage
  in garbage out.
* Reuses Types to return all the types in an *tree.Elem

Signed-off-by: Miek Gieben <miek@miek.nl>

* better comments

Signed-off-by: Miek Gieben <miek@miek.nl>
This commit is contained in:
Miek Gieben
2019-07-18 17:44:47 +00:00
committed by GitHub
parent 527772fc5f
commit 1d5095cf67
7 changed files with 154 additions and 123 deletions

View File

@@ -15,20 +15,34 @@ func newElem(rr dns.RR) *Elem {
return &e
}
// Types returns the RRs with type qtype from e. If qname is given (only the
// first one is used), the RR are copied and the owner is replaced with qname[0].
func (e *Elem) Types(qtype uint16, qname ...string) []dns.RR {
// Types returns the types of the records in e. The returned list is not sorted.
func (e *Elem) Types() []uint16 {
t := make([]uint16, len(e.m))
i := 0
for ty := range e.m {
t[i] = ty
i++
}
return t
}
// Type returns the RRs with type qtype from e.
func (e *Elem) Type(qtype uint16) []dns.RR { return e.m[qtype] }
// TypeForWildcard returns the RRs with type qtype from e. The ownername returned is set to qname.
func (e *Elem) TypeForWildcard(qtype uint16, qname string) []dns.RR {
rrs := e.m[qtype]
if rrs != nil && len(qname) > 0 {
copied := make([]dns.RR, len(rrs))
for i := range rrs {
copied[i] = dns.Copy(rrs[i])
copied[i].Header().Name = qname[0]
}
return copied
if rrs == nil {
return nil
}
return rrs
copied := make([]dns.RR, len(rrs))
for i := range rrs {
copied[i] = dns.Copy(rrs[i])
copied[i].Header().Name = qname
}
return copied
}
// All returns all RRs from e, regardless of type.
@@ -52,13 +66,10 @@ func (e *Elem) Name() string {
return ""
}
// Empty returns true is e does not contain any RRs, i.e. is an
// empty-non-terminal.
func (e *Elem) Empty() bool {
return len(e.m) == 0
}
// Empty returns true is e does not contain any RRs, i.e. is an empty-non-terminal.
func (e *Elem) Empty() bool { return len(e.m) == 0 }
// Insert inserts rr into e. If rr is equal to existing rrs this is a noop.
// Insert inserts rr into e. If rr is equal to existing RRs, the RR will be added anyway.
func (e *Elem) Insert(rr dns.RR) {
t := rr.Header().Rrtype
if e.m == nil {
@@ -71,66 +82,20 @@ func (e *Elem) Insert(rr dns.RR) {
e.m[t] = []dns.RR{rr}
return
}
for _, er := range rrs {
if equalRdata(er, rr) {
return
}
}
rrs = append(rrs, rr)
e.m[t] = rrs
}
// Delete removes rr from e. When e is empty after the removal the returned bool is true.
func (e *Elem) Delete(rr dns.RR) (empty bool) {
// Delete removes all RRs of type rr.Header().Rrtype from e.
func (e *Elem) Delete(rr dns.RR) {
if e.m == nil {
return true
}
t := rr.Header().Rrtype
rrs, ok := e.m[t]
if !ok {
return
}
for i, er := range rrs {
if equalRdata(er, rr) {
rrs = removeFromSlice(rrs, i)
e.m[t] = rrs
empty = len(rrs) == 0
if empty {
delete(e.m, t)
}
return
}
}
return
t := rr.Header().Rrtype
delete(e.m, t)
}
// Less is a tree helper function that calls less.
func Less(a *Elem, name string) int { return less(name, a.Name()) }
// Assuming the same type and name this will check if the rdata is equal as well.
func equalRdata(a, b dns.RR) bool {
switch x := a.(type) {
// TODO(miek): more types, i.e. all types. + tests for this.
case *dns.A:
return x.A.Equal(b.(*dns.A).A)
case *dns.AAAA:
return x.AAAA.Equal(b.(*dns.AAAA).AAAA)
case *dns.MX:
if x.Mx == b.(*dns.MX).Mx && x.Preference == b.(*dns.MX).Preference {
return true
}
}
return false
}
// removeFromSlice removes index i from the slice.
func removeFromSlice(rrs []dns.RR, i int) []dns.RR {
if i >= len(rrs) {
return rrs
}
rrs = append(rrs[:i], rrs[i+1:]...)
return rrs
}