chore: trie.DomainTrie will not depend on zero value
This commit is contained in:
@@ -34,7 +34,7 @@ type Pool struct {
|
||||
offset netip.Addr
|
||||
cycle bool
|
||||
mux sync.Mutex
|
||||
host *trie.DomainTrie[bool]
|
||||
host *trie.DomainTrie[struct{}]
|
||||
ipnet *netip.Prefix
|
||||
store store
|
||||
}
|
||||
@@ -150,7 +150,7 @@ func (p *Pool) restoreState() {
|
||||
|
||||
type Options struct {
|
||||
IPNet *netip.Prefix
|
||||
Host *trie.DomainTrie[bool]
|
||||
Host *trie.DomainTrie[struct{}]
|
||||
|
||||
// Size sets the maximum number of entries in memory
|
||||
// and does not work if Persistence is true
|
||||
|
||||
@@ -127,7 +127,7 @@ func ResolveAllIPv6WithResolver(host string, r Resolver) ([]netip.Addr, error) {
|
||||
}
|
||||
|
||||
if node := DefaultHosts.Search(host); node != nil {
|
||||
if ip := node.Data; ip.Is6() {
|
||||
if ip := node.Data(); ip.Is6() {
|
||||
return []netip.Addr{ip}, nil
|
||||
}
|
||||
}
|
||||
@@ -161,8 +161,8 @@ func ResolveAllIPv6WithResolver(host string, r Resolver) ([]netip.Addr, error) {
|
||||
|
||||
func ResolveAllIPv4WithResolver(host string, r Resolver) ([]netip.Addr, error) {
|
||||
if node := DefaultHosts.Search(host); node != nil {
|
||||
if ip := node.Data; ip.Is4() {
|
||||
return []netip.Addr{node.Data}, nil
|
||||
if ip := node.Data(); ip.Is4() {
|
||||
return []netip.Addr{node.Data()}, nil
|
||||
}
|
||||
}
|
||||
|
||||
@@ -200,7 +200,7 @@ func ResolveAllIPv4WithResolver(host string, r Resolver) ([]netip.Addr, error) {
|
||||
|
||||
func ResolveAllIPWithResolver(host string, r Resolver) ([]netip.Addr, error) {
|
||||
if node := DefaultHosts.Search(host); node != nil {
|
||||
return []netip.Addr{node.Data}, nil
|
||||
return []netip.Addr{node.Data()}, nil
|
||||
}
|
||||
|
||||
ip, err := netip.ParseAddr(host)
|
||||
|
||||
@@ -31,8 +31,8 @@ type SnifferDispatcher struct {
|
||||
|
||||
sniffers []sniffer.Sniffer
|
||||
|
||||
forceDomain *trie.DomainTrie[bool]
|
||||
skipSNI *trie.DomainTrie[bool]
|
||||
forceDomain *trie.DomainTrie[struct{}]
|
||||
skipSNI *trie.DomainTrie[struct{}]
|
||||
portRanges *[]utils.Range[uint16]
|
||||
skipList *cache.LruCache[string, uint8]
|
||||
rwMux sync.RWMutex
|
||||
@@ -183,8 +183,8 @@ func NewCloseSnifferDispatcher() (*SnifferDispatcher, error) {
|
||||
return &dispatcher, nil
|
||||
}
|
||||
|
||||
func NewSnifferDispatcher(needSniffer []sniffer.Type, forceDomain *trie.DomainTrie[bool],
|
||||
skipSNI *trie.DomainTrie[bool], ports *[]utils.Range[uint16],
|
||||
func NewSnifferDispatcher(needSniffer []sniffer.Type, forceDomain *trie.DomainTrie[struct{}],
|
||||
skipSNI *trie.DomainTrie[struct{}], ports *[]utils.Range[uint16],
|
||||
forceDnsMapping bool, parsePureIp bool) (*SnifferDispatcher, error) {
|
||||
dispatcher := SnifferDispatcher{
|
||||
enable: true,
|
||||
|
||||
@@ -17,7 +17,7 @@ var ErrInvalidDomain = errors.New("invalid domain")
|
||||
|
||||
// DomainTrie contains the main logic for adding and searching nodes for domain segments.
|
||||
// support wildcard domain (e.g *.google.com)
|
||||
type DomainTrie[T comparable] struct {
|
||||
type DomainTrie[T any] struct {
|
||||
root *Node[T]
|
||||
}
|
||||
|
||||
@@ -74,13 +74,13 @@ func (t *DomainTrie[T]) insert(parts []string, data T) {
|
||||
for i := len(parts) - 1; i >= 0; i-- {
|
||||
part := parts[i]
|
||||
if !node.hasChild(part) {
|
||||
node.addChild(part, newNode(getZero[T]()))
|
||||
node.addChild(part, newNode[T]())
|
||||
}
|
||||
|
||||
node = node.getChild(part)
|
||||
}
|
||||
|
||||
node.Data = data
|
||||
node.setData(data)
|
||||
}
|
||||
|
||||
// Search is the most important part of the Trie.
|
||||
@@ -96,7 +96,7 @@ func (t *DomainTrie[T]) Search(domain string) *Node[T] {
|
||||
|
||||
n := t.search(t.root, parts)
|
||||
|
||||
if n == nil || n.Data == getZero[T]() {
|
||||
if n.isEmpty() {
|
||||
return nil
|
||||
}
|
||||
|
||||
@@ -109,13 +109,13 @@ func (t *DomainTrie[T]) search(node *Node[T], parts []string) *Node[T] {
|
||||
}
|
||||
|
||||
if c := node.getChild(parts[len(parts)-1]); c != nil {
|
||||
if n := t.search(c, parts[:len(parts)-1]); n != nil && n.Data != getZero[T]() {
|
||||
if n := t.search(c, parts[:len(parts)-1]); !n.isEmpty() {
|
||||
return n
|
||||
}
|
||||
}
|
||||
|
||||
if c := node.getChild(wildcard); c != nil {
|
||||
if n := t.search(c, parts[:len(parts)-1]); n != nil && n.Data != getZero[T]() {
|
||||
if n := t.search(c, parts[:len(parts)-1]); !n.isEmpty() {
|
||||
return n
|
||||
}
|
||||
}
|
||||
@@ -124,6 +124,6 @@ func (t *DomainTrie[T]) search(node *Node[T], parts []string) *Node[T] {
|
||||
}
|
||||
|
||||
// New returns a new, empty Trie.
|
||||
func New[T comparable]() *DomainTrie[T] {
|
||||
return &DomainTrie[T]{root: newNode[T](getZero[T]())}
|
||||
func New[T any]() *DomainTrie[T] {
|
||||
return &DomainTrie[T]{root: newNode[T]()}
|
||||
}
|
||||
|
||||
@@ -23,7 +23,7 @@ func TestTrie_Basic(t *testing.T) {
|
||||
|
||||
node := tree.Search("example.com")
|
||||
assert.NotNil(t, node)
|
||||
assert.True(t, node.Data == localIP)
|
||||
assert.True(t, node.Data() == localIP)
|
||||
assert.NotNil(t, tree.Insert("", localIP))
|
||||
assert.Nil(t, tree.Search(""))
|
||||
assert.NotNil(t, tree.Search("localhost"))
|
||||
@@ -75,7 +75,7 @@ func TestTrie_Priority(t *testing.T) {
|
||||
assertFn := func(domain string, data int) {
|
||||
node := tree.Search(domain)
|
||||
assert.NotNil(t, node)
|
||||
assert.Equal(t, data, node.Data)
|
||||
assert.Equal(t, data, node.Data())
|
||||
}
|
||||
|
||||
for idx, domain := range domains {
|
||||
|
||||
@@ -1,9 +1,10 @@
|
||||
package trie
|
||||
|
||||
// Node is the trie's node
|
||||
type Node[T comparable] struct {
|
||||
type Node[T any] struct {
|
||||
children map[string]*Node[T]
|
||||
Data T
|
||||
inited bool
|
||||
data T
|
||||
}
|
||||
|
||||
func (n *Node[T]) getChild(s string) *Node[T] {
|
||||
@@ -18,14 +19,31 @@ func (n *Node[T]) addChild(s string, child *Node[T]) {
|
||||
n.children[s] = child
|
||||
}
|
||||
|
||||
func newNode[T comparable](data T) *Node[T] {
|
||||
func (n *Node[T]) isEmpty() bool {
|
||||
if n == nil || n.inited == false {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func (n *Node[T]) setData(data T) {
|
||||
n.data = data
|
||||
n.inited = true
|
||||
}
|
||||
|
||||
func (n *Node[T]) Data() T {
|
||||
return n.data
|
||||
}
|
||||
|
||||
func newNode[T any]() *Node[T] {
|
||||
return &Node[T]{
|
||||
Data: data,
|
||||
children: map[string]*Node[T]{},
|
||||
inited: false,
|
||||
data: getZero[T](),
|
||||
}
|
||||
}
|
||||
|
||||
func getZero[T comparable]() T {
|
||||
func getZero[T any]() T {
|
||||
var result T
|
||||
return result
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user