use of jetbrains.exodus.ByteIterable in project xodus by JetBrains.
the class BTreeCursorDupMutable method getNextDup.
@Override
public boolean getNextDup() {
moveIfNecessary();
// move to next dup if in -1 position or dupCursor has next element
if (traverser.node == ILeafNode.EMPTY) {
if (wasDelete) {
// traverser was reset to root after delete
final BasePage root = traverser.currentNode;
final ByteIterable key = nextAfterRemovedKey;
final ByteIterable value = nextAfterRemovedValue;
if (getNext()) {
if (traverser.inDupTree) {
return true;
}
// not really a dup, rollback
// also restores state
reset((MutableTreeRoot) root);
wasDelete = true;
nextAfterRemovedKey = key;
nextAfterRemovedValue = value;
}
return false;
}
return getNext();
} else {
return hasNext() && traverser.inDupTree && getNext() && traverser.inDupTree;
}
}
use of jetbrains.exodus.ByteIterable in project xodus by JetBrains.
the class BTreeDupMutable method save.
@Override
public long save() {
if (address != Loggable.NULL_ADDRESS) {
throw new IllegalStateException("Duplicates sub-tree already saved");
}
final BasePageMutable rootPage = getRoot();
final byte type = rootPage.isBottom() ? BTreeBase.LEAF_DUP_BOTTOM_ROOT : BTreeBase.LEAF_DUP_INTERNAL_ROOT;
final ByteIterable keyIterable = CompressedUnsignedLongByteIterable.getIterable(key.getLength());
ByteIterable sizeIterable;
// remember high address before saving the data
long startAddress = log.getWrittenHighAddress();
final ByteIterable rootDataIterable = rootPage.getData();
ByteIterable[] iterables;
long result;
final boolean canRetry;
if (log.isLastWrittenFileAddress(startAddress)) {
sizeIterable = CompressedUnsignedLongByteIterable.getIterable(size << 1);
iterables = new ByteIterable[] { keyIterable, key, sizeIterable, rootDataIterable };
result = log.tryWrite(type, structureId, new CompoundByteIterable(iterables));
if (result >= 0) {
address = result;
return result;
} else {
canRetry = false;
}
} else {
canRetry = true;
}
if (!log.isLastWrittenFileAddress(startAddress)) {
final byte writtenType = log.getWrittenLoggableType(startAddress, BTreeBase.DUP_LEAF);
if (NullLoggable.isNullLoggable(writtenType)) {
final long lengthBound = log.getFileLengthBound();
final long alignment = startAddress % lengthBound;
startAddress += (lengthBound - alignment);
if (log.getWrittenHighAddress() < startAddress) {
throw new IllegalStateException("Address alignment underflow: start address " + startAddress + ", alignment " + alignment);
}
}
}
sizeIterable = CompressedUnsignedLongByteIterable.getIterable((size << 1) + 1);
final ByteIterable offsetIterable = CompressedUnsignedLongByteIterable.getIterable(log.getWrittenHighAddress() - startAddress);
iterables = new ByteIterable[] { keyIterable, key, sizeIterable, offsetIterable, rootDataIterable };
final ByteIterable data = new CompoundByteIterable(iterables);
result = canRetry ? log.tryWrite(type, structureId, data) : log.writeContinuously(type, structureId, data);
if (result < 0) {
if (canRetry) {
iterables[3] = CompressedUnsignedLongByteIterable.getIterable(log.getWrittenHighAddress() - startAddress);
result = log.writeContinuously(type, structureId, new CompoundByteIterable(iterables));
if (result < 0) {
throw new TooBigLoggableException();
}
} else {
throw new TooBigLoggableException();
}
}
address = result;
return result;
}
use of jetbrains.exodus.ByteIterable in project xodus by JetBrains.
the class BasePageMutable method save.
/**
* Save page to log
*
* @return address of this page after save
*/
protected long save() {
// save leaf nodes
ReclaimFlag flag = saveChildren();
// save self. complementary to {@link load()}
final byte type = getType();
final BTreeBase tree = getTree();
final int structureId = tree.structureId;
final Log log = tree.log;
if (flag == ReclaimFlag.PRESERVE) {
// there is a chance to update the flag to RECLAIM
if (log.getWrittenHighAddress() % log.getFileLengthBound() == 0) {
// page will be exactly on file border
flag = ReclaimFlag.RECLAIM;
} else {
final ByteIterable[] iterables = getByteIterables(flag);
long result = log.tryWrite(type, structureId, new CompoundByteIterable(iterables));
if (result < 0) {
iterables[0] = CompressedUnsignedLongByteIterable.getIterable((size << 1) + ReclaimFlag.RECLAIM.value);
result = log.writeContinuously(type, structureId, new CompoundByteIterable(iterables));
if (result < 0) {
throw new TooBigLoggableException();
}
}
return result;
}
}
return log.write(type, structureId, new CompoundByteIterable(getByteIterables(flag)));
}
use of jetbrains.exodus.ByteIterable in project xodus by JetBrains.
the class TreeCursorMutable method deleteCurrent.
@Override
public boolean deleteCurrent() {
moveIfNecessary();
if (wasDelete) {
return false;
}
// delete and remember next
final ByteIterable key = getKey();
final ByteIterable value = getValue();
if (getNext()) {
nextAfterRemovedKey = traverser.getKey();
nextAfterRemovedValue = traverser.getValue();
} else {
nextAfterRemovedKey = null;
nextAfterRemovedValue = null;
}
// don't call back treeChanged() for current cursor
boolean result = tree.isAllowingDuplicates() ? tree.delete(key, value, this) : tree.delete(key, null, this);
wasDelete = true;
// root may be changed by tree.delete, so reset cursor with new root
reset(tree.getRoot());
return true;
}
use of jetbrains.exodus.ByteIterable in project xodus by JetBrains.
the class TreeCursorMutable method treeChanged.
@Override
public void treeChanged() {
if (moveToKey == null) {
final ByteIterable key = getKey();
final ByteIterable value = getValue();
moveToKey = key;
moveToValue = value;
}
}
Aggregations