chore: trie.DomainTrie will not depend on zero value

This commit is contained in:
wwqgtxx
2022-11-02 22:28:18 +08:00
parent c34c5ff1f9
commit 22fb219ad8
12 changed files with 66 additions and 48 deletions

View File

@@ -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

View File

@@ -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)

View File

@@ -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,

View File

@@ -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]()}
}

View File

@@ -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 {

View File

@@ -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
}