@Test public void testSetMappingDoesNotScanDirectoryKeySpace() { FDBStoreTimer timer = new FDBStoreTimer(); try (FDBRecordContext context = database.openContext()) { context.setTimer(timer); for (long i = 0; i < 10; i++) { globalScope.setMapping(context, "some-key-" + i, i).join(); } } assertThat("there are no scans of the directory layer", timer.getCount(FDBStoreTimer.DetailEvents.RD_CACHE_DIRECTORY_SCAN), is(0)); }
@Override public CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value) { return read(context, key).thenCombine(readInReverseCacheSubpspace(context.getTimer(), value.getValue()), (maybeRead, maybeReverseRead) -> { maybeRead.ifPresent(read -> { if (!read.equals(value)) { throw new RecordCoreException("mapping already exists with different value") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("valueFound", read); } }); maybeReverseRead.ifPresent(reverseRead -> { if (!reverseRead.equals(key)) { throw new RecordCoreException("reverse mapping already exists with different key") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("keyForValueFound", reverseRead); } }); if (!maybeRead.isPresent() && !maybeReverseRead.isPresent()) { return getMappingSubspaceAsync().thenCombine(getHca(context), (mappingSubspace, hca) -> { context.ensureActive().set(mappingSubspace.pack(key), serializeValue(value)); hca.forceAllocate(key, value.getValue()); return null; }).thenCompose(vignore -> context.getDatabase().getReverseDirectoryCache().putIfNotExists(context, wrap(key), value.getValue())); } return AsyncUtil.DONE; }).thenCompose(Function.identity()); }
ExtendedDirectoryLayer extends LocatableResolver { @Override public CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value) { return read(context, key).thenCombine(readInReverseCacheSubpspace(context.getTimer(), value.getValue()), (maybeRead, maybeReverseRead) -> { maybeRead.ifPresent(read -> { if (!read.equals(value)) { throw new RecordCoreException("mapping already exists with different value") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("valueFound", read); } }); maybeReverseRead.ifPresent(reverseRead -> { if (!reverseRead.equals(key)) { throw new RecordCoreException("reverse mapping already exists with different key") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("keyForValueFound", reverseRead); } }); if (!maybeRead.isPresent() && !maybeReverseRead.isPresent()) { return getMappingSubspaceAsync().thenCombine(getHca(context), (mappingSubspace, hca) -> { context.ensureActive().set(mappingSubspace.pack(key), serializeValue(value)); hca.forceAllocate(key, value.getValue()); return null; }).thenCompose(vignore -> context.getDatabase().getReverseDirectoryCache().putIfNotExists(context, wrap(key), value.getValue())); } return AsyncUtil.DONE; }).thenCompose(Function.identity()); } }
ExtendedDirectoryLayer extends LocatableResolver { @Override public CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value) { return read(context, key).thenCombine(readInReverseCacheSubpspace(context.getTimer(), value.getValue()), (maybeRead, maybeReverseRead) -> { maybeRead.ifPresent(read -> { if (!read.equals(value)) { throw new RecordCoreException("mapping already exists with different value") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("valueFound", read); } }); maybeReverseRead.ifPresent(reverseRead -> { if (!reverseRead.equals(key)) { throw new RecordCoreException("reverse mapping already exists with different key") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("keyForValueFound", reverseRead); } }); if (!maybeRead.isPresent() && !maybeReverseRead.isPresent()) { return getMappingSubspaceAsync().thenCombine(getHca(context), (mappingSubspace, hca) -> { context.ensureActive().set(mappingSubspace.pack(key), serializeValue(value)); hca.forceAllocate(key, value.getValue()); return null; }).thenCompose(vignore -> context.getDatabase().getReverseDirectoryCache().putIfNotExists(context, wrap(key), value.getValue())); } return AsyncUtil.DONE; }).thenCompose(Function.identity()); } @Deprecated @API(API.Status.DEPRECATED)  ExtendedDirectoryLayer(@Nonnull FDBRecordContext context, @Nonnull KeySpacePath path);  ExtendedDirectoryLayer(@Nonnull FDBDatabase database, @Nonnull ResolvedKeySpacePath path); private  ExtendedDirectoryLayer(@Nonnull FDBDatabase database,
                                   @Nullable KeySpacePath path,
                                   @Nullable CompletableFuture<ResolvedKeySpacePath> resolvedPathFuture); }
