@Nullable @Override public Tuple subspaceTag(@Nonnull Subspace subspace) { return indexSubspace.unpack(subspace.getKey()); } }
@Nonnull @Override public Subspace subspaceOf(@Nonnull byte[] keyBytes) { Tuple t = indexSubspace.unpack(keyBytes); return indexSubspace.subspace(TupleHelpers.subTuple(t, 0, groupingColumns)); }
@Override public ResolverResult deserializeValue(byte[] value) { return new ResolverResult(contentSubspace.unpack(value).getLong(0)); }
private CompletableFuture<AllocationWindow> initialWindow() { return currentCounter().thenApply(counter -> counter.map(kv -> AllocationWindow.startingFrom(counterSubspace.unpack(kv.getKey()).getLong(0))) .orElse(AllocationWindow.startingFrom(0)) ); }
protected String toDebugString(ReadTransactionContext tc) { return tc.read(tr -> { StringBuilder str = new StringBuilder(); for (int level = 0; level < nlevels; ++level) { if (level > 0) { str.setLength(str.length() - 2); str.append("\n"); } str.append("L").append(level).append(": "); for (KeyValue kv : tr.getRange(subspace.range(Tuple.from(level)))) { byte[] key = subspace.unpack(kv.getKey()).getBytes(1); long count = decodeLong(kv.getValue()); str.append("'").append(ByteArrayUtil2.loggable(key)).append("': ").append(count).append(", "); } } return str.toString(); }); }
@Nonnull public CompletableFuture<String> rep(@Nonnull ReadTransactionContext tc) { return tc.readAsync(tr -> { StringBuilder sb = new StringBuilder(); AsyncIterable<KeyValue> iterable = tr.getRange(subspace.range()); return iterable.asList().thenApply((List<KeyValue> list) -> { for (KeyValue kv : list) { byte[] key = subspace.unpack(kv.getKey()).getBytes(0); byte[] value = kv.getValue(); sb.append(ByteArrayUtil.printable(key)); sb.append(" -> "); sb.append(ByteArrayUtil.printable(value)); sb.append('\n'); } return sb.toString(); }); }); }
@Nonnull @Override public Subspace subspaceOf(@Nonnull byte[] keyBytes) { Tuple t = mapSubspace.unpack(keyBytes); return mapSubspace.subspace(TupleHelpers.subTuple(t, 0, 1)); }
@Nullable @Override public Long subspaceTag(@Nonnull Subspace subspace) { return bmSubspace.unpack(subspace.getKey()).getLong(0); } };
@Nonnull @Override public String subspaceTag(@Nonnull Subspace subspace) { return mapSubspace.unpack(subspace.getKey()).getString(0); } };
public static Tuple unpackKey(@Nonnull Subspace subspace, @Nonnull KeyValue kv) { try { return subspace.unpack(kv.getKey()); } catch (IllegalArgumentException e) { throw new RecordCoreArgumentException("unable to unpack key", e) .addLogInfo(LogMessageKeys.KEY, ByteArrayUtil2.loggable(kv.getKey())) .addLogInfo(LogMessageKeys.SUBSPACE, ByteArrayUtil2.loggable(subspace.getKey())); } }
private Long extractKey(Subspace allocationSubspace, KeyValue kv) { return allocationSubspace.unpack(kv.getKey()).getLong(0); }
@Nonnull @Override public Subspace subspaceOf(@Nonnull byte[] keyBytes) { try { Tuple t = bmSubspace.unpack(keyBytes); return bmSubspace.subspace(TupleHelpers.subTuple(t, 0, 1)); } catch (IllegalArgumentException e) { System.out.println("key: " + ByteArrayUtil2.loggable(keyBytes)); System.out.println("subspace: " + ByteArrayUtil2.loggable(bmSubspace.getKey())); throw e; } }
@Override public ResolverResult deserializeValue(byte[] value) { Tuple unpacked = contentSubspace.unpack(value); return unpacked.size() == 1 ? new ResolverResult(unpacked.getLong(0), null) : new ResolverResult(unpacked.getLong(0), unpacked.getBytes(1)); }
@Nonnull private List<Pair<Tuple, Integer>> scanTokenizerVersions(@Nonnull FDBRecordStore store, @Nonnull Index index) throws ExecutionException, InterruptedException { final Subspace tokenizerVersionSubspace = store.indexSecondarySubspace(index).subspace(TextIndexMaintainer.TOKENIZER_VERSION_SUBSPACE_TUPLE); return recordStore.ensureContextActive().getRange(tokenizerVersionSubspace.range()).asList().get().stream() .map(kv -> Pair.of(tokenizerVersionSubspace.unpack(kv.getKey()), (int)Tuple.fromBytes(kv.getValue()).getLong(0))) .collect(Collectors.toList()); }
private void verifyBoundaryKeys(@Nonnull List<Tuple> boundaryKeys) throws ExecutionException, InterruptedException { try (Transaction tr = db.createTransaction()) { map.verifyIntegrity(tr, bmSubspace).get(); List<KeyValue> rangeKVs = tr.getRange(bmSubspace.range()).asList().get(); List<Tuple> actualBoundaryKeys = rangeKVs.stream() .map(KeyValue::getKey) .map(bmSubspace::unpack) .collect(Collectors.toList()); List<Map.Entry<Tuple,Tuple>> entryList = rangeKVs.stream() .flatMap(kv -> serializer.deserializeEntries(bmSubspace.unpack(kv.getKey()), kv.getValue()).stream()) .collect(Collectors.toList()); System.out.println(entryList); assertEquals(boundaryKeys, actualBoundaryKeys); tr.cancel(); } }
private CompletableFuture<byte[]> getPreviousKey(TransactionContext tc, int level, byte[] key) { byte[] k = subspace.pack(Tuple.from(level, key)); CompletableFuture<byte[]> kf = tc.run(tr -> tr.snapshot() .getRange(KeySelector.lastLessThan(k), KeySelector.firstGreaterOrEqual(k), 1) .asList() .thenApply(kvs -> { byte[] prevk = kvs.get(0).getKey(); // If another key were inserted after between this and the target key, // it wouldn't be the one we should increment any more. // But do not conflict when key itself is incremented. byte[] exclusiveBegin = ByteArrayUtil.join(prevk, ZERO_ARRAY); tr.addReadConflictRange(exclusiveBegin, k); // Do conflict if key is removed entirely. tr.addReadConflictKey(subspace.pack(Tuple.from(0, subspace.unpack(prevk).getBytes(1)))); return prevk; })); return kf.thenApply(prevk -> subspace.unpack(prevk).getBytes(1)); }
private CompletableFuture<byte[]> computeInternal(@Nonnull FDBRecordContext context, @Nullable byte[] continuation, @Nonnull MessageDigest messageDigest) { final RecordCursor<KeyValue> cursor = KeyValueCursor.Builder.withSubspace(mappingSubspace) .setScanProperties(new ScanProperties(ExecuteProperties.newBuilder().setReturnedRowLimit(transactionRowLimit).setIsolationLevel(IsolationLevel.SNAPSHOT).build())) .setContext(context) .setContinuation(continuation) .build(); return AsyncUtil.whileTrue(() -> cursor.onHasNext().thenApply(hasNext -> { if (hasNext) { KeyValue kv = cursor.next(); String key = mappingSubspace.unpack(kv.getKey()).getString(0); ResolverResult value = resolver.deserializeValue(kv.getValue()); messageDigest.update(Tuple.from(key, value.getValue(), value.getMetadata()).pack()); } return hasNext; }), context.getExecutor() ).thenApply(ignore -> cursor.getContinuation()); } }
public AsyncIterable<byte[]> getRange(ReadTransaction tr, byte[] beginKey, byte[] endKey) { checkKey(beginKey); return AsyncUtil.mapIterable(tr.getRange(subspace.pack(Tuple.from(0, beginKey)), subspace.pack(Tuple.from(0, endKey))), keyValue -> { Tuple t = subspace.unpack(keyValue.getKey()); return t.getBytes(1); }); }
@Nonnull private void addConvertRecordVersions(@Nonnull List<CompletableFuture<Void>> work) { if (useOldVersionFormat()) { throw new RecordCoreException("attempted to convert record versions when still using older format"); } final Subspace legacyVersionSubspace = getSubspace().subspace(Tuple.from(RECORD_VERSION_KEY)); // Read all of the keys in the old record version location. For each // record, copy its version to the new location within the primary record // subspace. Then once they are all copied, delete the old subspace. KeyValueCursor kvCursor = KeyValueCursor.Builder.withSubspace(legacyVersionSubspace) .setContext(getRecordContext()) .setScanProperties(ScanProperties.FORWARD_SCAN) .build(); CompletableFuture<Void> workFuture = kvCursor.forEach(kv -> { final Tuple primaryKey = legacyVersionSubspace.unpack(kv.getKey()); final FDBRecordVersion version = FDBRecordVersion.fromBytes(kv.getValue(), false); final byte[] newKeyBytes = getSubspace().pack(recordVersionKey(primaryKey)); final byte[] newValueBytes = SplitHelper.packVersion(version); ensureContextActive().set(newKeyBytes, newValueBytes); }).thenAccept(ignore -> ensureContextActive().clear(legacyVersionSubspace.range())); work.add(workFuture); }
private void checkIncreasing() { List<KeyValue> kvs = db.readAsync(tr -> tr.getRange(rsSubspace.range()).asList()).join(); byte[] last = null; for (KeyValue kv : kvs) { byte[] key = rsSubspace.unpack(kv.getKey()).getBytes(0); assertTrue(compareUnsigned(key, kv.getValue()) < 0, "Key " + printable(key) + " is not less than value " + printable(kv.getValue())); if (last != null) { assertTrue(compareUnsigned(last, key) <= 0, "Last value " + printable(last) + " is after key " + printable(key)); } last = kv.getValue(); } }