Skip to content

Commit

Permalink
InternalTreeLogic, split leaf without using tmp byte[]
Browse files Browse the repository at this point in the history
  • Loading branch information
tinwelint authored and burqen committed Dec 21, 2016
1 parent f62a64c commit 906c15c
Show file tree
Hide file tree
Showing 2 changed files with 63 additions and 21 deletions.
Expand Up @@ -431,10 +431,10 @@ private void splitLeaf( PageCursor cursor, StructurePropagation<KEY> structurePr
int pos = positionOf( search( cursor, bTreeNode, newKey, readKey, keyCount ) ); int pos = positionOf( search( cursor, bTreeNode, newKey, readKey, keyCount ) );


// arrays to temporarily store all keys and values // arrays to temporarily store all keys and values
bTreeNode.readKeysWithInsertRecordInPosition( cursor, // bTreeNode.readKeysWithInsertRecordInPosition( cursor,
c -> layout.writeKey( c, newKey ), pos, bTreeNode.leafMaxKeyCount() + 1, tmpForKeys ); // c -> layout.writeKey( c, newKey ), pos, bTreeNode.leafMaxKeyCount() + 1, tmpForKeys );
bTreeNode.readValuesWithInsertRecordInPosition( cursor, // bTreeNode.readValuesWithInsertRecordInPosition( cursor,
c -> layout.writeValue( c, newValue ), pos, bTreeNode.leafMaxKeyCount() + 1, tmpForValues ); // c -> layout.writeValue( c, newValue ), pos, bTreeNode.leafMaxKeyCount() + 1, tmpForValues );


int keyCountAfterInsert = keyCount + 1; int keyCountAfterInsert = keyCount + 1;
int middlePos = middle( keyCountAfterInsert, options.splitRetentionFactor() ); int middlePos = middle( keyCountAfterInsert, options.splitRetentionFactor() );
Expand All @@ -459,35 +459,77 @@ private void splitLeaf( PageCursor cursor, StructurePropagation<KEY> structurePr
bTreeNode.keyAt( cursor, structurePropagation.primKey, pos < middlePos ? middlePos - 1 : middlePos ); bTreeNode.keyAt( cursor, structurePropagation.primKey, pos < middlePos ? middlePos - 1 : middlePos );
} }


{ // Update new right // Update new right
goTo( cursor, "new right sibling in split", newRight ); try ( PageCursor rightCursor = cursor.openLinkedCursor( newRight ) )
bTreeNode.initializeLeaf( cursor, stableGeneration, unstableGeneration ); {
bTreeNode.setRightSibling( cursor, oldRight, stableGeneration, unstableGeneration ); goTo( rightCursor, "new right sibling in split", newRight );
bTreeNode.setLeftSibling( cursor, current, stableGeneration, unstableGeneration ); bTreeNode.initializeLeaf( rightCursor, stableGeneration, unstableGeneration );
bTreeNode.writeKeys( cursor, tmpForKeys, middlePos, 0, keyCountAfterInsert - middlePos ); bTreeNode.setRightSibling( rightCursor, oldRight, stableGeneration, unstableGeneration );
bTreeNode.writeValues( cursor, tmpForValues, middlePos, 0, keyCountAfterInsert - middlePos ); bTreeNode.setLeftSibling( rightCursor, current, stableGeneration, unstableGeneration );
bTreeNode.setKeyCount( cursor, keyCountAfterInsert - middlePos ); int rightKeyCount = keyCountAfterInsert - middlePos;

if ( pos < middlePos )
{
// v-------v copy
// before _,_,_,_,_,_,_,_,_,_
// insert _,_,_,X,_,_,_,_,_,_,_
// middle ^
copyKeysAndValues( cursor, middlePos - 1, rightCursor, 0, rightKeyCount );
}
else
{
// v---v first copy
// v-v second copy
// before _,_,_,_,_,_,_,_,_,_
// insert _,_,_,_,_,_,_,_,X,_,_
// middle ^
int countBeforePos = pos - middlePos;
if ( countBeforePos > 0 )
{
// first copy
copyKeysAndValues( cursor, middlePos, rightCursor, 0, countBeforePos );
}
bTreeNode.insertKeyAt( rightCursor, newKey, countBeforePos, countBeforePos );
bTreeNode.insertValueAt( rightCursor, newValue, countBeforePos, countBeforePos );
int countAfterPos = keyCount - pos;
if ( countAfterPos > 0 )
{
// second copy
copyKeysAndValues( cursor, pos, rightCursor, countBeforePos + 1, countAfterPos );
}
}
bTreeNode.setKeyCount( rightCursor, rightKeyCount );
} }


