private void CopyKeysAndValues(PageCursor fromCursor, int fromPos, PageCursor toCursor, int toPos, int count) { fromCursor.CopyTo(KeyOffset(fromPos), toCursor, KeyOffset(toPos), count * KeySize()); fromCursor.CopyTo(ValueOffset(fromPos), toCursor, ValueOffset(toPos), count * ValueSize()); }
internal override void DoSplitInternal(PageCursor leftCursor, int leftKeyCount, PageCursor rightCursor, int insertPos, KEY newKey, long newRightChild, long stableGeneration, long unstableGeneration, KEY newSplitter, double ratioToKeepInLeftOnSplit) { int keyCountAfterInsert = leftKeyCount + 1; int splitPos = splitPos(keyCountAfterInsert, ratioToKeepInLeftOnSplit); if (splitPos == insertPos) { Layout.copyKey(newKey, newSplitter); } else { KeyAt(leftCursor, newSplitter, insertPos < splitPos ? splitPos - 1 : splitPos, INTERNAL); } int rightKeyCount = keyCountAfterInsert - splitPos - 1; // -1 because don't keep prim key in internal if (insertPos < splitPos) { // v-------v copy // before key _,_,_,_,_,_,_,_,_,_ // before child -,-,-,-,-,-,-,-,-,-,- // insert key _,_,X,_,_,_,_,_,_,_,_ // insert child -,-,-,x,-,-,-,-,-,-,-,- // split key ^ leftCursor.CopyTo(KeyOffset(splitPos), rightCursor, KeyOffset(0), rightKeyCount * KeySize()); leftCursor.CopyTo(ChildOffset(splitPos), rightCursor, ChildOffset(0), (rightKeyCount + 1) * ChildSize()); InsertKeyAt(leftCursor, newKey, insertPos, splitPos - 1); InsertChildAt(leftCursor, newRightChild, insertPos + 1, splitPos - 1, stableGeneration, unstableGeneration); } else { // pos > splitPos // v-v first copy // v-v-v second copy // before key _,_,_,_,_,_,_,_,_,_ // before child -,-,-,-,-,-,-,-,-,-,- // insert key _,_,_,_,_,_,_,X,_,_,_ // insert child -,-,-,-,-,-,-,-,x,-,-,- // split key ^ // pos == splitPos // first copy // v-v-v-v-v second copy // before key _,_,_,_,_,_,_,_,_,_ // before child -,-,-,-,-,-,-,-,-,-,- // insert key _,_,_,_,_,X,_,_,_,_,_ // insert child -,-,-,-,-,-,x,-,-,-,-,- // split key ^ // Keys int countBeforePos = insertPos - (splitPos + 1); // ... first copy if (countBeforePos > 0) { leftCursor.CopyTo(KeyOffset(splitPos + 1), rightCursor, KeyOffset(0), countBeforePos * KeySize()); } // ... insert if (countBeforePos >= 0) { InsertKeyAt(rightCursor, newKey, countBeforePos, countBeforePos); } // ... second copy int countAfterPos = leftKeyCount - insertPos; if (countAfterPos > 0) { leftCursor.CopyTo(KeyOffset(insertPos), rightCursor, KeyOffset(countBeforePos + 1), countAfterPos * KeySize()); } // Children countBeforePos = insertPos - splitPos; // ... first copy if (countBeforePos > 0) { // first copy leftCursor.CopyTo(ChildOffset(splitPos + 1), rightCursor, ChildOffset(0), countBeforePos * ChildSize()); } // ... insert InsertChildAt(rightCursor, newRightChild, countBeforePos, countBeforePos, stableGeneration, unstableGeneration); // ... second copy if (countAfterPos > 0) { leftCursor.CopyTo(ChildOffset(insertPos + 1), rightCursor, ChildOffset(countBeforePos + 1), countAfterPos * ChildSize()); } } TreeNode.SetKeyCount(leftCursor, splitPos); TreeNode.SetKeyCount(rightCursor, rightKeyCount); }