This page describes the algorithms implemented in the Leaf class.
find() method
This method is used to find a specific value, given a key.
We just have to check in the current page if the key is present, and if so, to return the associated value, otherwise we return null.
find(key) : K -> V
pos = findPos( key )
if pos < 0
then
return values[ - ( pos + 1 ) ]
else
return null
insert() method
This method is terminal (it won't go down one level like the same method in the Node class), as we are now to insert the value in the page.
We have three cases to deal with here :
- The key already exists in the page
- The key does not exist but can be added in the page
- The key does not exist and the page is full
Let's see what it means for each case
- We just have to copy the page, changing its revision, replace the value, and reference the previous and next links. We also return the modified page and the old value
- This is a bit more complex : we have to insert the key and the value at the right place in a copy of the page, then we will change the revision, and update the references to the previous and next pages
- Even more complex : the page will be split, a new pivot will be computed and send back to the caller.
Here is the algorithm :
Leaf.insert(revision, key, value) : (long, K, V) -> InsertResult<K, V>
pos <- findPos(key)
if pos < 0 then
index <- -(pos + 1)
return replaceElement(revision, key, value, index)
else
if nbElems < BTree.pageSize
then return addElement(revision, key, value, pos)
else return page.addAndSplit(revision, key, value, pos)
This helper method is used to implement the first case :
Leaf.replaceElement(revision, key, value, pos) : (long, K, V, int) -> InsertResult<K, V>
newLeaf <- new Leaf( btree, revision, nbElems );
copy keys[0..nbElems] to newLeaf.keys[0..nbElems]
copy values[0..nbElems] to newLeaf.values[0..nbElems]
oldValue <- newLeaf.values[index]
newLeaf.values[index] <- value
newLeaf.prev <- this.prev
newLeaf.next <- this.next
InsertResult<K, V> result <- new ModifyResult()
result.modifiedValue = oldValue
result.modifiedPage = newLeaf
return result
This helper class is used to manage the case 2 :
Leaf.addElement(revision, key, value, pos) : (long, K, V, int) -> InsertResult<K, V>
newLeaf <- new Leaf( btree, revision, nbElems + 1 );
copy keys[0..pos] to newLeaf.keys[0..pos]
newLeaf.keys[pos] <- key
copy keys[pos..nbElems] to newLeaf.keys[pos+1..nbElems+1]
copy values[0..pos] to newLeaf.values[0..pos]
newLeaf.values[pos] <- value
copy values[pos..nbElems] to newLeaf.values[pos+1..nbElems+1]
newLeaf.prev <- this.prev
newLeaf.next <- this.next
InsertResult<K, V> result <- new ModifyResult()
result.modifiedValue = null
result.modifiedPage = newLeaf
return result
This helper method is used to create the split pages :
Leaf.addAndSplit(revision, key, value, pos) : (long, K, V, int) -> InsertResult<K, V>
middle <- nbPageSize / 2
leftPage <- null
rightPage <- null
if pos <= middle
then
leftPage <- new Leaf(btree, revision, middle + 1)
copy keys[0..pos] to leftPage.keys[0..pos]
leftPage.keys[pos] <- key
copy keys[pos..middle] to leftPage.keys[pos+1..middle+1]
copy values[0..pos] to leftPage.values[0..pos]
leftPage.values[pos] <- value
copy values[pos..middle] to leftPage.values[pos+1..middle+1]
rightPage <- new Leaf(btree, revision, middle)
copy keys[middle..nbElems] to rightPage.keys[0..middle]
copy values[middle..nbElems] to rightPage.values[0..middle]
else
leftPage <- new Leaf(btree, revision, middle)
copy keys[0..middle] to leftPage.keys[0..middle]
copy values[0..middle] to leftPage.values[0..middle]
rightPage <- new Leaf(btree, revision, middle + 1)
copy keys[middle..pos] to rightPage.keys[0..pos]
rightPage.keys[pos] <- key
copy keys[pos..nbElems] to rightPage.keys[pos+1..middle+1]
copy values[middle..pos] to rightPage.values[0..pos]
rightPage.values[pos] <- value
copy values[pos..nbElems] to rightPage.values[pos+1..middle+1]
leftPage.prev <- this.prev
leftPage.next <- rightPag
rightPage.prev <- leftPage
rightPage.next <- this.next
newPivot <- rightPage.keys[0]
InsertResult<K, V> result <- new SplitResult()
result.newPivot <- newPivot
result.leftPage <- leftPage
result.rightPage <- rightPage
return result
delete() method
TODO