* as a unit. Recovery skips provisional entries, so the changed
* children are only used if the parent makes it out to the log.
*/
EnvironmentImpl env = databaseImpl.getDbEnvironment();
LogManager logManager = env.getLogManager();
INList inMemoryINs = env.getInMemoryINs();
long newSiblingLsn = newSibling.logProvisional(logManager, parent);
long myNewLsn = logProvisional(logManager, parent);
/*
* When we update the parent entry, we use updateEntryCompareKey so
* that we don't replace the parent's key that points at 'this'
* with a key that is > than the existing one. Replacing the
* parent's key with something > would effectively render a piece
* of the subtree inaccessible. So only replace the parent key
* with something <= the existing one. See tree/SplitTest.java for
* more details on the scenario.
*/
if (low == 0) {
/*
* Change the original entry to point to the new child and add
* an entry to point to the newly logged version of this
* existing child.
*/
if (childIndex == 0) {
parent.updateEntryCompareKey(childIndex, newSibling,
newSiblingLsn, newIdKey);
} else {
parent.updateEntry(childIndex, newSibling, newSiblingLsn);
}
boolean insertOk = parent.insertEntry
(new ChildReference(this, entryKeyVals[0], myNewLsn));
assert insertOk;
} else {
/*
* Update the existing child's LSN to reflect the newly logged
* version and insert new child into parent.
*/
if (childIndex == 0) {
/*
* This's idkey may be < the parent's entry 0 so we need to
* update parent's entry 0 with the key for 'this'.
*/
parent.updateEntryCompareKey
(childIndex, this, myNewLsn, entryKeyVals[0]);
} else {
parent.updateEntry(childIndex, this, myNewLsn);
}
boolean insertOk = parent.insertEntry
(new ChildReference(newSibling, newIdKey, newSiblingLsn));
assert insertOk;
}
parentLsn = parent.log(logManager);
/*
* Maintain dirtiness if this is the root, so this parent
* will be checkpointed. Other parents who are not roots
* are logged as part of the propagation of splits
* upwards.
*/
if (parent.isRoot()) {
parent.setDirty(true);
}
/*
* Update size. newSibling and parent are correct, but this IN has
* had its entries shifted and is not correct.
*/
long newSize = computeMemorySize();
updateMemorySize(oldMemorySize, newSize);
inMemoryINs.add(newSibling);
/* Debug log this information. */
traceSplit(Level.FINE, parent,
newSibling, parentLsn, myNewLsn,
newSiblingLsn, splitIndex, idKeyIndex, childIndex);