use of jetbrains.exodus.tree.ITreeCursor in project xodus by JetBrains.
the class PatriciaCursorDecorator method getSearchBothRange.
@Nullable
@Override
public ByteIterable getSearchBothRange(@NotNull ByteIterable key, @NotNull ByteIterable value) {
final ITreeCursor cursor = patriciaCursor.getTree().openCursor();
ITreeCursor cursorToClose = cursor;
try {
ByteIterable keyLengthIterable = cursor.getSearchKeyRange(new EscapingByteIterable(key));
if (keyLengthIterable != null) {
final int srcKeyLength = key.getLength();
final int valueLength = value.getLength();
while (true) {
int keyLength = CompressedUnsignedLongByteIterable.getInt(keyLengthIterable);
if (srcKeyLength == keyLength) {
final ByteIterable noDupKey = new UnEscapingByteIterable(cursor.getKey());
final byte[] srcKeyBytes = key.getBytesUnsafe();
final byte[] noDupKeyBytes = noDupKey.getBytesUnsafe();
if (ByteIterableUtil.compare(srcKeyBytes, keyLength, noDupKeyBytes, keyLength) == 0) {
// skip separator
final int noDupKeyLength = noDupKey.getLength() - keyLength - 1;
final int cmp = ByteIterableUtil.compare(noDupKeyBytes, noDupKeyLength, keyLength + 1, value.getBytesUnsafe(), valueLength);
if (cmp >= 0) {
keyBytes = noDupKeyBytes;
this.keyLength = keyLength;
this.valueLength = noDupKeyLength;
cursorToClose = patriciaCursor;
patriciaCursor = cursor;
// forget computed next pair
nextKeyLength = UNKNOWN;
// forget computed prev pair
prevKeyLength = UNKNOWN;
return getValue();
}
}
}
if (cursor.getNext()) {
keyLengthIterable = cursor.getValue();
} else {
break;
}
}
}
} finally {
cursorToClose.close();
}
return null;
}
use of jetbrains.exodus.tree.ITreeCursor in project xodus by JetBrains.
the class PatriciaCursorDecorator method count.
@Override
public int count() {
int result = 0;
try (ITreeCursor cursor = patriciaCursor.getTree().openCursor()) {
@Nullable ByteIterable value = cursor.getSearchKeyRange(new EscapingByteIterable(getKey()));
while (value != null) {
if (keyLength != CompressedUnsignedLongByteIterable.getInt(value)) {
break;
}
final ByteIterable noDupKey = new UnEscapingByteIterable(cursor.getKey());
if (ByteIterableUtil.compare(keyBytes, keyLength, noDupKey.getBytesUnsafe(), keyLength) != 0) {
break;
}
++result;
value = cursor.getNext() ? cursor.getValue() : null;
}
}
return result;
}
use of jetbrains.exodus.tree.ITreeCursor in project xodus by JetBrains.
the class BTreeReclaimSpecialTest method testStartAddress.
@Test
public void testStartAddress() {
final long fileSize = log.getFileLengthBound();
log.beginWrite();
for (long l = 1; l < fileSize; ++l) {
// fill all file except for one byte with nulls
log.write(NullLoggable.create());
}
log.flush();
log.endWrite();
Assert.assertEquals(1, log.getNumberOfFiles());
Assert.assertTrue(log.getHighAddress() < fileSize);
tm = new BTreeEmpty(log, true, 1).getMutableCopy();
final ArrayByteIterable key = key("K");
for (int i = 0; i <= COUNT; i++) {
tm.put(key, v(i));
}
long saved = saveTree();
reloadMutableTree(saved);
Assert.assertEquals(4, log.getNumberOfFiles());
final long address = 0L;
log.forgetFile(address);
// emulate gc of first file
log.removeFile(address);
Iterator<RandomAccessLoggable> loggables = log.getLoggableIterator(log.getFileAddress(fileSize * 2));
// reclaim third file
tm.reclaim(loggables.next(), loggables);
saved = saveTree();
reloadMutableTree(saved);
log.forgetFile(fileSize * 2);
// remove reclaimed file
log.removeFile(fileSize * 2);
loggables = log.getLoggableIterator(log.getFileAddress(fileSize));
// reclaim second file
tm.reclaim(loggables.next(), loggables);
saved = saveTree();
reloadMutableTree(saved);
// make sure that some files were added
Assert.assertTrue(log.getNumberOfFiles() > 2);
log.forgetFile(fileSize);
// remove reclaimed file
log.removeFile(fileSize);
try (ITreeCursor cursor = tm.openCursor()) {
// access minimum key
Assert.assertTrue(cursor.getNext());
}
}
use of jetbrains.exodus.tree.ITreeCursor in project xodus by JetBrains.
the class BTreePutSpecificTest method testNextDupWithSearch.
@Test
public void testNextDupWithSearch() {
tm = createEmptyTreeForCursor(1).getMutableCopy();
getTreeMutable().put(kv("1", "1"));
getTreeMutable().put(kv("1", "2"));
getTreeMutable().put(kv("1", "3"));
getTreeMutable().put(kv("1", "4"));
getTreeMutable().put(kv("1", "5"));
final ITreeCursor cursor = tm.openCursor();
assertNotNull(cursor.getSearchKey(key("1")));
assertTrue(cursor.getNextDup());
assertTrue(cursor.getNextDup());
assertTrue(cursor.getNextDup());
assertTrue(cursor.getNextDup());
}
use of jetbrains.exodus.tree.ITreeCursor in project xodus by JetBrains.
the class PatriciaCursorDecorator method getSearchBoth.
@Override
public boolean getSearchBoth(@NotNull ByteIterable key, @NotNull ByteIterable value) {
final ITreeCursor cursor = patriciaCursor.getTree().openCursor();
ITreeCursor cursorToClose = cursor;
try {
ByteIterable keyLengthIterable = cursor.getSearchKey(getEscapedKeyValue(key, value));
if (keyLengthIterable == null) {
return false;
}
final int keyLength = CompressedUnsignedLongByteIterable.getInt(keyLengthIterable);
if (keyLength == key.getLength()) {
keyBytes = new UnEscapingByteIterable(cursor.getKey()).getBytesUnsafe();
this.keyLength = keyLength;
valueLength = value.getLength();
cursorToClose = patriciaCursor;
patriciaCursor = cursor;
// forget computed next pair
nextKeyLength = UNKNOWN;
// forget computed prev pair
prevKeyLength = UNKNOWN;
return true;
}
return false;
} finally {
cursorToClose.close();
}
}
Aggregations