diff --git a/internal/cache/domain/domain.go b/internal/cache/domain/domain.go index 864d85428..37e97472a 100644 --- a/internal/cache/domain/domain.go +++ b/internal/cache/domain/domain.go @@ -80,6 +80,14 @@ func (b *BlockCache) Clear() { atomic.StorePointer(&b.rootptr, nil) } +// String returns a string representation of stored domains in block cache. +func (b *BlockCache) String() string { + if ptr := atomic.LoadPointer(&b.rootptr); ptr != nil { + return (*root)(ptr).String() + } + return "" +} + // root is the root node in the domain // block cache radix trie. this is the // singular access point to the trie. @@ -104,6 +112,13 @@ func (r *root) Sort() { r.root.sort() } +// String returns a string representation of node (and its descendants). +func (r *root) String() string { + buf := new(strings.Builder) + r.root.writestr(buf, "") + return buf.String() +} + type node struct { part string child []*node @@ -152,12 +167,7 @@ func (n *node) add(parts []string) { } func (n *node) match(parts []string) bool { - if len(parts) == 0 { - // Invalid domain. - return false - } - - for { + for len(parts) > 0 { // Pop next domain part. i := len(parts) - 1 part := parts[i] @@ -181,6 +191,10 @@ func (n *node) match(parts []string) bool { // child node. n = nn } + + // Ran out of parts + // without a match. + return false } // getChild fetches child node with given domain part string @@ -222,3 +236,22 @@ func (n *node) sort() { child.sort() } } + +func (n *node) writestr(buf *strings.Builder, prefix string) { + if prefix != "" { + // Suffix joining '.' + prefix += "." + } + + // Append current part. + prefix += n.part + + // Dump current prefix state. + buf.WriteString(prefix) + buf.WriteByte('\n') + + // Iterate through node children. + for _, child := range n.child { + child.writestr(buf, prefix) + } +} diff --git a/internal/cache/domain/domain_test.go b/internal/cache/domain/domain_test.go index b5937978c..8f975497b 100644 --- a/internal/cache/domain/domain_test.go +++ b/internal/cache/domain/domain_test.go @@ -69,7 +69,9 @@ func TestBlockCache(t *testing.T) { } // Clear the cache + t.Logf("%+v\n", c) c.Clear() + t.Logf("%+v\n", c) knownErr := errors.New("known error")