wrap rocksdb segmenthandles in atomicreference to ensure we do not reference closed handles (#3734)

Signed-off-by: garyschulte <garyschulte@gmail.com>
This commit is contained in:
garyschulte
2022-04-22 17:42:59 +02:00
committed by GitHub
parent 1693db9849
commit 23f5e2e933
4 changed files with 68 additions and 58 deletions

View File

@@ -20,6 +20,7 @@ import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import java.io.Closeable;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.stream.Stream;
@@ -30,7 +31,7 @@ import java.util.stream.Stream;
*/
public interface SegmentedKeyValueStorage<S> extends Closeable {
S getSegmentIdentifierByName(SegmentIdentifier segment);
AtomicReference<S> getSegmentIdentifierByName(SegmentIdentifier segment);
/**
* Get the value from the associated segment and key.
@@ -74,7 +75,7 @@ public interface SegmentedKeyValueStorage<S> extends Closeable {
Set<byte[]> getAllKeysThat(S segmentHandle, Predicate<byte[]> returnCondition);
S clear(S segmentHandle);
void clear(S segmentHandle);
/**
* Represents a set of changes to be committed atomically. A single transaction is not

View File

@@ -22,47 +22,48 @@ import org.hyperledger.besu.plugin.services.storage.SegmentIdentifier;
import java.io.IOException;
import java.util.Optional;
import java.util.Set;
import java.util.concurrent.atomic.AtomicReference;
import java.util.function.Predicate;
import java.util.stream.Stream;
public class SegmentedKeyValueStorageAdapter<S> implements KeyValueStorage {
private S segmentHandle;
private final AtomicReference<S> segmentHandle;
private final SegmentedKeyValueStorage<S> storage;
public SegmentedKeyValueStorageAdapter(
final SegmentIdentifier segment, final SegmentedKeyValueStorage<S> storage) {
this.segmentHandle = storage.getSegmentIdentifierByName(segment);
segmentHandle = storage.getSegmentIdentifierByName(segment);
this.storage = storage;
}
@Override
public void clear() {
segmentHandle = storage.clear(segmentHandle);
storage.clear(segmentHandle.get());
}
@Override
public boolean containsKey(final byte[] key) throws StorageException {
return storage.containsKey(segmentHandle, key);
return storage.containsKey(segmentHandle.get(), key);
}
@Override
public Optional<byte[]> get(final byte[] key) throws StorageException {
return storage.get(segmentHandle, key);
return storage.get(segmentHandle.get(), key);
}
@Override
public Set<byte[]> getAllKeysThat(final Predicate<byte[]> returnCondition) {
return storage.getAllKeysThat(segmentHandle, returnCondition);
return storage.getAllKeysThat(segmentHandle.get(), returnCondition);
}
@Override
public Stream<byte[]> streamKeys() {
return storage.streamKeys(segmentHandle);
return storage.streamKeys(segmentHandle.get());
}
@Override
public boolean tryDelete(final byte[] key) {
return storage.tryDelete(segmentHandle, key);
return storage.tryDelete(segmentHandle.get(), key);
}
@Override
@@ -77,12 +78,12 @@ public class SegmentedKeyValueStorageAdapter<S> implements KeyValueStorage {
@Override
public void put(final byte[] key, final byte[] value) {
transaction.put(segmentHandle, key, value);
transaction.put(segmentHandle.get(), key, value);
}
@Override
public void remove(final byte[] key) {
transaction.remove(segmentHandle, key);
transaction.remove(segmentHandle.get(), key);
}
@Override