github.com/Nigel2392/go-datastructures@v1.1.5/hashmap/bucketnode.go (about)

     1  package hashmap
     2  
     3  import (
     4  	"github.com/Nigel2392/go-datastructures"
     5  )
     6  
     7  type keyNode[T1 datastructures.Hashable[T1], T2 any] struct {
     8  	_hash uint64
     9  	key   T1
    10  	value T2
    11  	next  *keyNode[T1, T2]
    12  }
    13  
    14  func (n *keyNode[T1, T2]) insert(v *keyNode[T1, T2]) {
    15  	if n.key.Equals(v.key) {
    16  		n.value = v.value
    17  		return
    18  	}
    19  
    20  	if n.next == nil {
    21  		n.next = v
    22  		return
    23  	}
    24  
    25  	n.next.insert(v)
    26  }
    27  
    28  func (n *keyNode[T1, T2]) retrieve(other *keyNode[T1, T2]) (value T2, ok bool) {
    29  	if n == nil {
    30  		return
    31  	}
    32  
    33  	if n.key.Equals(other.key) {
    34  		return n.value, true
    35  	}
    36  
    37  	return n.next.retrieve(other)
    38  }
    39  
    40  func (n *keyNode[T1, T2]) delete(other *keyNode[T1, T2]) (newRoot *keyNode[T1, T2], deleted bool) {
    41  	if n == nil {
    42  		return nil, false
    43  	}
    44  
    45  	if n.key.Equals(other.key) {
    46  		return n.next, true
    47  	}
    48  
    49  	n.next, deleted = n.next.delete(other)
    50  	return n, deleted
    51  }
    52  
    53  func (n *keyNode[T1, T2]) pop(other *keyNode[T1, T2]) (newRoot *keyNode[T1, T2], value T2, ok bool) {
    54  	if n == nil {
    55  		return
    56  	}
    57  
    58  	if n.key.Equals(other.key) {
    59  		return n.next, n.value, true
    60  	}
    61  
    62  	n.next, value, ok = n.next.pop(other)
    63  	return n, value, ok
    64  }
    65  
    66  func (n *keyNode[T1, T2]) deleteIf(predicate func(k T1, v T2) bool) (newRoot *keyNode[T1, T2], amountDeleted int) {
    67  	if n == nil {
    68  		return
    69  	}
    70  
    71  	if predicate(n.key, n.value) {
    72  		newRoot, amountDeleted = n.next.deleteIf(predicate)
    73  		return newRoot, amountDeleted + 1
    74  	}
    75  
    76  	n.next, amountDeleted = n.next.deleteIf(predicate)
    77  	return n, amountDeleted
    78  }
    79  
    80  type bucketNode[T1 datastructures.Hashable[T1], T2 any] struct {
    81  	_hash uint64
    82  	next  *keyNode[T1, T2]
    83  	left  *bucketNode[T1, T2]
    84  	right *bucketNode[T1, T2]
    85  }
    86  
    87  func (n *bucketNode[T1, T2]) insert(v *keyNode[T1, T2]) {
    88  	if n._hash == v._hash {
    89  		if n.next == nil {
    90  			n.next = v
    91  			return
    92  		}
    93  		n.next.insert(v)
    94  		return
    95  	} else if n._hash < v._hash {
    96  		if n.right == nil {
    97  			n.right = &bucketNode[T1, T2]{
    98  				_hash: v._hash,
    99  				next:  v,
   100  			}
   101  		} else {
   102  			n.right.insert(v)
   103  		}
   104  		return
   105  	} else if n._hash > v._hash {
   106  		if n.left == nil {
   107  			n.left = &bucketNode[T1, T2]{
   108  				_hash: v._hash,
   109  				next:  v,
   110  			}
   111  		} else {
   112  			n.left.insert(v)
   113  		}
   114  		return
   115  	}
   116  }
   117  
   118  func (n *bucketNode[T1, T2]) retrieve(k *keyNode[T1, T2]) (value T2, ok bool) {
   119  	if n == nil {
   120  		return
   121  	}
   122  
   123  	if n._hash < k._hash {
   124  		return n.right.retrieve(k)
   125  	} else if n._hash > k._hash {
   126  		return n.left.retrieve(k)
   127  	}
   128  
   129  	return n.next.retrieve(k)
   130  }
   131  
   132  func (n *bucketNode[T1, T2]) delete(other *keyNode[T1, T2]) (newRoot *bucketNode[T1, T2], deleted bool) {
   133  	if n == nil {
   134  		return nil, false
   135  	}
   136  
   137  	if other._hash < n._hash {
   138  		n.left, deleted = n.left.delete(other)
   139  	} else if other._hash > n._hash {
   140  		n.right, deleted = n.right.delete(other)
   141  	} else {
   142  		n.next, deleted = n.next.delete(other)
   143  	}
   144  	if n.next == nil {
   145  		if n.left == nil {
   146  			return n.right, true
   147  		} else if n.right == nil {
   148  			return n.left, true
   149  		}
   150  
   151  		// find the min node in the right subtree
   152  		var minNode = n.right.findMin()
   153  		n._hash = minNode._hash
   154  		n.next = minNode.next
   155  		// delete the min node from the right subtree
   156  		n.right, deleted = n.right.deleteNode(minNode)
   157  	}
   158  	return n, deleted
   159  }
   160  
   161  func (n *bucketNode[T1, T2]) deleteIf(predicate func(T1, T2) bool) (newRoot *bucketNode[T1, T2], amountDeleted int) {
   162  	if n == nil {
   163  		return nil, 0
   164  	}
   165  	var deleted int
   166  	n.left, deleted = n.left.deleteIf(predicate)
   167  	amountDeleted += deleted
   168  	n.right, deleted = n.right.deleteIf(predicate)
   169  	amountDeleted += deleted
   170  	n.next, deleted = n.next.deleteIf(predicate)
   171  	amountDeleted += deleted
   172  	return n, amountDeleted
   173  }
   174  
   175  // deleteNode deletes the node with the given hash
   176  func (n *bucketNode[T1, T2]) deleteNode(other *bucketNode[T1, T2]) (newRoot *bucketNode[T1, T2], deleted bool) {
   177  	if n == nil {
   178  		return nil, false
   179  	}
   180  
   181  	if other._hash < n._hash {
   182  		n.left, deleted = n.left.deleteNode(other)
   183  	} else if other._hash > n._hash {
   184  		n.right, deleted = n.right.deleteNode(other)
   185  	} else {
   186  		if n.left == nil {
   187  			return n.right, true
   188  		} else if n.right == nil {
   189  			return n.left, true
   190  		}
   191  
   192  		// find the min node in the right subtree
   193  		var minNode = n.right.findMin()
   194  		n._hash = minNode._hash
   195  		n.next = minNode.next
   196  		// delete the min node from the right subtree
   197  		n.right, deleted = n.right.deleteNode(minNode)
   198  	}
   199  	return n, deleted
   200  }
   201  
   202  func (n *bucketNode[T1, T2]) pop(k *keyNode[T1, T2]) (newRoot *bucketNode[T1, T2], value T2, ok bool) {
   203  	if n == nil {
   204  		return nil, value, false
   205  	}
   206  
   207  	if k._hash < n._hash {
   208  		n.left, value, ok = n.left.pop(k)
   209  	} else if k._hash > n._hash {
   210  		n.right, value, ok = n.right.pop(k)
   211  	} else {
   212  		n.next, value, ok = n.next.pop(k)
   213  		if n.next == nil {
   214  			if n.left == nil {
   215  				return n.right, value, ok
   216  			} else if n.right == nil {
   217  				return n.left, value, ok
   218  			}
   219  
   220  			// find the min node in the right subtree
   221  			var minNode = n.right.findMin()
   222  			n._hash = minNode._hash
   223  			n.next = minNode.next
   224  			// delete the min node from the right subtree
   225  			n.right, _ = n.right.deleteNode(minNode)
   226  		}
   227  	}
   228  
   229  	return n, value, ok
   230  }
   231  
   232  func (n *bucketNode[T1, T2]) findMin() *bucketNode[T1, T2] {
   233  	if n.left == nil {
   234  		return n
   235  	}
   236  
   237  	return n.left.findMin()
   238  }
   239  
   240  func (n *bucketNode[T1, T2]) traverse(f func(k T1, v T2) bool) (continueLoop bool) {
   241  	if n == nil {
   242  		return true
   243  	}
   244  	if !n.left.traverse(f) {
   245  		return true
   246  	}
   247  	for n.next != nil {
   248  		if !f(n.next.key, n.next.value) {
   249  			return false
   250  		}
   251  		n.next = n.next.next
   252  	}
   253  	if !n.right.traverse(f) {
   254  		return true
   255  	}
   256  	return true
   257  }