@Nullable @Override public Tuple subspaceTag(@Nonnull Subspace subspace) { return indexSubspace.unpack(subspace.getKey()); } }
@Override @Nonnull public Subspace getMappingSubspace() { return nodeSubspace.get(nodeSubspace.getKey()).get(0); }
@Override @Nonnull public Subspace getMappingSubspace() { return nodeSubspace.get(nodeSubspace.getKey()).get(0); }
private Subspace getCounterSubspace() { return nodeSubspace.get(nodeSubspace.getKey()).get("hca".getBytes(Charset.forName("UTF-8"))).get(0); }
private Subspace getAllocationSubspace() { return nodeSubspace.get(nodeSubspace.getKey()).get("hca".getBytes(Charset.forName("UTF-8"))).get(1); }
private ExtendedDirectoryLayer(@Nonnull FDBDatabase database, @Nullable KeySpacePath path, @Nonnull Supplier<Tuple> pathTuple) { super(database, path); if (path == null) { this.isRootLevel = true; this.baseSubspace = DEFAULT_BASE_SUBSPACE; this.nodeSubspace = DEFAULT_NODE_SUBSPACE; this.contentSubspace = DEFAULT_CONTENT_SUBSPACE; this.infoString = "ExtendedDirectoryLayer:GLOBAL"; } else { this.isRootLevel = false; this.baseSubspace = new Subspace(pathTuple.get()); this.nodeSubspace = new Subspace(Bytes.concat(baseSubspace.getKey(), DirectoryLayer.DEFAULT_NODE_SUBSPACE.getKey())); this.contentSubspace = new Subspace(RESERVED_CONTENT_SUBSPACE_PREFIX); this.infoString = "ExtendedDirectoryLayer:" + path.toString(); } this.stateSubspace = nodeSubspace.get(STATE_SUBSPACE_KEY_SUFFIX); this.hashCode = Objects.hash(ExtendedDirectoryLayer.class, baseSubspace, database); }
private CompletableFuture<Void> updateResolverState(@Nonnull final FDBRecordContext context, @Nonnull final StateMutation mutation) { byte[] stateKey = getStateSubspace().getKey(); return context.ensureActive().get(stateKey) .thenApply(LocatableResolver::deserializeResolverState) .thenApply(state -> mutation.apply(state).toByteArray()) .thenApply(bytes -> { context.ensureActive().set(stateKey, bytes); return null; }); }
private ScopedDirectoryLayer(@Nonnull FDBDatabase database, @Nullable KeySpacePath path, @Nonnull Supplier<Tuple> pathTuple) { super(database, path); if (path == null) { this.baseSubspace = new Subspace(); this.contentSubspace = new Subspace(); this.infoString = "ScopedDirectoryLayer:GLOBAL"; } else { this.baseSubspace = new Subspace(pathTuple.get()); this.contentSubspace = new Subspace(RESERVED_CONTENT_SUBSPACE_PREFIX); this.infoString = "ScopedDirectoryLayer:" + path.toString(); } this.nodeSubspace = new Subspace(Bytes.concat(baseSubspace.getKey(), DirectoryLayer.DEFAULT_NODE_SUBSPACE.getKey())); this.directoryLayer = new DirectoryLayer(nodeSubspace, contentSubspace); this.stateSubspace = nodeSubspace.get(STATE_SUBSPACE_KEY_SUFFIX); this.hashCode = Objects.hash(ScopedDirectoryLayer.class, baseSubspace, database); }
@Nonnull private Pair<Integer, Integer> estimateSize(@Nullable Tuple groupingKey, @Nonnull Map<String, List<Integer>> positionMap, @Nonnull Tuple groupedKey, boolean remove) { final int idSize = groupedKey.pack().length; final int subspaceSize = getIndexSubspace().getKey().length + (groupingKey != null ? groupingKey.pack().length : 0); int keySize = 0; int valueSize = 0; for (Map.Entry<String, List<Integer>> posting : positionMap.entrySet()) { keySize += subspaceSize + 2 + posting.getKey().length() + idSize; if (omitPositionLists) { valueSize += 1; } else { int listSize = posting.getValue().stream().mapToInt(TextIndexMaintainer::varIntSize).sum(); valueSize += varIntSize(idSize) + idSize + varIntSize(listSize) + listSize; } } if (state.store.getTimer() != null) { state.store.getTimer().increment(remove ? FDBStoreTimer.Counts.DELETE_INDEX_KEY : FDBStoreTimer.Counts.SAVE_INDEX_KEY, positionMap.size()); state.store.getTimer().increment(remove ? FDBStoreTimer.Counts.DELETE_INDEX_KEY_BYTES : FDBStoreTimer.Counts.SAVE_INDEX_KEY_BYTES, keySize); state.store.getTimer().increment(remove ? FDBStoreTimer.Counts.DELETE_INDEX_VALUE_BYTES : FDBStoreTimer.Counts.SAVE_INDEX_VALUE_BYTES, valueSize); } return Pair.of(keySize, valueSize); }
@Override public void deleteAllRecords() { preloadCache.invalidateAll(); Transaction tr = ensureContextActive(); tr.clear(recordsSubspace().getKey(), getSubspace().range().end); }
@Nonnull @Override public String subspaceTag(@Nonnull Subspace subspace) { return mapSubspace.unpack(subspace.getKey()).getString(0); } };
@Nullable @Override public Long subspaceTag(@Nonnull Subspace subspace) { return bmSubspace.unpack(subspace.getKey()).getLong(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())); } }
@Test public void serializeKey() { List<Tuple> sortedTuples = TEST_TUPLES.stream().sorted().collect(Collectors.toList()); List<Tuple> sortedKeys = TEST_TUPLES.stream() .map(serializer::serializeKey) .sorted(ByteArrayUtil::compareUnsigned) .map(serializer::deserializeKey) .collect(Collectors.toList()); assertEquals(sortedTuples, sortedKeys); // Add a subspace and make sure unpacking by length works. Subspace subspace = new Subspace(Tuple.from("fake", "subspace")); List<Tuple> prefixedTuples = TEST_TUPLES.stream() .map(serializer::serializeKey) .map(b -> ByteArrayUtil.join(subspace.getKey(), b)) .map(data -> serializer.deserializeKey(data, subspace.getKey().length)) .collect(Collectors.toList()); assertEquals(TEST_TUPLES, prefixedTuples); }
private void validate(FDBRecordContext context, LocatableResolver resolver, DirectoryLayer directoryLayer, String key, Long value) { List<String> directories = directoryLayer.list(context.ensureActive()).join(); assertThat("entry was added to the appropriate directory layer", directories, hasItem(key)); Subspace resultSubpsace = directoryLayer.open(context.ensureActive(), ImmutableList.of(key)).join(); Long directoryValue = resolver.deserializeValue(resultSubpsace.getKey()).getValue(); assertThat("resolver returned the value of the subspace prefix", directoryValue, is(value)); Long newValue = resolver.resolve(context.getTimer(), key).join(); assertThat("repeated calls to resolve return the same value", newValue, is(value)); }
@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; } }
private void scanOneByteMulti(int limit, boolean reverse, List<List<Tuple>> keyLists) throws InterruptedException, ExecutionException { byte[] one = Tuple.from(1L).pack(); byte[] start = new byte[]{one[0]}; byte[] end = new byte[]{(byte)(one[0] + 1)}; testScanMulti(limit, reverse, keyLists, (tr, continuation) -> map.scanMulti(tr, bmSubspace, splitter, start, end, continuation, limit, reverse)); byte[] fullStart = ByteArrayUtil.join(bmSubspace.getKey(), start); byte[] fullEnd = ByteArrayUtil.join(bmSubspace.getKey(), end); testScanMulti(limit, reverse, keyLists, (tr, continuation) -> new BunchedMapMultiIterator<>( AsyncPeekIterator.wrap(tr.getRange(fullStart, fullEnd, ReadTransaction.ROW_LIMIT_UNLIMITED, reverse).iterator()), tr, bmSubspace, bmSubspace.getKey(), splitter, BunchedTupleSerializer.instance(), Comparator.naturalOrder(), continuation, limit, reverse ) ); }
private void getKeysContinuationRescan(int limit, boolean reverse) { testScan(limit, reverse, (tr, continuation) -> { Tuple continuationKey = continuation == null ? null : Tuple.fromBytes(continuation); return new BunchedMapIterator<>( AsyncPeekIterator.wrap(tr.getRange(bmSubspace.range(), ReadTransaction.ROW_LIMIT_UNLIMITED, reverse).iterator()), tr, bmSubspace, bmSubspace.getKey(), BunchedTupleSerializer.instance(), Comparator.naturalOrder(), continuationKey, limit, reverse ); }); }
private void scanFullMulti(int limit, boolean reverse, List<List<Tuple>> keyLists) throws InterruptedException, ExecutionException { testScanMulti(limit, reverse, keyLists, (tr, continuation) -> map.scanMulti(tr, bmSubspace, splitter, continuation, limit, reverse)); testScanMulti(limit, reverse, keyLists, (tr, continuation) -> new BunchedMapMultiIterator<>( AsyncPeekIterator.wrap(tr.getRange(bmSubspace.range(), ReadTransaction.ROW_LIMIT_UNLIMITED, reverse).iterator()), tr, bmSubspace, bmSubspace.getKey(), splitter, BunchedTupleSerializer.instance(), Comparator.naturalOrder(), continuation, limit, reverse ) ); }
private void scanOneMulti(int limit, boolean reverse, List<List<Tuple>> keyLists) throws InterruptedException, ExecutionException { byte[] start = Tuple.from(1L).pack(); byte[] end = Tuple.from(2L).pack(); testScanMulti(limit, reverse, keyLists, (tr, continuation) -> map.scanMulti(tr, bmSubspace, splitter, start, end, continuation, limit, reverse)); testScanMulti(limit, reverse, keyLists, (tr, continuation) -> new BunchedMapMultiIterator<>( AsyncPeekIterator.wrap(tr.getRange(bmSubspace.pack(1L), bmSubspace.pack(2L), ReadTransaction.ROW_LIMIT_UNLIMITED, reverse).iterator()), tr, bmSubspace, bmSubspace.getKey(), splitter, BunchedTupleSerializer.instance(), Comparator.naturalOrder(), continuation, limit, reverse ) ); }