github.com/dashpay/godash@v0.0.0-20160726055534-e038a21e0e3d/database/internal/treap/immutable.go (about)

     1  // Copyright (c) 2015-2016 The btcsuite developers
     2  // Copyright (c) 2016 The Dash developers
     3  // Use of this source code is governed by an ISC
     4  // license that can be found in the LICENSE file.
     5  
     6  package treap
     7  
     8  import (
     9  	"bytes"
    10  	"math/rand"
    11  )
    12  
    13  // cloneTreapNode returns a shallow copy of the passed node.
    14  func cloneTreapNode(node *treapNode) *treapNode {
    15  	return &treapNode{
    16  		key:      node.key,
    17  		value:    node.value,
    18  		priority: node.priority,
    19  		left:     node.left,
    20  		right:    node.right,
    21  	}
    22  }
    23  
    24  // Immutable represents a treap data structure which is used to hold ordered
    25  // key/value pairs using a combination of binary search tree and heap semantics.
    26  // It is a self-organizing and randomized data structure that doesn't require
    27  // complex operations to maintain balance.  Search, insert, and delete
    28  // operations are all O(log n).  In addition, it provides O(1) snapshots for
    29  // multi-version concurrency control (MVCC).
    30  //
    31  // All operations which result in modifying the treap return a new version of
    32  // the treap with only the modified nodes updated.  All unmodified nodes are
    33  // shared with the previous version.  This is extremely useful in concurrent
    34  // applications since the caller only has to atomically replace the treap
    35  // pointer with the newly returned version after performing any mutations.  All
    36  // readers can simply use their existing pointer as a snapshot since the treap
    37  // it points to is immutable.  This effectively provides O(1) snapshot
    38  // capability with efficient memory usage characteristics since the old nodes
    39  // only remain allocated until there are no longer any references to them.
    40  type Immutable struct {
    41  	root  *treapNode
    42  	count int
    43  
    44  	// totalSize is the best estimate of the total size of of all data in
    45  	// the treap including the keys, values, and node sizes.
    46  	totalSize uint64
    47  }
    48  
    49  // newImmutable returns a new immutable treap given the passed parameters.
    50  func newImmutable(root *treapNode, count int, totalSize uint64) *Immutable {
    51  	return &Immutable{root: root, count: count, totalSize: totalSize}
    52  }
    53  
    54  // Len returns the number of items stored in the treap.
    55  func (t *Immutable) Len() int {
    56  	return t.count
    57  }
    58  
    59  // Size returns a best estimate of the total number of bytes the treap is
    60  // consuming including all of the fields used to represent the nodes as well as
    61  // the size of the keys and values.  Shared values are not detected, so the
    62  // returned size assumes each value is pointing to different memory.
    63  func (t *Immutable) Size() uint64 {
    64  	return t.totalSize
    65  }
    66  
    67  // get returns the treap node that contains the passed key.  It will return nil
    68  // when the key does not exist.
    69  func (t *Immutable) get(key []byte) *treapNode {
    70  	for node := t.root; node != nil; {
    71  		// Traverse left or right depending on the result of the
    72  		// comparison.
    73  		compareResult := bytes.Compare(key, node.key)
    74  		if compareResult < 0 {
    75  			node = node.left
    76  			continue
    77  		}
    78  		if compareResult > 0 {
    79  			node = node.right
    80  			continue
    81  		}
    82  
    83  		// The key exists.
    84  		return node
    85  	}
    86  
    87  	// A nil node was reached which means the key does not exist.
    88  	return nil
    89  }
    90  
    91  // Has returns whether or not the passed key exists.
    92  func (t *Immutable) Has(key []byte) bool {
    93  	if node := t.get(key); node != nil {
    94  		return true
    95  	}
    96  	return false
    97  }
    98  
    99  // Get returns the value for the passed key.  The function will return nil when
   100  // the key does not exist.
   101  func (t *Immutable) Get(key []byte) []byte {
   102  	if node := t.get(key); node != nil {
   103  		return node.value
   104  	}
   105  	return nil
   106  }
   107  
   108  // Put inserts the passed key/value pair.
   109  func (t *Immutable) Put(key, value []byte) *Immutable {
   110  	// Use an empty byte slice for the value when none was provided.  This
   111  	// ultimately allows key existence to be determined from the value since
   112  	// an empty byte slice is distinguishable from nil.
   113  	if value == nil {
   114  		value = emptySlice
   115  	}
   116  
   117  	// The node is the root of the tree if there isn't already one.
   118  	if t.root == nil {
   119  		root := newTreapNode(key, value, rand.Int())
   120  		return newImmutable(root, 1, nodeSize(root))
   121  	}
   122  
   123  	// Find the binary tree insertion point and construct a replaced list of
   124  	// parents while doing so.  This is done because this is an immutable
   125  	// data structure so regardless of where in the treap the new key/value
   126  	// pair ends up, all ancestors up to and including the root need to be
   127  	// replaced.
   128  	//
   129  	// When the key matches an entry already in the treap, replace the node
   130  	// with a new one that has the new value set and return.
   131  	var parents parentStack
   132  	var compareResult int
   133  	for node := t.root; node != nil; {
   134  		// Clone the node and link its parent to it if needed.
   135  		nodeCopy := cloneTreapNode(node)
   136  		if oldParent := parents.At(0); oldParent != nil {
   137  			if oldParent.left == node {
   138  				oldParent.left = nodeCopy
   139  			} else {
   140  				oldParent.right = nodeCopy
   141  			}
   142  		}
   143  		parents.Push(nodeCopy)
   144  
   145  		// Traverse left or right depending on the result of comparing
   146  		// the keys.
   147  		compareResult = bytes.Compare(key, node.key)
   148  		if compareResult < 0 {
   149  			node = node.left
   150  			continue
   151  		}
   152  		if compareResult > 0 {
   153  			node = node.right
   154  			continue
   155  		}
   156  
   157  		// The key already exists, so update its value.
   158  		nodeCopy.value = value
   159  
   160  		// Return new immutable treap with the replaced node and
   161  		// ancestors up to and including the root of the tree.
   162  		newRoot := parents.At(parents.Len() - 1)
   163  		newTotalSize := t.totalSize - uint64(len(node.value)) +
   164  			uint64(len(value))
   165  		return newImmutable(newRoot, t.count, newTotalSize)
   166  	}
   167  
   168  	// Link the new node into the binary tree in the correct position.
   169  	node := newTreapNode(key, value, rand.Int())
   170  	parent := parents.At(0)
   171  	if compareResult < 0 {
   172  		parent.left = node
   173  	} else {
   174  		parent.right = node
   175  	}
   176  
   177  	// Perform any rotations needed to maintain the min-heap and replace
   178  	// the ancestors up to and including the tree root.
   179  	newRoot := parents.At(parents.Len() - 1)
   180  	for parents.Len() > 0 {
   181  		// There is nothing left to do when the node's priority is
   182  		// greater than or equal to its parent's priority.
   183  		parent = parents.Pop()
   184  		if node.priority >= parent.priority {
   185  			break
   186  		}
   187  
   188  		// Perform a right rotation if the node is on the left side or
   189  		// a left rotation if the node is on the right side.
   190  		if parent.left == node {
   191  			node.right, parent.left = parent, node.right
   192  		} else {
   193  			node.left, parent.right = parent, node.left
   194  		}
   195  
   196  		// Either set the new root of the tree when there is no
   197  		// grandparent or relink the grandparent to the node based on
   198  		// which side the old parent the node is replacing was on.
   199  		grandparent := parents.At(0)
   200  		if grandparent == nil {
   201  			newRoot = node
   202  		} else if grandparent.left == parent {
   203  			grandparent.left = node
   204  		} else {
   205  			grandparent.right = node
   206  		}
   207  	}
   208  
   209  	return newImmutable(newRoot, t.count+1, t.totalSize+nodeSize(node))
   210  }
   211  
   212  // Delete removes the passed key from the treap and returns the resulting treap
   213  // if it exists.  The original immutable treap is returned if the key does not
   214  // exist.
   215  func (t *Immutable) Delete(key []byte) *Immutable {
   216  	// Find the node for the key while constructing a list of parents while
   217  	// doing so.
   218  	var parents parentStack
   219  	var delNode *treapNode
   220  	for node := t.root; node != nil; {
   221  		parents.Push(node)
   222  
   223  		// Traverse left or right depending on the result of the
   224  		// comparison.
   225  		compareResult := bytes.Compare(key, node.key)
   226  		if compareResult < 0 {
   227  			node = node.left
   228  			continue
   229  		}
   230  		if compareResult > 0 {
   231  			node = node.right
   232  			continue
   233  		}
   234  
   235  		// The key exists.
   236  		delNode = node
   237  		break
   238  	}
   239  
   240  	// There is nothing to do if the key does not exist.
   241  	if delNode == nil {
   242  		return t
   243  	}
   244  
   245  	// When the only node in the tree is the root node and it is the one
   246  	// being deleted, there is nothing else to do besides removing it.
   247  	parent := parents.At(1)
   248  	if parent == nil && delNode.left == nil && delNode.right == nil {
   249  		return newImmutable(nil, 0, 0)
   250  	}
   251  
   252  	// Construct a replaced list of parents and the node to delete itself.
   253  	// This is done because this is an immutable data structure and
   254  	// therefore all ancestors of the node that will be deleted, up to and
   255  	// including the root, need to be replaced.
   256  	var newParents parentStack
   257  	for i := parents.Len(); i > 0; i-- {
   258  		node := parents.At(i - 1)
   259  		nodeCopy := cloneTreapNode(node)
   260  		if oldParent := newParents.At(0); oldParent != nil {
   261  			if oldParent.left == node {
   262  				oldParent.left = nodeCopy
   263  			} else {
   264  				oldParent.right = nodeCopy
   265  			}
   266  		}
   267  		newParents.Push(nodeCopy)
   268  	}
   269  	delNode = newParents.Pop()
   270  	parent = newParents.At(0)
   271  
   272  	// Perform rotations to move the node to delete to a leaf position while
   273  	// maintaining the min-heap while replacing the modified children.
   274  	var child *treapNode
   275  	newRoot := newParents.At(newParents.Len() - 1)
   276  	for delNode.left != nil || delNode.right != nil {
   277  		// Choose the child with the higher priority.
   278  		var isLeft bool
   279  		if delNode.left == nil {
   280  			child = delNode.right
   281  		} else if delNode.right == nil {
   282  			child = delNode.left
   283  			isLeft = true
   284  		} else if delNode.left.priority >= delNode.right.priority {
   285  			child = delNode.left
   286  			isLeft = true
   287  		} else {
   288  			child = delNode.right
   289  		}
   290  
   291  		// Rotate left or right depending on which side the child node
   292  		// is on.  This has the effect of moving the node to delete
   293  		// towards the bottom of the tree while maintaining the
   294  		// min-heap.
   295  		child = cloneTreapNode(child)
   296  		if isLeft {
   297  			child.right, delNode.left = delNode, child.right
   298  		} else {
   299  			child.left, delNode.right = delNode, child.left
   300  		}
   301  
   302  		// Either set the new root of the tree when there is no
   303  		// grandparent or relink the grandparent to the node based on
   304  		// which side the old parent the node is replacing was on.
   305  		//
   306  		// Since the node to be deleted was just moved down a level, the
   307  		// new grandparent is now the current parent and the new parent
   308  		// is the current child.
   309  		if parent == nil {
   310  			newRoot = child
   311  		} else if parent.left == delNode {
   312  			parent.left = child
   313  		} else {
   314  			parent.right = child
   315  		}
   316  
   317  		// The parent for the node to delete is now what was previously
   318  		// its child.
   319  		parent = child
   320  	}
   321  
   322  	// Delete the node, which is now a leaf node, by disconnecting it from
   323  	// its parent.
   324  	if parent.right == delNode {
   325  		parent.right = nil
   326  	} else {
   327  		parent.left = nil
   328  	}
   329  
   330  	return newImmutable(newRoot, t.count-1, t.totalSize-nodeSize(delNode))
   331  }
   332  
   333  // ForEach invokes the passed function with every key/value pair in the treap
   334  // in ascending order.
   335  func (t *Immutable) ForEach(fn func(k, v []byte) bool) {
   336  	// Add the root node and all children to the left of it to the list of
   337  	// nodes to traverse and loop until they, and all of their child nodes,
   338  	// have been traversed.
   339  	var parents parentStack
   340  	for node := t.root; node != nil; node = node.left {
   341  		parents.Push(node)
   342  	}
   343  	for parents.Len() > 0 {
   344  		node := parents.Pop()
   345  		if !fn(node.key, node.value) {
   346  			return
   347  		}
   348  
   349  		// Extend the nodes to traverse by all children to the left of
   350  		// the current node's right child.
   351  		for node := node.right; node != nil; node = node.left {
   352  			parents.Push(node)
   353  		}
   354  	}
   355  }
   356  
   357  // NewImmutable returns a new empty immutable treap ready for use.  See the
   358  // documentation for the Immutable structure for more details.
   359  func NewImmutable() *Immutable {
   360  	return &Immutable{}
   361  }