use of jetbrains.exodus.ByteIterator in project xodus by JetBrains.
the class PatriciaTreeMutable method reclaim.
private static void reclaim(@NotNull final PatriciaReclaimSourceTraverser source, @NotNull final PatriciaReclaimActualTraverser actual) {
final NodeBase actualNode = actual.currentNode;
final NodeBase sourceNode = source.currentNode;
if (actualNode.getAddress() == sourceNode.getAddress()) {
actual.currentNode = actualNode.getMutableCopy(actual.mainTree);
actual.getItr();
actual.wasReclaim = true;
reclaimActualChildren(source, actual);
} else {
@NotNull ByteIterator srcItr = sourceNode.keySequence.iterator();
@NotNull ByteIterator actItr = actualNode.keySequence.iterator();
int srcPushes = 0;
int actPushes = 0;
while (true) {
if (srcItr.hasNext()) {
if (actItr.hasNext()) {
if (srcItr.next() != actItr.next()) {
// key is not matching
break;
}
} else {
final NodeChildrenIterator children = actual.currentNode.getChildren(srcItr.next());
final ChildReference child = children.getNode();
if (child == null) {
break;
}
actual.currentChild = child;
actual.currentIterator = children;
actual.moveDown();
++actPushes;
actItr = actual.currentNode.keySequence.iterator();
}
} else if (actItr.hasNext()) {
final NodeChildrenIterator children = source.currentNode.getChildren(actItr.next());
final ChildReference child = children.getNode();
if (child == null || !source.isAddressReclaimable(child.suffixAddress)) {
// child can be expired if source parent was already not-current
break;
}
source.currentChild = child;
source.currentIterator = children;
source.moveDown();
++srcPushes;
srcItr = source.currentNode.keySequence.iterator();
} else {
// both iterators matched, here comes the branching
reclaimChildren(source, actual);
break;
}
}
for (int i = 0; i < srcPushes; ++i) {
source.moveUp();
}
for (int i = 0; i < actPushes; ++i) {
actual.popAndMutate();
}
}
}
use of jetbrains.exodus.ByteIterator in project xodus by JetBrains.
the class NodeBase method matchesKeySequence.
long matchesKeySequence(@NotNull final ByteIterator it) {
int matchingLength = 0;
final ByteIterator keyIt = keySequence.iterator();
while (keyIt.hasNext()) {
final byte keyByte = keyIt.next();
if (!it.hasNext()) {
return MatchResult.getMatchResult(-matchingLength - 1, keyByte, false, (byte) 0);
}
final byte nextByte = it.next();
if (nextByte != keyByte) {
return MatchResult.getMatchResult(-matchingLength - 1, keyByte, true, nextByte);
}
++matchingLength;
}
return MatchResult.getMatchResult(matchingLength);
}
use of jetbrains.exodus.ByteIterator in project xodus by JetBrains.
the class LinkValue method entryToLinkValue.
public static LinkValue entryToLinkValue(@NotNull final ByteIterable entry) {
final ByteIterator it = entry.iterator();
final int linkId = IntegerBinding.readCompressed(it);
return new LinkValue(EntityIdBinding.iteratorToEntityId(it), linkId);
}
use of jetbrains.exodus.ByteIterator in project xodus by JetBrains.
the class PropertyKey method entryToPropertyKey.
public static PropertyKey entryToPropertyKey(@NotNull final ByteIterable entry) {
final ByteIterator it = entry.iterator();
final long entityLocalId = LongBinding.readCompressed(it);
final int propertyId = IntegerBinding.readCompressed(it);
return new PropertyKey(entityLocalId, propertyId);
}
use of jetbrains.exodus.ByteIterator in project xodus by JetBrains.
the class PatriciaTraverser method moveToRange.
@Override
public boolean moveToRange(@NotNull ByteIterable key, @Nullable ByteIterable value) {
final ByteIterator it = key.iterator();
// the most bottom node, ignoring lower bound
NodeBase node = top == 0 ? currentNode : stack[0].getParentNode();
int depth = 0;
NodeChildrenIterator[] tmp = new NodeChildrenIterator[INITIAL_STACK_CAPACITY];
// go down and search
final boolean dive;
boolean smaller = false;
while (true) {
final boolean hasNext = it.hasNext();
final long matchResult = node.matchesKeySequence(it);
if (NodeBase.MatchResult.getMatchingLength(matchResult) < 0) {
if (value == null) {
smaller = NodeBase.MatchResult.hasNext(matchResult) && (!hasNext || NodeBase.MatchResult.getKeyByte(matchResult) < NodeBase.MatchResult.getNextByte(matchResult));
dive = !smaller;
break;
}
return false;
}
if (!it.hasNext()) {
// key match
if (!node.hasValue()) {
dive = true;
break;
}
if (value == null || value.compareTo(node.getValue()) <= 0) {
setCurrentNode(node);
getItr();
stack = tmp;
top = depth;
return true;
}
return false;
}
final byte nextByte = it.next();
NodeChildrenIterator itr = node.getChildren(nextByte);
ChildReference ref = itr.getNode();
if (ref == null) {
itr = node.getChildrenRange(nextByte);
ref = itr.getNode();
if (ref != null) {
tmp = pushIterator(tmp, itr, depth++);
node = ref.getNode(tree);
dive = true;
break;
}
smaller = true;
dive = false;
break;
}
tmp = pushIterator(tmp, itr, depth++);
node = ref.getNode(tree);
}
if (smaller || !node.hasValue()) {
if (dive && node.getChildrenCount() > 0) {
final NodeChildrenIterator itr = node.getChildren().iterator();
tmp = pushIterator(tmp, itr, depth);
node = itr.next().getNode(tree);
} else {
// go up and try range search
NodeChildrenIterator itr;
do {
if (depth > 0) {
itr = tmp[--depth];
} else {
// search already gave us the max
return false;
}
} while (!itr.hasNext());
node = itr.next().getNode(tree);
// trick: tmp[depth] was already in stack
}
++depth;
while (!node.hasValue()) {
final NodeChildrenIterator itr = node.getChildren().iterator();
if (!itr.hasNext()) {
throw new IllegalStateException("Can't dive into tree branch");
}
final ChildReference ref = itr.next();
tmp = pushIterator(tmp, itr, depth++);
node = ref.getNode(tree);
}
}
setCurrentNode(node);
getItr();
stack = tmp;
top = depth;
return true;
}
Aggregations