Search in sources :

Example 1 with ByteIterable

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.getFileSize() == 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)));
}
Also used : Log(jetbrains.exodus.log.Log) TooBigLoggableException(jetbrains.exodus.log.TooBigLoggableException) CompoundByteIterable(jetbrains.exodus.CompoundByteIterable) CompressedUnsignedLongByteIterable(jetbrains.exodus.log.CompressedUnsignedLongByteIterable) CompressedUnsignedLongArrayByteIterable(jetbrains.exodus.bindings.CompressedUnsignedLongArrayByteIterable) ByteIterable(jetbrains.exodus.ByteIterable) CompoundByteIterable(jetbrains.exodus.CompoundByteIterable)

Example 2 with ByteIterable

use of jetbrains.exodus.ByteIterable in project xodus by JetBrains.

the class LeafNode method reclaim.

protected void reclaim(@NotNull final BTreeReclaimTraverser context) {
    final ByteIterable keyIterable = getKey();
    if (!context.canMoveDown() && context.canMoveRight()) {
        final int leafIndex;
        final int cmp = context.compareCurrent(keyIterable);
        if (cmp > 0) {
            return;
        }
        if (cmp == 0) {
            leafIndex = context.currentPos;
        } else {
            context.moveRight();
            leafIndex = context.getNextSibling(keyIterable);
        }
        if (leafIndex >= 0) {
            doReclaim(context, leafIndex);
            context.moveTo(leafIndex + 1);
            return;
        } else if (context.canMoveTo(-leafIndex - 1)) {
            return;
        }
    }
    // go up
    if (context.canMoveUp()) {
        while (true) {
            context.popAndMutate();
            context.moveRight();
            final int index = context.getNextSibling(keyIterable);
            if (index < 0) {
                if (context.canMoveTo(-index - 1) || !context.canMoveUp()) {
                    context.moveTo(Math.max(-index - 2, 0));
                    break;
                }
            } else {
                // node is always internal
                context.pushChild(index);
                break;
            }
        }
    }
    // go down
    while (context.canMoveDown()) {
        int index = context.getNextSibling(keyIterable);
        if (index < 0) {
            index = Math.max(-index - 2, 0);
        }
        context.pushChild(index);
    }
    int leafIndex = context.getNextSibling(keyIterable);
    if (leafIndex >= 0) {
        doReclaim(context, leafIndex);
        context.moveTo(leafIndex + 1);
    } else {
        context.moveTo(-leafIndex - 1);
    }
}
Also used : CompressedUnsignedLongByteIterable(jetbrains.exodus.log.CompressedUnsignedLongByteIterable) ByteIterable(jetbrains.exodus.ByteIterable)

Example 3 with ByteIterable

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;
    }
}
Also used : ByteIterable(jetbrains.exodus.ByteIterable)

Example 4 with ByteIterable

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 (NullLoggable.isNullLoggable(log.getWrittenLoggableType(startAddress))) {
        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;
}
Also used : CompoundByteIterable(jetbrains.exodus.CompoundByteIterable) ByteIterable(jetbrains.exodus.ByteIterable) CompoundByteIterable(jetbrains.exodus.CompoundByteIterable)

Example 5 with ByteIterable

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);
    assert result;
    wasDelete = true;
    // root may be changed by tree.delete, so reset cursor with new root
    reset(tree.getRoot());
    return true;
}
Also used : ByteIterable(jetbrains.exodus.ByteIterable)

Aggregations

ByteIterable (jetbrains.exodus.ByteIterable)86 ArrayByteIterable (jetbrains.exodus.ArrayByteIterable)45 Test (org.junit.Test)26 CompressedUnsignedLongByteIterable (jetbrains.exodus.log.CompressedUnsignedLongByteIterable)15 Nullable (org.jetbrains.annotations.Nullable)11 ITreeCursor (jetbrains.exodus.tree.ITreeCursor)8 Cursor (jetbrains.exodus.env.Cursor)7 RandomAccessLoggable (jetbrains.exodus.log.RandomAccessLoggable)7 CompoundByteIterable (jetbrains.exodus.CompoundByteIterable)6 Store (jetbrains.exodus.env.Store)4 TreeSet (java.util.TreeSet)3 Transaction (jetbrains.exodus.env.Transaction)3 Exchange (com.persistit.Exchange)2 ExodusException (jetbrains.exodus.ExodusException)2 TokyoCabinetBenchmark (jetbrains.exodus.benchmark.TokyoCabinetBenchmark)2 Pair (jetbrains.exodus.core.dataStructures.Pair)2 HashSet (jetbrains.exodus.core.dataStructures.hash.HashSet)2 PersistentLongSet (jetbrains.exodus.core.dataStructures.persistent.PersistentLongSet)2 PersistentStoreTransaction (jetbrains.exodus.entitystore.PersistentStoreTransaction)2 Loggable (jetbrains.exodus.log.Loggable)2