고유 한 순서 지정을 제공하는 사용자 지정 ComparableBinding/ByteIterable 조합을 구현할 수 있습니까? 그리고 어떻게 이것을 시스템에 등록 할 수 있습니까? 또한, 키에만 사용될 때 ByteIterable.subIterable (final int offset, final int length) 메서드를 구현하지 않는 것이 안전할까요? 내 유스 케이스에는 유효한 서브 테이블이 없으므로 순서가 깨질 수 있습니다.사용자 지정 ComparableBinding 구현
아래 TestStore.test() 메소드는 커서를 오름차순으로 이동시키기에 충분하지 않으므로 하단의 assert 문이 실패합니다. 하지만 키를 생성하는 빌드 - IntegerBinding.intToEntry (인덱스)를 사용 때 작동합니다
import jetbrains.exodus.ArrayByteIterable;
import jetbrains.exodus.ByteIterable;
import jetbrains.exodus.ByteIterator;
import org.jetbrains.annotations.NotNull;
import java.nio.charset.Charset;
public class TestKey implements ByteIterable {
private final int value;
private final byte[] bytes;
public TestKey(int value) {
this.value = value;
this.bytes = Integer.toString(value).getBytes(Charset.forName("utf-8"));
}
@Override
public int compareTo(@NotNull ByteIterable o) {
return Integer.compare(value, ((TestKey)o).value);
}
@Override
public ByteIterator iterator() {
return new ArrayByteIterable(bytes).iterator();
}
@Override
public byte[] getBytesUnsafe() {
return bytes;
}
@Override
public int getLength() {
return bytes.length;
}
@Override
public @NotNull ByteIterable subIterable(int offset, int length) {
throw new UnsupportedOperationException("subIterable");
}
}
import jetbrains.exodus.ByteIterable;
import jetbrains.exodus.bindings.IntegerBinding;
import jetbrains.exodus.bindings.StringBinding;
import jetbrains.exodus.env.Cursor;
import jetbrains.exodus.env.Environment;
import jetbrains.exodus.env.Environments;
import jetbrains.exodus.env.Store;
import jetbrains.exodus.env.StoreConfig;
import jetbrains.exodus.env.Transaction;
import jetbrains.exodus.env.TransactionalExecutable;
import org.jetbrains.annotations.NotNull;
import java.io.File;
import java.util.Arrays;
import java.util.UUID;
public class TestStore {
private Store store;
private Environment environment;
public TestStore(File folder) {
environment = Environments.newContextualInstance(folder);
environment.executeInTransaction(new TransactionalExecutable() {
@Override
public void execute(@NotNull Transaction txn) {
store = environment.openStore(
UUID.randomUUID().toString(),
StoreConfig.WITHOUT_DUPLICATES,
txn,
true);
}
});
}
public void test() {
int count = 1000;
int[] orig = new int[count];
int[] iterated = new int[count];
for(int i = 0; i < count; i++) {
final int index = i;
environment.executeInTransaction(new TransactionalExecutable() {
@Override
public void execute(@NotNull Transaction txn) {
orig[index] = index;
store.put(txn,
new TestKey(index),
// IntegerBinding.intToEntry(index),
StringBinding.stringToEntry(Integer.toString(index))
);
}
});
}
environment.executeInTransaction(new TransactionalExecutable() {
@Override
public void execute(@NotNull Transaction txn) {
int offset = 0;
try(Cursor cursor = store.openCursor(txn)) {
while(cursor.getNext()) {
ByteIterable key = cursor.getKey();
ByteIterable value = cursor.getValue();
iterated[offset++] = Integer.parseInt(StringBinding.entryToString(value));
}
}
}
});
assert Arrays.equals(orig, iterated);
}
}
|이 바인딩을 사용하려고 (환경 EntityStores)? –
환경 전용. – wolpers