// Update old right with new left sibling (newRight) // Update old right with new left sibling (newRight)
if ( TreeNode.isNode( oldRight ) ) if ( TreeNode.isNode( oldRight ) )
{ {
bTreeNode.goTo( cursor, "old right sibling", oldRight ); try ( PageCursor oldRightCursor = cursor.openLinkedCursor( oldRight ) )
bTreeNode.setLeftSibling( cursor, newRight, stableGeneration, unstableGeneration ); {
bTreeNode.goTo( oldRightCursor, "old right sibling", oldRight );
bTreeNode.setLeftSibling( oldRightCursor, newRight, stableGeneration, unstableGeneration );
}
} }


// Update left child // Update left child
bTreeNode.goTo( cursor, "left", current );
bTreeNode.setKeyCount( cursor, middlePos );
// If pos < middle. Write shifted values to left node. Else, don't write anything. // If pos < middle. Write shifted values to left node. Else, don't write anything.
if ( pos < middlePos ) if ( pos < middlePos )
{ {
bTreeNode.writeKeys( cursor, tmpForKeys, pos, pos, middlePos - pos ); bTreeNode.insertKeyAt( cursor, newKey, pos, middlePos - 1 );
bTreeNode.writeValues( cursor, tmpForValues, pos, pos, middlePos - pos ); bTreeNode.insertValueAt( cursor, newValue, pos, middlePos - 1 );
} }
bTreeNode.setKeyCount( cursor, middlePos );
bTreeNode.setRightSibling( cursor, newRight, stableGeneration, unstableGeneration ); bTreeNode.setRightSibling( cursor, newRight, stableGeneration, unstableGeneration );
} }


private void copyKeysAndValues( PageCursor cursor, int fromPos, PageCursor rightCursor, int toPos, int count )
{
cursor.copyTo( bTreeNode.keyOffset( fromPos ), rightCursor, bTreeNode.keyOffset( toPos ),
count * bTreeNode.keySize() );
cursor.copyTo( bTreeNode.valueOffset( fromPos ), rightCursor, bTreeNode.valueOffset( toPos ),
count * bTreeNode.valueSize() );
}

/** /**
* Remove given {@code key} and associated value from tree if it exists. The removed value will be stored in * Remove given {@code key} and associated value from tree if it exists. The removed value will be stored in
* provided {@code into} which will be returned for convenience. * provided {@code into} which will be returned for convenience.
Expand Down
Expand Up @@ -261,9 +261,9 @@ private void removeSlotAt( PageCursor cursor, int pos, int keyCount, int baseOff
* Moves items (key/value/child) one step to the right, which means rewriting all items of the particular type * Moves items (key/value/child) one step to the right, which means rewriting all items of the particular type
* from pos - keyCount. * from pos - keyCount.
*/ */
private void insertSlotAt( PageCursor cursor, int pos, int toExcluding, int baseOffset, int itemSize ) private void insertSlotAt( PageCursor cursor, int pos, int keyCount, int baseOffset, int itemSize )
{ {
for ( int posToMoveRight = toExcluding - 1, offset = baseOffset + posToMoveRight * itemSize; for ( int posToMoveRight = keyCount - 1, offset = baseOffset + posToMoveRight * itemSize;
posToMoveRight >= pos; posToMoveRight--, offset -= itemSize ) posToMoveRight >= pos; posToMoveRight--, offset -= itemSize )
{ {
cursor.copyTo( offset, cursor, offset + itemSize, itemSize ); cursor.copyTo( offset, cursor, offset + itemSize, itemSize );
Expand Down Expand Up @@ -335,7 +335,7 @@ int keyOffset( int pos )
return HEADER_LENGTH + pos * keySize; return HEADER_LENGTH + pos * keySize;
} }


private int valueOffset( int pos ) int valueOffset( int pos )
{ {
return HEADER_LENGTH + leafMaxKeyCount * keySize + pos * valueSize; return HEADER_LENGTH + leafMaxKeyCount * keySize + pos * valueSize;
} }
Expand Down

0 comments on commit 906c15c

Please sign in to comment.