ExtendedDirectoryLayer extends LocatableResolver { @Override public CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value) { return read(context, key).thenCombine(readInReverseCacheSubpspace(context.getTimer(), value.getValue()), (maybeRead, maybeReverseRead) -> { maybeRead.ifPresent(read -> { if (!read.equals(value)) { throw new RecordCoreException("mapping already exists with different value") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("valueFound", read); } }); maybeReverseRead.ifPresent(reverseRead -> { if (!reverseRead.equals(key)) { throw new RecordCoreException("reverse mapping already exists with different key") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("keyForValueFound", reverseRead); } }); if (!maybeRead.isPresent() && !maybeReverseRead.isPresent()) { return getMappingSubspaceAsync().thenCombine(getHca(context), (mappingSubspace, hca) -> { context.ensureActive().set(mappingSubspace.pack(key), serializeValue(value)); hca.forceAllocate(key, value.getValue()); return null; }).thenCompose(vignore -> context.getDatabase().getReverseDirectoryCache().putIfNotExists(context, wrap(key), value.getValue())); } return AsyncUtil.DONE; }).thenCompose(Function.identity()); } @Deprecated @API(API.Status.DEPRECATED)  ExtendedDirectoryLayer(@Nonnull FDBRecordContext context, @Nonnull KeySpacePath path);  ExtendedDirectoryLayer(@Nonnull FDBDatabase database, @Nonnull ResolvedKeySpacePath path); private  ExtendedDirectoryLayer(@Nonnull FDBDatabase database,
                                   @Nullable KeySpacePath path,
                                   @Nullable CompletableFuture<ResolvedKeySpacePath> resolvedPathFuture); static ExtendedDirectoryLayer global(@Nonnull FDBDatabase database); @Override CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value); @Override CompletableFuture<Void> updateMetadata(FDBRecordContext context, String key, byte[] metadata); @Override CompletableFuture<Void> setWindow(long count); @Override @Nonnull CompletableFuture<Subspace> getMappingSubspaceAsync(); @Override @Nonnull ResolverResult deserializeValue(byte[] value); @Override @Nonnull CompletableFuture<Subspace> getBaseSubspaceAsync(); }
ExtendedDirectoryLayer extends LocatableResolver { @Override public CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value) { return read(context, key).thenCombine(readInReverseCacheSubpspace(context.getTimer(), value.getValue()), (maybeRead, maybeReverseRead) -> { maybeRead.ifPresent(read -> { if (!read.equals(value)) { throw new RecordCoreException("mapping already exists with different value") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("valueFound", read); } }); maybeReverseRead.ifPresent(reverseRead -> { if (!reverseRead.equals(key)) { throw new RecordCoreException("reverse mapping already exists with different key") .addLogInfo("keyToSet", key) .addLogInfo("valueToSet", value) .addLogInfo("keyForValueFound", reverseRead); } }); if (!maybeRead.isPresent() && !maybeReverseRead.isPresent()) { return getMappingSubspaceAsync().thenCombine(getHca(context), (mappingSubspace, hca) -> { context.ensureActive().set(mappingSubspace.pack(key), serializeValue(value)); hca.forceAllocate(key, value.getValue()); return null; }).thenCompose(vignore -> context.getDatabase().getReverseDirectoryCache().putIfNotExists(context, wrap(key), value.getValue())); } return AsyncUtil.DONE; }).thenCompose(Function.identity()); } @Deprecated @API(API.Status.DEPRECATED)  ExtendedDirectoryLayer(@Nonnull FDBRecordContext context, @Nonnull KeySpacePath path);  ExtendedDirectoryLayer(@Nonnull FDBDatabase database, @Nonnull ResolvedKeySpacePath path); private  ExtendedDirectoryLayer(@Nonnull FDBDatabase database,
                                   @Nullable KeySpacePath path,
                                   @Nullable CompletableFuture<ResolvedKeySpacePath> resolvedPathFuture); static ExtendedDirectoryLayer global(@Nonnull FDBDatabase database); @Override CompletableFuture<Void> setMapping(FDBRecordContext context, String key, ResolverResult value); @Override CompletableFuture<Void> updateMetadata(FDBRecordContext context, String key, byte[] metadata); @Override CompletableFuture<Void> setWindow(long count); @Override @Nonnull CompletableFuture<Subspace> getMappingSubspaceAsync(); @Override @Nonnull ResolverResult deserializeValue(byte[] value); @Override @Nonnull CompletableFuture<Subspace> getBaseSubspaceAsync();  }