github.com/searKing/golang/go@v1.2.117/container/trie_tree/ternary_search_tree/node.go (about)

     1  // Copyright 2020 The searKing Author. All rights reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package ternary_search_tree
     6  
     7  import (
     8  	"fmt"
     9  	"strings"
    10  
    11  	"github.com/searKing/golang/go/container/traversal"
    12  )
    13  
    14  const (
    15  	NilKey = 0
    16  )
    17  
    18  type node struct {
    19  	prefix   []byte
    20  	key      byte
    21  	hasKey   bool
    22  	value    any
    23  	hasValue bool
    24  
    25  	left, middle, right *node
    26  	tree                *TernarySearchTree
    27  }
    28  
    29  func (n *node) LeftNodes() []any {
    30  	left := n.Left()
    31  	if left == nil {
    32  		return nil
    33  	}
    34  	return []any{left}
    35  }
    36  
    37  func (n *node) MiddleNodes() []any {
    38  	middle := n.Middle()
    39  	if middle == nil {
    40  		return nil
    41  	}
    42  	return []any{middle}
    43  }
    44  
    45  func (n *node) RightNodes() []any {
    46  	right := n.Right()
    47  	if right == nil {
    48  		return nil
    49  	}
    50  	return []any{right}
    51  }
    52  
    53  // Left returns the left list node or nil.
    54  func (n *node) Left() *node {
    55  	if p := n.left; n.tree != nil && p != &n.tree.root {
    56  		return p
    57  	}
    58  	return nil
    59  }
    60  
    61  // Middle returns the middle list node or nil.
    62  func (n *node) Middle() *node {
    63  	if p := n.middle; n.tree != nil && p != &n.tree.root {
    64  		return p
    65  	}
    66  	return nil
    67  }
    68  
    69  // Right returns the right list node or nil.
    70  func (n *node) Right() *node {
    71  	if p := n.right; n.tree != nil && p != &n.tree.root {
    72  		return p
    73  	}
    74  	return nil
    75  }
    76  
    77  func (n *node) Traversal(order traversal.Order, handler Handler) {
    78  	if handler == nil {
    79  		return
    80  	}
    81  	if !n.hasKey {
    82  		return
    83  	}
    84  	order(n, traversal.HandlerFunc(func(ele any, depth int) (goon bool) {
    85  		currentNode := ele.(*node)
    86  		if !currentNode.hasKey || !currentNode.hasValue {
    87  			return true
    88  		}
    89  		return handler.Handle(currentNode.prefix, currentNode.value)
    90  	}))
    91  	return
    92  }
    93  
    94  func (n *node) Follow(prefix []byte) (key []byte, value any, ok bool) {
    95  	graph := n.follow(prefix)
    96  	if len(graph) == 0 {
    97  		return nil, nil, false
    98  	}
    99  	tail := graph[len(graph)-1]
   100  	return tail.prefix, tail.value, tail.hasValue
   101  }
   102  
   103  func (n *node) Load(prefix []byte) (value any, ok bool) {
   104  	cur, _, _, has := n.search(prefix)
   105  	if !has {
   106  		return nil, false
   107  	}
   108  	return cur.value, cur.hasValue
   109  }
   110  
   111  func (n *node) ContainsPrefix(prefix []byte) bool {
   112  	cur, _, _, has := n.search(prefix)
   113  	if !has {
   114  		return false
   115  	}
   116  	return cur.hasKey
   117  }
   118  
   119  func (n *node) Contains(prefix []byte) bool {
   120  	_, ok := n.Load(prefix)
   121  	return ok
   122  }
   123  
   124  type pos int
   125  
   126  const (
   127  	posNotFound pos = iota // Root's middle, default
   128  	posLeft
   129  	posMiddle
   130  	posRight
   131  	posRoot
   132  )
   133  
   134  func (n *node) Store(prefix []byte, value any) {
   135  	// force update
   136  	n.CAS(prefix, nil, value, func(x, y any) int { return 0 })
   137  }
   138  
   139  func (n *node) remove(prefix []byte, shrinkToFit bool, omitMiddle bool) (old any, ok bool) {
   140  	cur, last, lastPos, has := n.search(prefix)
   141  	if !has {
   142  		return nil, false
   143  	}
   144  	// shrinkToFit if cur's children are empty
   145  	if shrinkToFit {
   146  		cur.shrinkToFit(last, lastPos, omitMiddle)
   147  	}
   148  
   149  	if !cur.hasValue {
   150  		return nil, false
   151  	}
   152  	cur.hasValue = false
   153  	// all matched, goto remove the old
   154  	return cur.value, true
   155  }
   156  
   157  func (n *node) Remove(prefix []byte, shrinkToFit bool) (old any, ok bool) {
   158  	return n.remove(prefix, shrinkToFit, false)
   159  }
   160  
   161  func (n *node) RemoveAll(prefix []byte) (value any, ok bool) {
   162  	return n.remove(prefix, true, true)
   163  }
   164  
   165  func (n *node) String() string {
   166  	s := ""
   167  	n.Traversal(traversal.Inorder, HandlerFunc(func(prefix []byte, value any) (goon bool) {
   168  		s += fmt.Sprintf("%s:%v\n", string(prefix), value)
   169  		return true
   170  	}))
   171  
   172  	return strings.TrimRight(s, "\n")
   173  }
   174  
   175  func (n *node) CAS(prefix []byte, old, new any, cmps ...func(x, y any) int) bool {
   176  	newElement := func(prefix []byte, hasKey bool, key byte, hasValue bool, value any) *node {
   177  		var p = make([]byte, len(prefix))
   178  		copy(p, prefix)
   179  		return &node{
   180  			prefix:   p,
   181  			key:      key,
   182  			hasKey:   hasKey,
   183  			value:    value,
   184  			hasValue: hasValue,
   185  			left:     &n.tree.root,
   186  			middle:   &n.tree.root,
   187  			right:    &n.tree.root,
   188  			tree:     n.tree,
   189  		}
   190  	}
   191  
   192  	cur := n
   193  	for idx := 0; idx < len(prefix); {
   194  		// create the idx layer if not exist
   195  		// otherwise, step to the next layer
   196  		k := prefix[idx]
   197  		if !cur.hasKey {
   198  			cur.key = k
   199  			cur.hasKey = true
   200  			cur.prefix = prefix[:idx+1]
   201  		}
   202  		// goto left
   203  		if k < cur.key {
   204  			left := cur.Left()
   205  			if left == nil {
   206  				cur.left = newElement(prefix[:idx+1], true, k, false, nil)
   207  			}
   208  			cur = cur.left
   209  			continue
   210  		}
   211  		// goto right
   212  		if k > cur.key {
   213  			right := cur.Right()
   214  			if right == nil {
   215  				cur.right = newElement(prefix[:idx+1], true, k, false, nil)
   216  			}
   217  			cur = cur.right
   218  			continue
   219  		}
   220  		// key match, goto match next layer
   221  		idx++
   222  		// all matched, goto set the value
   223  		if idx == len(prefix) {
   224  			// no old
   225  			if !cur.hasValue {
   226  				cur.value = new
   227  				cur.hasValue = true
   228  				return true
   229  			}
   230  			var cmp func(x, y any) int
   231  			if len(cmps) > 0 {
   232  				cmp = cmps[0]
   233  			}
   234  			if cmp == nil {
   235  				cmp = func(x, y any) int {
   236  					if x == y {
   237  						return 0
   238  					}
   239  					return -1
   240  				}
   241  			}
   242  			if cmp(cur.value, old) == 0 {
   243  				cur.value = new
   244  				cur.hasValue = true
   245  				return true
   246  			}
   247  			return false
   248  		}
   249  		// partial matched, goto middle on next layer
   250  		middle := cur.Middle()
   251  		if middle == nil {
   252  			cur.middle = newElement(nil, false, NilKey, false, nil)
   253  		}
   254  		cur = cur.middle
   255  	}
   256  	// never reach
   257  	return false
   258  }
   259  
   260  // Depth return max len of all prefixs
   261  func (n *node) Depth() int {
   262  	var depth int
   263  	n.Traversal(traversal.Preorder, HandlerFunc(func(prefix []byte, value any) (goon bool) {
   264  		if depth < len(prefix) {
   265  			depth = len(prefix)
   266  		}
   267  		return true
   268  	}))
   269  	return depth
   270  }
   271  
   272  // shrinkToFit cutoff last node's children nodes if all children nodes are empty
   273  func (n *node) shrinkToFit(last *node, lastPos pos, omitMiddle bool) {
   274  	var has bool
   275  	n.Traversal(traversal.Preorder, HandlerFunc(func(prefix []byte, value any) (goon bool) {
   276  		has = true
   277  		return false
   278  	}))
   279  	if !has {
   280  		return
   281  	}
   282  
   283  	// match
   284  	switch lastPos {
   285  	case posLeft:
   286  		n.shrinkLeft(last, omitMiddle)
   287  	case posMiddle:
   288  		n.shrinkMiddle(last, omitMiddle)
   289  	case posRight:
   290  		n.shrinkRight(last, omitMiddle)
   291  	case posRoot:
   292  		n.shrinkRoot(last, omitMiddle)
   293  	}
   294  }
   295  
   296  // return node graph until prefix matched
   297  func (n *node) follow(prefix []byte) (graph []*node) {
   298  	cur := n
   299  
   300  	for idx := 0; idx < len(prefix); {
   301  		// return if nilKey has been meet
   302  		if !cur.hasKey {
   303  			return
   304  		}
   305  		// create the idx layer if not exist
   306  		// otherwise, step to the next layer
   307  		k := prefix[idx]
   308  		if k < cur.key {
   309  			left := cur.Left()
   310  			if left == nil {
   311  				return
   312  			}
   313  			cur = left
   314  			continue
   315  		}
   316  		if k > cur.key {
   317  			right := cur.Right()
   318  			if right == nil {
   319  				return
   320  			}
   321  			cur = right
   322  			continue
   323  		}
   324  		if cur.hasValue {
   325  			graph = append(graph, cur)
   326  		}
   327  		// key match, goto match next layer
   328  		idx++
   329  		// all matched, goto remove the value
   330  		if idx == len(prefix) {
   331  			// match
   332  			return
   333  		}
   334  		// partial matched, goto middle on next layer
   335  		middle := cur.Middle()
   336  		if middle == nil {
   337  			return
   338  		}
   339  		cur = middle
   340  	}
   341  	return
   342  }
   343  
   344  // return true if prefix matches, no matter value exists
   345  func (n *node) search(prefix []byte) (cur, last *node, lastPos pos, has bool) {
   346  	cur = n
   347  	last = n
   348  
   349  	lastPos = posNotFound
   350  	for idx := 0; idx < len(prefix); {
   351  		// return if nilKey has been met
   352  		if !cur.hasKey {
   353  			return
   354  		}
   355  		// create the idx layer if not exist
   356  		// otherwise, step to the next layer
   357  		k := prefix[idx]
   358  		if k < cur.key {
   359  			left := cur.Left()
   360  			if left == nil {
   361  				return
   362  			}
   363  			last = cur
   364  			lastPos = posLeft
   365  			cur = left
   366  			continue
   367  		}
   368  		if k > cur.key {
   369  			right := cur.Right()
   370  			if right == nil {
   371  				return
   372  			}
   373  			last = cur
   374  			lastPos = posRight
   375  			cur = right
   376  			continue
   377  		}
   378  		// key match, goto match next layer
   379  		idx++
   380  		// all matched, goto remove the value
   381  		if idx == len(prefix) {
   382  			// match
   383  			// Special case: prefix is Root node
   384  			if idx == 1 {
   385  				lastPos = posRoot
   386  			}
   387  			return cur, last, lastPos, true
   388  		}
   389  		// partial matched, goto middle on next layer
   390  		middle := cur.Middle()
   391  		if middle == nil {
   392  			return
   393  		}
   394  		last = cur
   395  		lastPos = posMiddle
   396  		cur = middle
   397  	}
   398  	return
   399  }
   400  
   401  func (n *node) IsLeaf() bool {
   402  	if !n.hasKey {
   403  		return false
   404  	}
   405  	if n.Left() != nil {
   406  		return false
   407  	}
   408  	if n.Middle() != nil {
   409  		return false
   410  	}
   411  	if n.Right() != nil {
   412  		return false
   413  	}
   414  	return false
   415  }
   416  
   417  func (n *node) shrinkLeft(last *node, omitMiddle bool) {
   418  	cur := last.left
   419  	if omitMiddle {
   420  		cur.middle = &n.tree.root
   421  	}
   422  	// L M R empty
   423  	// remove current node if all children nodes of current node are empty
   424  	if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil {
   425  		last.right = &n.tree.root
   426  		return
   427  	}
   428  
   429  	// M nonempty
   430  	if cur.Middle() != nil {
   431  		return
   432  	}
   433  	// M is empty below
   434  
   435  	// reconnect only one nonempty child[L|R] to be Parent Node's left node
   436  	if cur.Left() == nil {
   437  		last.left = cur.right
   438  		return
   439  	}
   440  	if cur.Right() == nil {
   441  		last.left = cur.left
   442  		return
   443  	}
   444  
   445  	// L|R both nonempty, M empty
   446  
   447  	// Step1. merge L onto R's left most node
   448  	node := cur.right
   449  	for {
   450  		if node.Left() == nil {
   451  			node.left = cur.left
   452  			break
   453  		}
   454  		node = node.left
   455  	}
   456  	// Step1. move R to be Parent Node's left node
   457  	last.left = cur.right
   458  }
   459  
   460  func (n *node) shrinkRight(last *node, omitMiddle bool) {
   461  	cur := last.middle
   462  	if omitMiddle {
   463  		cur.middle = &n.tree.root
   464  	}
   465  	// remove current node if all children nodes of current node are empty
   466  	if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil {
   467  		last.middle = &n.tree.root
   468  		return
   469  	}
   470  	// M nonempty
   471  	if cur.Middle() != nil {
   472  		return
   473  	}
   474  	// M is empty below
   475  
   476  	// reconnect only one nonempty child[L|R] to be Parent Node's middle node
   477  	if cur.Left() == nil {
   478  		last.middle = cur.right
   479  		return
   480  	}
   481  	if cur.Right() == nil {
   482  		last.middle = cur.left
   483  		return
   484  	}
   485  
   486  	// L|R both nonempty, M empty
   487  
   488  	// Step1. merge R onto L's right most node
   489  	node := cur.left
   490  	for {
   491  		if node.Right() == nil {
   492  			node.right = cur.right
   493  			break
   494  		}
   495  		node = node.right
   496  	}
   497  	// Step1. move L to be Parent Node's middle node
   498  	last.middle = cur.left
   499  }
   500  
   501  func (n *node) shrinkMiddle(last *node, omitMiddle bool) {
   502  	cur := last.middle
   503  	if omitMiddle {
   504  		cur.middle = &n.tree.root
   505  	}
   506  	// remove current node if all children nodes of current node are empty
   507  	if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil {
   508  		last.middle = &n.tree.root
   509  		return
   510  	}
   511  	// M nonempty
   512  	if cur.Middle() != nil {
   513  		return
   514  	}
   515  	// M is empty below
   516  
   517  	// reconnect only one nonempty child[L|R] to be Parent Node's middle node
   518  	if cur.Left() == nil {
   519  		last.middle = cur.right
   520  		return
   521  	}
   522  	if cur.Right() == nil {
   523  		last.middle = cur.left
   524  		return
   525  	}
   526  
   527  	// L|R both nonempty, M empty
   528  
   529  	// Step1. merge R onto L's right most node
   530  	node := cur.left
   531  	for {
   532  		if node.Right() == nil {
   533  			node.right = cur.right
   534  			break
   535  		}
   536  		node = node.right
   537  	}
   538  	// Step1. move L to be Parent Node's middle node
   539  	last.middle = cur.left
   540  }
   541  
   542  func (n *node) shrinkRoot(last *node, omitMiddle bool) {
   543  	cur := last
   544  	if omitMiddle {
   545  		cur.middle = &n.tree.root
   546  	}
   547  	// nop if all children nodes of current node are empty
   548  	if cur.Left() == nil && cur.Right() == nil && cur.Middle() == nil {
   549  		return
   550  	}
   551  	// M nonempty
   552  	if cur.Middle() != nil {
   553  		return
   554  	}
   555  	// M is empty below
   556  
   557  	// reconnect only one nonempty child[L|R] to be Parent Node
   558  	if cur.Left() == nil {
   559  		last = cur.right
   560  		return
   561  	}
   562  	if cur.Right() == nil {
   563  		last.middle = cur.left
   564  		return
   565  	}
   566  
   567  	// L|R both nonempty, M empty
   568  
   569  	// Step1. merge R onto L's right most node
   570  	node := cur.left
   571  	for {
   572  		if node.Right() == nil {
   573  			node.right = cur.right
   574  			break
   575  		}
   576  		node = node.right
   577  	}
   578  	// Step1. move L to be Parent Node
   579  	last = cur.left
   580  }