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