github.com/scottcagno/storage@v1.8.0/pkg/lsmt/trees/bptree/bptree.go (about)

     1  /*
     2   * // Copyright (c) 2021. Scott Cagno. All rights reserved.
     3   * // The license can be found in the root of this project; see LICENSE.
     4   */
     5  
     6  package bptree
     7  
     8  import (
     9  	"encoding/binary"
    10  	"log"
    11  	"strconv"
    12  	"strings"
    13  	"unsafe"
    14  )
    15  
    16  var stringZero = *new(string)
    17  var ValTypeZero = *new([]byte)
    18  
    19  func Compare(a, b string) int {
    20  	return strings.Compare(a, b)
    21  }
    22  
    23  func Equal(a, b string) bool {
    24  	return a == b
    25  }
    26  
    27  const (
    28  	defaultOrder = orderSize32
    29  	orderSize4   = 4
    30  	orderSize8   = 8
    31  	orderSize16  = 16
    32  	orderSize32  = 32
    33  	orderSize64  = 64
    34  	orderSize128 = 128
    35  	orderSize256 = 256
    36  	orderSize512 = 512
    37  )
    38  
    39  // bpNode represents a bpNode of the BPTree
    40  type bpNode struct {
    41  	numKeys  int
    42  	keys     [defaultOrder - 1]string
    43  	pointers [defaultOrder]unsafe.Pointer
    44  	parent   *bpNode
    45  	isLeaf   bool
    46  }
    47  
    48  func (n *bpNode) hasKey(key string) bool {
    49  	if n.isLeaf {
    50  		for i := 0; i < n.numKeys; i++ {
    51  			if Equal(key, n.keys[i]) {
    52  				return true
    53  			}
    54  		}
    55  	}
    56  	return false
    57  }
    58  
    59  func (n *bpNode) closest(key string) (*entry, bool) {
    60  	if n.isLeaf {
    61  		i := 0
    62  		for ; i < n.numKeys; i++ {
    63  			if Compare(key, n.keys[i]) < 0 {
    64  				break
    65  			}
    66  		}
    67  		if i > 0 {
    68  			i--
    69  		}
    70  		return (*entry)(n.pointers[i]), true
    71  	}
    72  	return nil, false
    73  }
    74  
    75  func (n *bpNode) record(key string) (*entry, bool) {
    76  	if n.isLeaf {
    77  		for i := 0; i < n.numKeys; i++ {
    78  			if Equal(key, n.keys[i]) {
    79  				return (*entry)(n.pointers[i]), true
    80  			}
    81  		}
    82  	}
    83  	return nil, false
    84  }
    85  
    86  // entry represents an entry pointed to by a leaf bpNode
    87  type entry struct {
    88  	Key   string
    89  	Value []byte
    90  }
    91  
    92  // BPTree represents the root of a b+tree
    93  type BPTree struct {
    94  	root *bpNode
    95  }
    96  
    97  // NewBPTree creates and returns a new tree
    98  func NewBPTree() *BPTree {
    99  	return new(BPTree)
   100  }
   101  
   102  // Has returns a boolean indicating weather or not
   103  // the provided key and associated record exists.
   104  func (t *BPTree) Has(key string) bool {
   105  	return t.findEntry(key) != nil
   106  }
   107  
   108  // HasInt tests and returns a boolean value if the
   109  // provided key exists in the tree
   110  func (t *BPTree) HasInt(key int64) bool {
   111  	return t.findEntry(IntToKey(key)) != nil
   112  }
   113  
   114  // Add inserts a new record using the provided key. It
   115  // only inserts an entry if the key does not already exist.
   116  func (t *BPTree) Add(key string, value []byte) {
   117  	// master insertUnique method only inserts if the key
   118  	// does not currently exist in the tree
   119  	t.insertUnique(key, value)
   120  }
   121  
   122  // AddInt inserts a new record using the provided integer key
   123  // and value. It only inserts an entry if the key does not
   124  // already exist.
   125  func (t *BPTree) AddInt(key int64, value int64) {
   126  	// master insertUnique method only inserts if the key
   127  	// does not currently exist in the tree
   128  	t.insertUnique(IntToKey(key), IntToVal(value))
   129  }
   130  
   131  // insertUnique inserts a new record using the provided key. It
   132  // only inserts an entry if the key does not already exist.
   133  func (t *BPTree) insertUnique(key string, value []byte) {
   134  	// If the tree is empty, start a new one and return.
   135  	if t.root == nil {
   136  		t.root = startNewTree(key, &entry{key, value})
   137  		return
   138  	}
   139  	// If the tree already exists, let's see what we
   140  	// get when we try to find the correct leaf.
   141  	leaf := findLeaf(t.root, key)
   142  	// check to ensure the leaf node does already contain the key
   143  	if leaf.hasKey(key) {
   144  		return // Key already exists! So lets just return.
   145  	}
   146  	// If the tree already exists and the key has not been
   147  	// found, then let's insert it into the tree and return!
   148  	if leaf.numKeys < defaultOrder-1 {
   149  		insertIntoLeaf(leaf, key, &entry{key, value})
   150  		return
   151  	}
   152  	// Otherwise, insert, split and balance returning the updated root.
   153  	t.root = insertIntoLeafAfterSplitting(t.root, leaf, key, &entry{key, value})
   154  }
   155  
   156  // Put is mainly used when you wish to upsert as it assumes the
   157  // data to already be contained the tree. It will  overwrite
   158  // duplicate keys, as it does not check to see if the key exists
   159  func (t *BPTree) Put(key string, value []byte) bool {
   160  	// master insert method treats insertion much like
   161  	// "setting" in a hashmap (an upsert) by default
   162  	return t.insert(key, value)
   163  }
   164  
   165  // PutInt is mainly used when you wish to upsert as it assumes the
   166  // data to already be contained the tree. It will overwrite
   167  // duplicate keys, as it does not check to see if the key exists
   168  func (t *BPTree) PutInt(key int64, value int64) bool {
   169  	// master insert method treats insertion much like
   170  	// "setting" in a hashmap (an upsert) by default
   171  	return t.insert(IntToKey(key), IntToVal(value))
   172  }
   173  
   174  func (t *BPTree) GetClosest(key string) (string, []byte) {
   175  	l := findLeaf(t.root, key)
   176  	if l == nil {
   177  		return "", nil
   178  	}
   179  	e, ok := l.closest(key)
   180  	if !ok {
   181  		return "", nil
   182  	}
   183  	return e.Key, e.Value
   184  }
   185  
   186  // Get returns the record for a given key if it exists
   187  func (t *BPTree) Get(key string) (string, []byte) {
   188  	e := t.findEntry(key)
   189  	if e == nil {
   190  		return "", nil
   191  	}
   192  	return e.Key, e.Value
   193  }
   194  
   195  // GetInt returns the record for a given key if it exists
   196  func (t *BPTree) GetInt(key int64) (int64, int64) {
   197  	e := t.findEntry(IntToKey(key))
   198  	if e == nil {
   199  		return -1, -1
   200  	}
   201  	return KeyToInt(e.Key), ValToInt(e.Value)
   202  }
   203  
   204  func (t *BPTree) Del(key string) (string, []byte) {
   205  	e := t.delete(key)
   206  	if e == nil {
   207  		return "", nil
   208  	}
   209  	return e.Key, e.Value
   210  }
   211  
   212  func (t *BPTree) DelInt(key int64) (int64, int64) {
   213  	e := t.delete(IntToKey(key))
   214  	if e == nil {
   215  		return -1, -1
   216  	}
   217  	return KeyToInt(e.Key), ValToInt(e.Value)
   218  }
   219  
   220  func (t *BPTree) Range(iter func(k string, v []byte) bool) {
   221  	c := findFirstLeaf(t.root)
   222  	if c == nil {
   223  		return
   224  	}
   225  	var e *entry
   226  	for {
   227  		for i := 0; i < c.numKeys; i++ {
   228  			e = (*entry)(c.pointers[i])
   229  			if e != nil && !iter(e.Key, e.Value) {
   230  				continue
   231  			}
   232  		}
   233  		if c.pointers[defaultOrder-1] != nil {
   234  			c = (*bpNode)(c.pointers[defaultOrder-1])
   235  		} else {
   236  			break
   237  		}
   238  	}
   239  }
   240  
   241  func (t *BPTree) Min() (string, []byte) {
   242  	c := findFirstLeaf(t.root)
   243  	if c == nil {
   244  		return "", nil
   245  	}
   246  	e := (*entry)(c.pointers[0])
   247  	return e.Key, e.Value
   248  }
   249  
   250  func (t *BPTree) Max() (string, []byte) {
   251  	c := findLastLeaf(t.root)
   252  	if c == nil {
   253  		return "", nil
   254  	}
   255  	e := (*entry)(c.pointers[c.numKeys-1])
   256  	return e.Key, e.Value
   257  }
   258  
   259  func (t *BPTree) Len() int {
   260  	var count int
   261  	for n := findFirstLeaf(t.root); n != nil; n = n.nextLeaf() {
   262  		count += n.numKeys
   263  	}
   264  	return count
   265  }
   266  
   267  func (t *BPTree) Size() int64 {
   268  	c := findFirstLeaf(t.root)
   269  	if c == nil {
   270  		return 0
   271  	}
   272  	var s int64
   273  	var e *entry
   274  	for {
   275  		for i := 0; i < c.numKeys; i++ {
   276  			e = (*entry)(c.pointers[i])
   277  			if e != nil {
   278  				s += int64(len(e.Key) + len(e.Value))
   279  			}
   280  		}
   281  		if c.pointers[defaultOrder-1] != nil {
   282  			c = (*bpNode)(c.pointers[defaultOrder-1])
   283  		} else {
   284  			break
   285  		}
   286  	}
   287  	return s
   288  }
   289  
   290  func (t *BPTree) Close() {
   291  	//t.destroyTree()
   292  	t.root = nil
   293  }
   294  
   295  // insert is the "master" insertion function.
   296  // Inserts a key and an associated Value into
   297  // the B+ tree, causing the tree to be adjusted
   298  // however necessary to maintain the B+ tree
   299  // properties
   300  func (t *BPTree) insert(key string, value []byte) bool {
   301  
   302  	// CASE: BPTree does not exist yet, start a new tree
   303  	if t.root == nil {
   304  		t.root = startNewTree(key, &entry{key, value})
   305  		return false
   306  	}
   307  
   308  	// The current implementation ignores duplicates (will treat it kind of like a set operation)
   309  	leaf, recordPointer := t.find(key)
   310  	if recordPointer != nil {
   311  
   312  		// If the key already exists in this tree then proceed to update Value and return
   313  		recordPointer.Value = value
   314  		return true
   315  	}
   316  
   317  	// No Record found, so create a new Record for the Value. NOTE: Normally t.find would not return
   318  	// a record pointer in which case we would need the line below this.
   319  	//recordPointer = makeRecord(Value)
   320  
   321  	// CASE: BPTree already exists (continue through the rest of the function)
   322  
   323  	// Leaf has room for the key and recordPointer--insert into leaf and return
   324  	if leaf.numKeys < defaultOrder-1 {
   325  		insertIntoLeaf(leaf, key, &entry{key, value})
   326  		return false
   327  	}
   328  
   329  	// Leaf does not have enough room and needs to be split
   330  	t.root = insertIntoLeafAfterSplitting(t.root, leaf, key, &entry{key, value})
   331  	return false
   332  }
   333  
   334  // startNewTree first insertion case: starts a new tree
   335  func startNewTree(key string, pointer *entry) *bpNode {
   336  	root := &bpNode{isLeaf: true} // makeLeaf()
   337  	root.keys[0] = key
   338  	root.pointers[0] = unsafe.Pointer(pointer)
   339  	root.pointers[defaultOrder-1] = nil
   340  	root.parent = nil
   341  	root.numKeys++
   342  	return root
   343  }
   344  
   345  // insertIntoNewRoot creates a new root for two subtrees and inserts the appropriate key into the new root
   346  func insertIntoNewRoot(left *bpNode, key string, right *bpNode) *bpNode {
   347  	root := &bpNode{} // makeNode()
   348  	root.keys[0] = key
   349  	root.pointers[0] = unsafe.Pointer(left)
   350  	root.pointers[1] = unsafe.Pointer(right)
   351  	root.numKeys++
   352  	root.parent = nil
   353  	left.parent = root
   354  	right.parent = root
   355  	return root
   356  }
   357  
   358  /*
   359   * insertIntoParent inserts a new bpNode (leaf or internal bpNode) into the tree--returns the root of
   360   * the tree after insertion is complete
   361   */
   362  func insertIntoParent(root *bpNode, left *bpNode, key string, right *bpNode) *bpNode {
   363  
   364  	/*
   365  	 * Case: new root
   366  	 */
   367  	if left.parent == nil {
   368  		return insertIntoNewRoot(left, key, right)
   369  	}
   370  
   371  	/*
   372  	 * Case: leaf or bpNode. (Remainder of function body.)
   373  	 * Find the parents pointer to the left bpNode
   374  	 */
   375  	leftIndex := getLeftIndex(left.parent, left)
   376  
   377  	/*
   378  	 * Simple case: the new key fits into the bpNode.
   379  	 */
   380  	if left.parent.numKeys < defaultOrder-1 {
   381  		return insertIntoNode(root, left.parent, leftIndex, key, right)
   382  	}
   383  
   384  	/* Harder case:  split a bpNode in order
   385  	 * to preserve the B+ tree properties.
   386  	 */
   387  	return insertIntoNodeAfterSplitting(root, left.parent, leftIndex, key, right)
   388  }
   389  
   390  /*
   391   *	getLeftIndex helper function used in insertIntoParent to find the index of the parents
   392   *  pointer to the bpNode to the left of the key to be inserted
   393   */
   394  func getLeftIndex(parent, left *bpNode) int {
   395  	var leftIndex int
   396  	for leftIndex <= parent.numKeys && (*bpNode)(parent.pointers[leftIndex]) != left {
   397  		leftIndex++
   398  	}
   399  	return leftIndex
   400  }
   401  
   402  /*
   403   * insertIntoNode inserts a new key and pointer to a bpNode into a bpNode into which these can fit without violating the
   404   * tree's properties
   405   */
   406  func insertIntoNode(root, n *bpNode, leftIndex int, key string, right *bpNode) *bpNode {
   407  	// Consider using copy, it might be better
   408  	copy(n.pointers[leftIndex+2:], n.pointers[leftIndex+1:])
   409  	copy(n.keys[leftIndex+1:], n.keys[leftIndex:])
   410  
   411  	/* // ORIG
   412  	for i := n.numKeys; i > leftIndex; i-- {
   413  		n.pointers[i+1] = n.pointers[i]
   414  		n.keys[i] = n.keys[i-1]
   415  	}
   416  	*/
   417  
   418  	n.pointers[leftIndex+1] = unsafe.Pointer(right)
   419  	n.keys[leftIndex] = key
   420  	n.numKeys++
   421  	return root
   422  }
   423  
   424  // insertIntoNodeAfterSplitting inserts a new key and pointer to a bpNode into a bpNode, causing
   425  // the nodes size to exceed the ORDER, and causing the bpNode to split
   426  func insertIntoNodeAfterSplitting(root, oldNode *bpNode, leftIndex int, key string, right *bpNode) *bpNode {
   427  
   428  	// first create a temp set of keys and pointers to hold everything in ORDER, including
   429  	// the new key and pointer, inserted in their correct places--then create a new bpNode
   430  	// and copy half of the keys and pointers to the old bpNode and the other half to the new
   431  
   432  	var i, j int
   433  	var tempKeys [defaultOrder]string                 //tempKeys := make([]int, ORDER)
   434  	var tempPointers [defaultOrder + 1]unsafe.Pointer //tempPointers := make([]interface{}, ORDER+1)
   435  
   436  	for i, j = 0, 0; i < oldNode.numKeys+1; i, j = i+1, j+1 {
   437  		if j == leftIndex+1 {
   438  			j++
   439  		}
   440  		tempPointers[j] = oldNode.pointers[i]
   441  	}
   442  
   443  	for i, j = 0, 0; i < oldNode.numKeys; i, j = i+1, j+1 {
   444  		if j == leftIndex {
   445  			j++
   446  		}
   447  		tempKeys[j] = oldNode.keys[i]
   448  	}
   449  
   450  	tempPointers[leftIndex+1] = unsafe.Pointer(right)
   451  	tempKeys[leftIndex] = key
   452  
   453  	/*
   454  	 * copy half the keys and pointers to the old bpNode...
   455  	 */
   456  	split := cut(defaultOrder)
   457  
   458  	oldNode.numKeys = 0
   459  
   460  	for i = 0; i < split-1; i++ {
   461  		oldNode.pointers[i] = tempPointers[i]
   462  		oldNode.keys[i] = tempKeys[i]
   463  		oldNode.numKeys++
   464  	}
   465  	oldNode.pointers[i] = tempPointers[i]
   466  	kPrime := tempKeys[split-1]
   467  
   468  	/*
   469  	 * ...create the new bpNode and copy the other half the keys and pointers
   470  	 */
   471  	newNode := &bpNode{} // makeNode()
   472  
   473  	for i, j = i+1, 0; i < defaultOrder; i, j = i+1, j+1 {
   474  		newNode.pointers[j] = tempPointers[i]
   475  		newNode.keys[j] = tempKeys[i]
   476  		newNode.numKeys++
   477  	}
   478  	newNode.pointers[j] = tempPointers[i]
   479  	newNode.parent = oldNode.parent
   480  
   481  	/*
   482  	 * Free up tempPointers and tempKeys
   483  	 */
   484  	for i = 0; i < defaultOrder; i++ {
   485  		tempKeys[i] = *new(string) // zero values
   486  		tempPointers[i] = nil      // zero values
   487  	}
   488  	tempPointers[defaultOrder] = nil
   489  
   490  	var child *bpNode
   491  	for i = 0; i <= newNode.numKeys; i++ {
   492  		child = (*bpNode)(newNode.pointers[i])
   493  		child.parent = newNode
   494  	}
   495  
   496  	/* Insert a new key into the parent of the two
   497  	 * nodes resulting from the split, with
   498  	 * the old bpNode to the left and the new to the right.
   499  	 */
   500  	return insertIntoParent(root, oldNode, kPrime, newNode)
   501  }
   502  
   503  // insertIntoLeaf inserts a new pointer to a Record and its
   504  // corresponding key into a leaf.
   505  func insertIntoLeaf(leaf *bpNode, key string, pointer *entry) /* *bpNode */ {
   506  	var i, insertionPoint int
   507  	for insertionPoint < leaf.numKeys && Compare(leaf.keys[insertionPoint], key) == -1 {
   508  		insertionPoint++
   509  	}
   510  	for i = leaf.numKeys; i > insertionPoint; i-- {
   511  		leaf.keys[i] = leaf.keys[i-1]
   512  		leaf.pointers[i] = leaf.pointers[i-1]
   513  	}
   514  	leaf.keys[insertionPoint] = key
   515  	leaf.pointers[insertionPoint] = unsafe.Pointer(pointer)
   516  	leaf.numKeys++
   517  	//return leaf // might not need to return this leaf
   518  }
   519  
   520  // insertIntoLeafAfterSplitting inserts a new key and pointer to a new Record into a leaf
   521  // so as to exceed the tree's ORDER, causing the leaf to be split in half
   522  func insertIntoLeafAfterSplitting(root, leaf *bpNode, key string, pointer *entry) *bpNode {
   523  
   524  	// perform linear search to find index to insert new record
   525  	var insertionIndex int
   526  	for insertionIndex < defaultOrder-1 && Compare(leaf.keys[insertionIndex], key) == -1 {
   527  		insertionIndex++
   528  	}
   529  
   530  	var i, j int
   531  	var tempKeys [defaultOrder]string
   532  	var tempPointers [defaultOrder]unsafe.Pointer
   533  
   534  	// copy leaf keys and pointers to temp sets
   535  	// reserve space at insertion index for new record
   536  	for i, j = 0, 0; i < leaf.numKeys; i, j = i+1, j+1 {
   537  		if j == insertionIndex {
   538  			j++
   539  		}
   540  		tempKeys[j] = leaf.keys[i]
   541  		tempPointers[j] = leaf.pointers[i]
   542  	}
   543  
   544  	tempKeys[insertionIndex] = key
   545  	tempPointers[insertionIndex] = unsafe.Pointer(pointer)
   546  
   547  	leaf.numKeys = 0
   548  
   549  	// find pivot index where to split leaf
   550  	split := cut(defaultOrder - 1)
   551  
   552  	// overwrite original leaf up to the split point
   553  	for i = 0; i < split; i++ {
   554  		leaf.keys[i] = tempKeys[i]
   555  		leaf.pointers[i] = tempPointers[i]
   556  		leaf.numKeys++
   557  	}
   558  
   559  	// create new leaf
   560  	newLeaf := &bpNode{isLeaf: true} // makeLeaf()
   561  
   562  	// writing to new leaf from split point to end of original leaf pre split
   563  	for i, j = split, 0; i < defaultOrder; i, j = i+1, j+1 {
   564  		newLeaf.keys[j] = tempKeys[i]
   565  		newLeaf.pointers[j] = tempPointers[i]
   566  		newLeaf.numKeys++
   567  	}
   568  
   569  	// free temps
   570  	for i = 0; i < defaultOrder; i++ {
   571  		tempKeys[i] = *new(string) // zero Value
   572  		tempPointers[i] = nil      // zero Value
   573  	}
   574  
   575  	newLeaf.pointers[defaultOrder-1] = leaf.pointers[defaultOrder-1]
   576  	leaf.pointers[defaultOrder-1] = unsafe.Pointer(newLeaf)
   577  
   578  	for i = leaf.numKeys; i < defaultOrder-1; i++ {
   579  		leaf.pointers[i] = nil
   580  	}
   581  	for i = newLeaf.numKeys; i < defaultOrder-1; i++ {
   582  		newLeaf.pointers[i] = nil
   583  	}
   584  
   585  	newLeaf.parent = leaf.parent
   586  	newKey := newLeaf.keys[0]
   587  
   588  	return insertIntoParent(root, leaf, newKey, newLeaf)
   589  }
   590  
   591  /*
   592   *	findRecord finds and returns the Record to which a key refers
   593   */
   594  func (t *BPTree) find(key string) (*bpNode, *entry) {
   595  	leaf := findLeaf(t.root, key)
   596  	if leaf == nil {
   597  		return nil, nil
   598  	}
   599  	/*
   600  	 * If root/leaf != nil, leaf must have a Value, even if it does not contain the desired key.
   601  	 * The leaf holds the range of keys that would include the desired key
   602  	 */
   603  	var i int
   604  	for i = 0; i < leaf.numKeys; i++ {
   605  		if Equal(leaf.keys[i], key) {
   606  			break
   607  		}
   608  	}
   609  	if i == leaf.numKeys {
   610  		return leaf, nil
   611  	}
   612  	return leaf, (*entry)(leaf.pointers[i])
   613  }
   614  
   615  /*
   616   *	findEntry finds and returns the entry to which a key refers
   617   */
   618  func (t *BPTree) findEntry(key string) *entry {
   619  	leaf := findLeaf(t.root, key)
   620  	if leaf == nil {
   621  		return nil
   622  	}
   623  	/*
   624  	 * If root/leaf != nil, leaf must have a Value, even if it does not contain the desired key.
   625  	 * The leaf holds the range of keys that would include the desired key
   626  	 */
   627  	var i int
   628  	for i = 0; i < leaf.numKeys; i++ {
   629  		if Equal(leaf.keys[i], key) {
   630  			break
   631  		}
   632  	}
   633  	if i == leaf.numKeys {
   634  		return nil
   635  	}
   636  	return (*entry)(leaf.pointers[i])
   637  }
   638  
   639  /*
   640   *	findLeaf traces the path from the root to a leaf, searching by key and displaying information about the path if the
   641   *  verbose flag is set--findLeaf returns the leaf containing the given key
   642   */
   643  func findLeaf(root *bpNode, key string) *bpNode {
   644  	if root == nil {
   645  		return root
   646  	}
   647  	i, c := 0, root
   648  	for !c.isLeaf {
   649  		i = 0
   650  		for i < c.numKeys {
   651  			if Compare(key, c.keys[i]) >= 0 {
   652  				i++
   653  			} else {
   654  				break
   655  			}
   656  		}
   657  		c = (*bpNode)(c.pointers[i])
   658  	}
   659  	// c is the found leaf bpNode
   660  	return c
   661  }
   662  
   663  /*
   664   * findFirstLeaf traces the path from the root to the leftmost leaf in the tree
   665   */
   666  func findFirstLeaf(root *bpNode) *bpNode {
   667  	if root == nil {
   668  		return root
   669  	}
   670  	c := root
   671  	for !c.isLeaf {
   672  		c = (*bpNode)(c.pointers[0])
   673  	}
   674  	return c
   675  }
   676  
   677  func findLastLeaf(root *bpNode) *bpNode {
   678  	if root == nil {
   679  		return root
   680  	}
   681  	c := root
   682  	for !c.isLeaf {
   683  		c = (*bpNode)(c.pointers[c.numKeys])
   684  	}
   685  	return c
   686  }
   687  
   688  /*
   689   *  nextLeaf returns the next non-nil leaf in the chain (to the right) of the current leaf
   690   */
   691  func (n *bpNode) nextLeaf() *bpNode {
   692  	if p := (*bpNode)(n.pointers[defaultOrder-1]); p != nil && p.isLeaf {
   693  		return p
   694  	}
   695  	return nil
   696  }
   697  
   698  /*
   699   * delete is the master delete function
   700   */
   701  func (t *BPTree) delete(key string) *entry {
   702  	var old *entry
   703  	keyLeaf, keyEntry := t.find(key)
   704  	if keyEntry != nil && keyLeaf != nil {
   705  		t.root = deleteEntry(t.root, keyLeaf, key, unsafe.Pointer(keyEntry))
   706  		old = keyEntry
   707  		keyEntry = nil
   708  	}
   709  	return old // return the old entry we just deleted
   710  }
   711  
   712  /*
   713   * getNeighborIndex is a utility function for deletion. It gets the index of a bpNode's nearest
   714   * sibling (that exists) to the left. If not then bpNode is already the leftmost child and (in
   715   * such a case the bpNode) will return -1
   716   */
   717  func getNeighborIndex(n *bpNode) int {
   718  	var i int
   719  	for i = 0; i <= n.parent.numKeys; i++ {
   720  		if (*bpNode)(n.parent.pointers[i]) == n {
   721  			return i - 1
   722  		}
   723  	}
   724  	log.Panicf("getNeighborIndex: Search for nonexistent pointer to bpNode in parent.\nNode: %#v\n", n)
   725  	return i
   726  }
   727  
   728  /*
   729   * removeEntryFromNode does just that
   730   */
   731  func removeEntryFromNode(n *bpNode, key string, pointer unsafe.Pointer) *bpNode {
   732  
   733  	/*
   734  	 * Remove the key and shift the other keys accordingly
   735  	 */
   736  	var i, numPointers int
   737  	for !Equal(n.keys[i], key) {
   738  		i++
   739  	}
   740  	for i++; i < n.numKeys; i++ { // was for i+=1;
   741  		n.keys[i-1] = n.keys[i]
   742  	}
   743  
   744  	/*
   745  	 * Remove the pointer and shift other pointers accordingly
   746  	 */
   747  	if n.isLeaf {
   748  		numPointers = n.numKeys
   749  	} else {
   750  		numPointers = n.numKeys + 1
   751  	}
   752  
   753  	i = 0
   754  	for n.pointers[i] != pointer {
   755  		i++
   756  	}
   757  	for i++; i < numPointers; i++ { // was for i+=1;
   758  		n.pointers[i-1] = n.pointers[i]
   759  	}
   760  
   761  	/*
   762  	 * One key fewer
   763  	 */
   764  	n.numKeys--
   765  
   766  	/*
   767  	 * Set the other pointers to nil for tidiness. A leaf uses
   768  	 * the last pointer to point to the next leaf
   769  	 */
   770  	if n.isLeaf {
   771  		for i = n.numKeys; i < defaultOrder-1; i++ {
   772  			n.pointers[i] = nil
   773  		}
   774  	} else {
   775  		for i = n.numKeys + 1; i < defaultOrder; i++ {
   776  			n.pointers[i] = nil
   777  		}
   778  	}
   779  	return n
   780  }
   781  
   782  /*
   783   * deleteEntry deletes and entry from the tree. Removes the Record and it's key and pointer from
   784   * the leaf, and then makes all appropriate changes to preserve the tree's properties
   785   */
   786  func deleteEntry(root, n *bpNode, key string, pointer unsafe.Pointer) *bpNode {
   787  
   788  	var minKeys, kPrimeIndex, capacity int
   789  
   790  	/*
   791  	 * Remove key and pointer from bpNode
   792  	 */
   793  	n = removeEntryFromNode(n, key, pointer)
   794  
   795  	/*
   796  	 * CASE: deletion from the root bpNode
   797  	 */
   798  	if n == root {
   799  		return adjustRoot(root)
   800  	}
   801  
   802  	/*
   803  	 * CASE: deletion from a bpNode below the root (continue rest of function)
   804  	 *
   805  	 * Determine minimum allowable size of bpNode to be preserved after deletion
   806  	 */
   807  	if n.isLeaf {
   808  		minKeys = cut(defaultOrder - 1)
   809  	} else {
   810  		minKeys = cut(defaultOrder) - 1
   811  	}
   812  
   813  	/*
   814  	 * CASE: bpNode stays at or above minimum (simple case)
   815  	 */
   816  	if n.numKeys >= minKeys {
   817  		return root
   818  	}
   819  
   820  	/*
   821  			 * CASE: bpNode falls below minimum. Either coalescence or redistribution is needed
   822  		     *
   823  			 * Find the appropriate neighbor bpNode with which to coalesce. Also find the key (kPrime)
   824  			 * in the parent between the pointer to bpNode n and the pointer to the neighbor
   825  	*/
   826  	neighborIndex := getNeighborIndex(n)
   827  	if neighborIndex == -1 {
   828  		kPrimeIndex = 0
   829  	} else {
   830  		kPrimeIndex = neighborIndex
   831  	}
   832  
   833  	kPrime := n.parent.keys[kPrimeIndex]
   834  
   835  	var neighbor *bpNode
   836  	if neighborIndex == -1 {
   837  		neighbor = (*bpNode)(n.parent.pointers[1])
   838  	} else {
   839  		neighbor = (*bpNode)(n.parent.pointers[neighborIndex])
   840  	}
   841  
   842  	if n.isLeaf {
   843  		capacity = defaultOrder
   844  	} else {
   845  		capacity = defaultOrder - 1
   846  	}
   847  
   848  	/*
   849  	 * Coalescence
   850  	 */
   851  	if neighbor.numKeys+n.numKeys < capacity {
   852  		return coalesceNodes(root, n, neighbor, neighborIndex, kPrime)
   853  	}
   854  
   855  	/*S
   856  	 * Redistribution
   857  	 */
   858  	return redistributeNodes(root, n, neighbor, neighborIndex, kPrimeIndex, kPrime)
   859  }
   860  
   861  /*
   862   * adjustRoot does some magic in the root bpNode (not really)
   863   */
   864  func adjustRoot(root *bpNode) *bpNode {
   865  	/*
   866  	 * CASE: nonempty root. key and pointer have already been deleted, so nothing to be done
   867  	 */
   868  	if root.numKeys > 0 {
   869  		return root
   870  	}
   871  
   872  	/*
   873  	 * CASE: empty root. If it has a child, promote the first (only) child as the new root
   874  	 */
   875  	var newRoot *bpNode
   876  	if !root.isLeaf {
   877  		newRoot = (*bpNode)(root.pointers[0])
   878  		newRoot.parent = nil
   879  	} else {
   880  		/*
   881  		 * If it is a leaf (has no children), then the whole tree is in fact empty
   882  		 */
   883  		newRoot = nil // free
   884  	}
   885  	root = nil
   886  	return newRoot
   887  }
   888  
   889  /*
   890   * coalesceNodes coalesces a bpNode that has become too small after deletion with a
   891   * neighboring bpNode that can accept the additional entries without exceeing the maximum
   892   */
   893  func coalesceNodes(root, n, neighbor *bpNode, neighborIndex int, kPrime string) *bpNode {
   894  
   895  	var tmp *bpNode
   896  
   897  	/*
   898  	 * Swap neighbor with bpNode if bpNode is on the extreme left and neighbor is to it's right
   899  	 */
   900  	if neighborIndex == -1 {
   901  		tmp = n
   902  		n = neighbor
   903  		neighbor = tmp
   904  	}
   905  
   906  	/*
   907  	 * Starting point in the neighbor for copying keys and pointers from n. Recall that n and
   908  	 * neighbor have swapped places in the special case of n being a leftmost child
   909  	 */
   910  	neighborInsertionIndex := neighbor.numKeys
   911  	var i, j, nEnd int
   912  
   913  	/*
   914  	 * CASE: Nonleaf bpNode. Append kPrime and the following pointer and append all pointers and keys from the neighbor
   915  	 */
   916  	if !n.isLeaf {
   917  		/*
   918  		 * Append kPrime
   919  		 */
   920  		neighbor.keys[neighborInsertionIndex] = kPrime
   921  		neighbor.numKeys++
   922  		nEnd = n.numKeys
   923  
   924  		for i, j = neighborInsertionIndex+1, 0; j < nEnd; i, j = i+1, j+1 {
   925  			neighbor.keys[i] = n.keys[j]
   926  			neighbor.pointers[i] = n.pointers[j]
   927  			neighbor.numKeys++
   928  			n.numKeys--
   929  		}
   930  
   931  		/*
   932  		 * The number of pointers is always one more than the number of keys
   933  		 */
   934  		neighbor.pointers[i] = n.pointers[j]
   935  
   936  		/*
   937  		 * All children must now point up to the same parent
   938  		 */
   939  		for i = 0; i < neighbor.numKeys+1; i++ {
   940  			tmp = (*bpNode)(neighbor.pointers[i])
   941  			tmp.parent = neighbor
   942  		}
   943  		/*
   944  		 * CASE: In a leaf, append the keys and pointers of n to the neighbor.
   945  		 * Set the neighbor's last pointer to point to what had been n's right neighbor.
   946  		 */
   947  	} else {
   948  		for i, j = neighborInsertionIndex, 0; j < n.numKeys; i, j = i+1, j+1 {
   949  			neighbor.keys[i] = n.keys[j]
   950  			neighbor.pointers[i] = n.pointers[j]
   951  			neighbor.numKeys++
   952  		}
   953  		neighbor.pointers[defaultOrder-1] = n.pointers[defaultOrder-1]
   954  	}
   955  	root = deleteEntry(root, n.parent, kPrime, unsafe.Pointer(n))
   956  	n = nil // free
   957  	return root
   958  }
   959  
   960  /*
   961   * redistributeNodes redistributes entries between two nodes when one has become too small
   962   * after deletion but its neighbor is too big to append the small bpNode's entries without
   963   * exceeding the maximum
   964   */
   965  func redistributeNodes(root, n, neighbor *bpNode, neighborIndex, kPrimeIndex int, kPrime string) *bpNode {
   966  
   967  	var i int
   968  	var tmp *bpNode
   969  
   970  	/*
   971  	 * CASE: n has a neighbor to the left. Pull the neighbor's last key-pointer pair over
   972  	 * from the neighbor's right end to n's lef end
   973  	 */
   974  	if neighborIndex != -1 {
   975  		if !n.isLeaf {
   976  			n.pointers[n.numKeys+1] = n.pointers[n.numKeys]
   977  		}
   978  		for i = n.numKeys; i > 0; i-- {
   979  			n.keys[i] = n.keys[i-1]
   980  			n.pointers[i] = n.pointers[i-1]
   981  		}
   982  		if !n.isLeaf {
   983  			n.pointers[0] = neighbor.pointers[neighbor.numKeys]
   984  			tmp = (*bpNode)(n.pointers[0])
   985  			tmp.parent = n
   986  			neighbor.pointers[neighbor.numKeys] = nil
   987  			n.keys[0] = kPrime
   988  			n.parent.keys[kPrimeIndex] = neighbor.keys[neighbor.numKeys-1]
   989  		} else {
   990  			n.pointers[0] = neighbor.pointers[neighbor.numKeys-1]
   991  			neighbor.pointers[neighbor.numKeys-1] = nil
   992  			n.keys[0] = neighbor.keys[neighbor.numKeys-1]
   993  			n.parent.keys[kPrimeIndex] = n.keys[0]
   994  		}
   995  
   996  		/*
   997  		 * CASE: n is the leftmost child. Take a key-pointer pair from the neighbor
   998  		 * to the right.  Move the neighbor's leftmost key-pointer pair to n's rightmost position
   999  		 */
  1000  	} else {
  1001  		if n.isLeaf {
  1002  			n.keys[n.numKeys] = neighbor.keys[0]
  1003  			n.pointers[n.numKeys] = neighbor.pointers[0]
  1004  			n.parent.keys[kPrimeIndex] = neighbor.keys[1]
  1005  		} else {
  1006  			n.keys[n.numKeys] = kPrime
  1007  			n.pointers[n.numKeys+1] = neighbor.pointers[0]
  1008  			tmp = (*bpNode)(n.pointers[n.numKeys+1])
  1009  			tmp.parent = n
  1010  			n.parent.keys[kPrimeIndex] = neighbor.keys[0]
  1011  		}
  1012  		for i = 0; i < neighbor.numKeys-1; i++ {
  1013  			neighbor.keys[i] = neighbor.keys[i+1]
  1014  			neighbor.pointers[i] = neighbor.pointers[i+1]
  1015  		}
  1016  		if !n.isLeaf {
  1017  			neighbor.pointers[i] = neighbor.pointers[i+1]
  1018  		}
  1019  	}
  1020  
  1021  	/*
  1022  	 * n now has one more key and one more pointer; the neighbor has one fewer of each
  1023  	 */
  1024  	n.numKeys++
  1025  	neighbor.numKeys--
  1026  	return root
  1027  }
  1028  
  1029  func destroyTreeNodes(n *bpNode) {
  1030  	if n == nil {
  1031  		return
  1032  	}
  1033  	if n.isLeaf {
  1034  		for i := 0; i < n.numKeys; i++ {
  1035  			n.pointers[i] = nil
  1036  		}
  1037  	} else {
  1038  		for i := 0; i < n.numKeys+1; i++ {
  1039  			destroyTreeNodes((*bpNode)(n.pointers[i]))
  1040  		}
  1041  	}
  1042  	n = nil
  1043  }
  1044  
  1045  func (t *BPTree) destroyTree() {
  1046  	destroyTreeNodes(t.root)
  1047  }
  1048  
  1049  /*
  1050   *	cut finds the appropriate place to split a bpNode that is too big
  1051   */
  1052  func cut(length int) int {
  1053  	if length%2 == 0 {
  1054  		return length / 2
  1055  	}
  1056  	return length/2 + 1
  1057  }
  1058  
  1059  // makeRecord create a new Record to hold the Value to which a key refers
  1060  func makeRecord(value []byte) *entry {
  1061  	return &entry{
  1062  		Value: value,
  1063  	}
  1064  }
  1065  
  1066  // makeNode creates a new general bpNode, which can be adapted to serve as either a leaf or internal bpNode
  1067  func makeNode() *bpNode {
  1068  	return &bpNode{}
  1069  }
  1070  
  1071  // makeLeaf creates a new leaf by creating a bpNode and then adapting it appropriately
  1072  func makeLeaf() *bpNode {
  1073  	leaf := &bpNode{} // makeNode()
  1074  	leaf.isLeaf = true
  1075  	return leaf
  1076  }
  1077  
  1078  func Btoi(b []byte) int64 {
  1079  	return int64(b[7]) |
  1080  		int64(b[6])<<8 |
  1081  		int64(b[5])<<16 |
  1082  		int64(b[4])<<24 |
  1083  		int64(b[3])<<32 |
  1084  		int64(b[2])<<40 |
  1085  		int64(b[1])<<48 |
  1086  		int64(b[0])<<56
  1087  }
  1088  
  1089  func Itob(i int64) []byte {
  1090  	return []byte{
  1091  		byte(i >> 56),
  1092  		byte(i >> 48),
  1093  		byte(i >> 40),
  1094  		byte(i >> 32),
  1095  		byte(i >> 24),
  1096  		byte(i >> 16),
  1097  		byte(i >> 8),
  1098  		byte(i),
  1099  	}
  1100  }
  1101  
  1102  func IntToKey(key int64) string {
  1103  	return "i" + strconv.FormatInt(key, 10)
  1104  }
  1105  
  1106  func KeyToInt(key string) int64 {
  1107  	if len(key) != 11 || key[0] != 'i' {
  1108  		return -1
  1109  	}
  1110  	ikey, err := strconv.ParseInt(key[1:], 10, 0)
  1111  	if err != nil {
  1112  		return -1
  1113  	}
  1114  	return ikey
  1115  }
  1116  
  1117  func IntToVal(val int64) []byte {
  1118  	buf := make([]byte, 1+binary.MaxVarintLen64)
  1119  	buf[0] = 'i'
  1120  	_ = binary.PutVarint(buf[1:], val)
  1121  	return buf
  1122  }
  1123  
  1124  func ValToInt(val []byte) int64 {
  1125  	if len(val) != 11 || val[0] != 'i' {
  1126  		return -1
  1127  	}
  1128  	ival, n := binary.Varint(val[1:])
  1129  	if ival == 0 && n <= 0 {
  1130  		return -1
  1131  	}
  1132  	return ival
  1133  }