Safer access to database elements
This commit is contained in:
parent
88a1add102
commit
e03afafcee
@ -332,17 +332,11 @@ public sealed abstract class AbstractRocksDBColumn<T extends RocksDB> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void ensureOpen() {
|
protected void ensureOpen() {
|
||||||
if (Schedulers.isInNonBlockingThread()) {
|
RocksDBUtils.ensureOpen(db, cfh);
|
||||||
throw new UnsupportedOperationException("Called in a nonblocking thread");
|
|
||||||
}
|
|
||||||
ensureOwned(db);
|
|
||||||
ensureOwned(cfh);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void ensureOwned(org.rocksdb.RocksObject rocksObject) {
|
protected void ensureOwned(org.rocksdb.RocksObject rocksObject) {
|
||||||
if (!rocksObject.isOwningHandle()) {
|
RocksDBUtils.ensureOwned(rocksObject);
|
||||||
throw new IllegalStateException("Not owning handle");
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -939,7 +933,13 @@ public sealed abstract class AbstractRocksDBColumn<T extends RocksDB> implements
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected int getLevels() {
|
protected int getLevels() {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
return RocksDBUtils.getLevels(db, cfh);
|
return RocksDBUtils.getLevels(db, cfh);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
@ -516,6 +516,17 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
|| Boolean.parseBoolean(System.getProperty("it.cavallium.dbengine.disableslowdown", "false"));
|
|| Boolean.parseBoolean(System.getProperty("it.cavallium.dbengine.disableslowdown", "false"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void ensureOpen() {
|
||||||
|
if (closed) {
|
||||||
|
throw new IllegalStateException("Database closed");
|
||||||
|
}
|
||||||
|
RocksDBUtils.ensureOpen(db, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void ensureOwned(org.rocksdb.RocksObject rocksObject) {
|
||||||
|
RocksDBUtils.ensureOwned(rocksObject);
|
||||||
|
}
|
||||||
|
|
||||||
private synchronized PersistentCache resolvePersistentCache(HashMap<String, PersistentCache> caches,
|
private synchronized PersistentCache resolvePersistentCache(HashMap<String, PersistentCache> caches,
|
||||||
DBOptions rocksdbOptions,
|
DBOptions rocksdbOptions,
|
||||||
List<it.cavallium.dbengine.rpc.current.data.PersistentCache> persistentCaches,
|
List<it.cavallium.dbengine.rpc.current.data.PersistentCache> persistentCaches,
|
||||||
@ -562,22 +573,51 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int getLevels(Column column) {
|
public int getLevels(Column column) {
|
||||||
return RocksDBUtils.getLevels(db, handles.get(column));
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
var cfh = handles.get(column);
|
||||||
|
ensureOwned(cfh);
|
||||||
|
return RocksDBUtils.getLevels(db, cfh);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public List<String> getColumnFiles(Column column, boolean excludeLastLevel) {
|
public List<String> getColumnFiles(Column column, boolean excludeLastLevel) {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
var cfh = handles.get(column);
|
var cfh = handles.get(column);
|
||||||
|
ensureOwned(cfh);
|
||||||
return RocksDBUtils.getColumnFiles(db, cfh, excludeLastLevel);
|
return RocksDBUtils.getColumnFiles(db, cfh, excludeLastLevel);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void forceCompaction(int volumeId) throws RocksDBException {
|
public void forceCompaction(int volumeId) throws RocksDBException {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
for (var cfh : this.handles.values()) {
|
for (var cfh : this.handles.values()) {
|
||||||
|
ensureOwned(cfh);
|
||||||
RocksDBUtils.forceCompaction(db, name, cfh, volumeId, logger);
|
RocksDBUtils.forceCompaction(db, name, cfh, volumeId, logger);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void flush(FlushOptions flushOptions) throws RocksDBException {
|
public void flush(FlushOptions flushOptions) throws RocksDBException {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
ensureOwned(flushOptions);
|
||||||
db.flush(flushOptions);
|
db.flush(flushOptions);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private record RocksLevelOptions(CompressionType compressionType, CompressionOptions compressionOptions) {}
|
private record RocksLevelOptions(CompressionType compressionType, CompressionOptions compressionOptions) {}
|
||||||
@ -601,7 +641,11 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
if (closed) {
|
if (closed) {
|
||||||
return 0d;
|
return 0d;
|
||||||
}
|
}
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
try {
|
try {
|
||||||
|
if (closed) {
|
||||||
|
return 0d;
|
||||||
|
}
|
||||||
return database.getAggregatedLongProperty(propertyName)
|
return database.getAggregatedLongProperty(propertyName)
|
||||||
/ (divideByAllColumns ? getAllColumnFamilyHandles().size() : 1d);
|
/ (divideByAllColumns ? getAllColumnFamilyHandles().size() : 1d);
|
||||||
} catch (RocksDBException e) {
|
} catch (RocksDBException e) {
|
||||||
@ -609,6 +653,8 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
return 0d;
|
return 0d;
|
||||||
}
|
}
|
||||||
throw new RuntimeException(e);
|
throw new RuntimeException(e);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
@ -949,19 +995,41 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Snapshot getSnapshotLambda(LLSnapshot snapshot) {
|
||||||
|
var closeReadSnapLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
var snapshotHandle = snapshotsHandles.get(snapshot.getSequenceNumber());
|
||||||
|
ensureOwned(snapshotHandle);
|
||||||
|
return snapshotHandle;
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadSnapLock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<LLLocalSingleton> getSingleton(byte[] singletonListColumnName,
|
public Mono<LLLocalSingleton> getSingleton(byte[] singletonListColumnName,
|
||||||
byte[] name,
|
byte[] name,
|
||||||
byte @Nullable[] defaultValue) {
|
byte @Nullable[] defaultValue) {
|
||||||
return Mono
|
return Mono
|
||||||
.fromCallable(() -> new LLLocalSingleton(
|
.fromCallable(() -> {
|
||||||
getRocksDBColumn(db, getCfh(singletonListColumnName)),
|
var closeReadLock = closeLock.readLock();
|
||||||
(snapshot) -> snapshotsHandles.get(snapshot.getSequenceNumber()),
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
var cfh = getCfh(singletonListColumnName);
|
||||||
|
ensureOwned(cfh);
|
||||||
|
return new LLLocalSingleton(
|
||||||
|
getRocksDBColumn(db, cfh),
|
||||||
|
this::getSnapshotLambda,
|
||||||
LLLocalKeyValueDatabase.this.name,
|
LLLocalKeyValueDatabase.this.name,
|
||||||
name,
|
name,
|
||||||
ColumnUtils.toString(singletonListColumnName),
|
ColumnUtils.toString(singletonListColumnName),
|
||||||
dbWScheduler, dbRScheduler, defaultValue
|
dbWScheduler, dbRScheduler, defaultValue
|
||||||
))
|
);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
|
})
|
||||||
.onErrorMap(cause -> new IOException("Failed to read " + Arrays.toString(name), cause))
|
.onErrorMap(cause -> new IOException("Failed to read " + Arrays.toString(name), cause))
|
||||||
.subscribeOn(dbRScheduler);
|
.subscribeOn(dbRScheduler);
|
||||||
}
|
}
|
||||||
@ -969,28 +1037,45 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
@Override
|
@Override
|
||||||
public Mono<LLLocalDictionary> getDictionary(byte[] columnName, UpdateMode updateMode) {
|
public Mono<LLLocalDictionary> getDictionary(byte[] columnName, UpdateMode updateMode) {
|
||||||
return Mono
|
return Mono
|
||||||
.fromCallable(() -> new LLLocalDictionary(
|
.fromCallable(() -> {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
var cfh = getCfh(columnName);
|
||||||
|
ensureOwned(cfh);
|
||||||
|
return new LLLocalDictionary(
|
||||||
allocator,
|
allocator,
|
||||||
getRocksDBColumn(db, getCfh(columnName)),
|
getRocksDBColumn(db, cfh),
|
||||||
name,
|
name,
|
||||||
ColumnUtils.toString(columnName),
|
ColumnUtils.toString(columnName),
|
||||||
dbWScheduler,
|
dbWScheduler,
|
||||||
dbRScheduler,
|
dbRScheduler,
|
||||||
(snapshot) -> snapshotsHandles.get(snapshot.getSequenceNumber()),
|
this::getSnapshotLambda,
|
||||||
updateMode,
|
updateMode,
|
||||||
databaseOptions
|
databaseOptions
|
||||||
))
|
);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
|
})
|
||||||
.subscribeOn(dbRScheduler);
|
.subscribeOn(dbRScheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public RocksDBColumn getRocksDBColumn(byte[] columnName) {
|
public RocksDBColumn getRocksDBColumn(byte[] columnName) {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
ColumnFamilyHandle cfh;
|
ColumnFamilyHandle cfh;
|
||||||
try {
|
try {
|
||||||
cfh = getCfh(columnName);
|
cfh = getCfh(columnName);
|
||||||
|
ensureOwned(cfh);
|
||||||
} catch (RocksDBException e) {
|
} catch (RocksDBException e) {
|
||||||
throw new UnsupportedOperationException("Column family doesn't exist: " + Arrays.toString(columnName), e);
|
throw new UnsupportedOperationException("Column family doesn't exist: " + Arrays.toString(columnName), e);
|
||||||
}
|
}
|
||||||
return getRocksDBColumn(db, cfh);
|
return getRocksDBColumn(db, cfh);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private RocksDBColumn getRocksDBColumn(RocksDB db, ColumnFamilyHandle cfh) {
|
private RocksDBColumn getRocksDBColumn(RocksDB db, ColumnFamilyHandle cfh) {
|
||||||
@ -1031,15 +1116,29 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<Long> getProperty(String propertyName) {
|
public Mono<Long> getProperty(String propertyName) {
|
||||||
return Mono.fromCallable(() -> db.getAggregatedLongProperty(propertyName))
|
return Mono.fromCallable(() -> {
|
||||||
.onErrorMap(cause -> new IOException("Failed to read " + propertyName, cause))
|
var closeReadLock = closeLock.readLock();
|
||||||
.subscribeOn(dbRScheduler);
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
return db.getAggregatedLongProperty(propertyName);
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
|
}).onErrorMap(cause -> new IOException("Failed to read " + propertyName, cause)).subscribeOn(dbRScheduler);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Flux<Path> getSSTS() {
|
public Flux<Path> getSSTS() {
|
||||||
var paths = convertPaths(dbPath.toAbsolutePath().getParent(), dbPath.getFileName(), databaseOptions.volumes());
|
var paths = convertPaths(dbPath.toAbsolutePath().getParent(), dbPath.getFileName(), databaseOptions.volumes());
|
||||||
return Mono
|
return Mono
|
||||||
.fromCallable(() -> db.getLiveFiles())
|
.fromCallable(() -> {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
|
return db.getLiveFiles();
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
|
})
|
||||||
.flatMapIterable(liveFiles -> liveFiles.files)
|
.flatMapIterable(liveFiles -> liveFiles.files)
|
||||||
.filter(file -> file.endsWith(".sst"))
|
.filter(file -> file.endsWith(".sst"))
|
||||||
.map(file -> file.substring(1))
|
.map(file -> file.substring(1))
|
||||||
@ -1064,6 +1163,7 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
return sstsFlux
|
return sstsFlux
|
||||||
.map(path -> path.toAbsolutePath().toString())
|
.map(path -> path.toAbsolutePath().toString())
|
||||||
.flatMap(sst -> Mono.fromCallable(() -> {
|
.flatMap(sst -> Mono.fromCallable(() -> {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
try (var opts = new IngestExternalFileOptions()) {
|
try (var opts = new IngestExternalFileOptions()) {
|
||||||
try {
|
try {
|
||||||
logger.info("Ingesting SST \"{}\"...", sst);
|
logger.info("Ingesting SST \"{}\"...", sst);
|
||||||
@ -1072,6 +1172,8 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
} catch (RocksDBException e) {
|
} catch (RocksDBException e) {
|
||||||
logger.error("Can't ingest SST \"{}\"", sst, e);
|
logger.error("Can't ingest SST \"{}\"", sst, e);
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
}).subscribeOn(Schedulers.boundedElastic()))
|
}).subscribeOn(Schedulers.boundedElastic()))
|
||||||
@ -1082,7 +1184,11 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
public Mono<MemoryStats> getMemoryStats() {
|
public Mono<MemoryStats> getMemoryStats() {
|
||||||
return Mono
|
return Mono
|
||||||
.fromCallable(() -> {
|
.fromCallable(() -> {
|
||||||
|
if (closed) return null;
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
|
ensureOpen();
|
||||||
return new MemoryStats(db.getAggregatedLongProperty("rocksdb.estimate-table-readers-mem"),
|
return new MemoryStats(db.getAggregatedLongProperty("rocksdb.estimate-table-readers-mem"),
|
||||||
db.getAggregatedLongProperty("rocksdb.size-all-mem-tables"),
|
db.getAggregatedLongProperty("rocksdb.size-all-mem-tables"),
|
||||||
db.getAggregatedLongProperty("rocksdb.cur-size-all-mem-tables"),
|
db.getAggregatedLongProperty("rocksdb.cur-size-all-mem-tables"),
|
||||||
@ -1093,6 +1199,9 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.onErrorMap(cause -> new IOException("Failed to read memory stats", cause))
|
.onErrorMap(cause -> new IOException("Failed to read memory stats", cause))
|
||||||
.subscribeOn(dbRScheduler);
|
.subscribeOn(dbRScheduler);
|
||||||
@ -1102,7 +1211,11 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
public Mono<String> getRocksDBStats() {
|
public Mono<String> getRocksDBStats() {
|
||||||
return Mono
|
return Mono
|
||||||
.fromCallable(() -> {
|
.fromCallable(() -> {
|
||||||
|
if (closed) return null;
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
if (!closed) {
|
if (!closed) {
|
||||||
|
ensureOpen();
|
||||||
StringBuilder aggregatedStats = new StringBuilder();
|
StringBuilder aggregatedStats = new StringBuilder();
|
||||||
for (var entry : this.handles.entrySet()) {
|
for (var entry : this.handles.entrySet()) {
|
||||||
aggregatedStats
|
aggregatedStats
|
||||||
@ -1115,6 +1228,9 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
} else {
|
} else {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.onErrorMap(cause -> new IOException("Failed to read stats", cause))
|
.onErrorMap(cause -> new IOException("Failed to read stats", cause))
|
||||||
.subscribeOn(dbRScheduler);
|
.subscribeOn(dbRScheduler);
|
||||||
@ -1126,10 +1242,14 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
.fromIterable(handles.entrySet())
|
.fromIterable(handles.entrySet())
|
||||||
.flatMapSequential(handle -> Mono
|
.flatMapSequential(handle -> Mono
|
||||||
.fromCallable(() -> {
|
.fromCallable(() -> {
|
||||||
if (!closed) {
|
if (closed) return null;
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
if (closed) return null;
|
||||||
|
ensureOpen();
|
||||||
return db.getPropertiesOfAllTables(handle.getValue());
|
return db.getPropertiesOfAllTables(handle.getValue());
|
||||||
} else {
|
} finally {
|
||||||
return null;
|
closeLock.unlockRead(closeReadLock);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.subscribeOn(dbRScheduler)
|
.subscribeOn(dbRScheduler)
|
||||||
@ -1143,7 +1263,13 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
public Mono<Void> verifyChecksum() {
|
public Mono<Void> verifyChecksum() {
|
||||||
return Mono
|
return Mono
|
||||||
.<Void>fromCallable(() -> {
|
.<Void>fromCallable(() -> {
|
||||||
|
var closeReadLock = closeLock.readLock();
|
||||||
|
try {
|
||||||
|
ensureOpen();
|
||||||
db.verifyChecksum();
|
db.verifyChecksum();
|
||||||
|
} finally {
|
||||||
|
closeLock.unlockRead(closeReadLock);
|
||||||
|
}
|
||||||
return null;
|
return null;
|
||||||
})
|
})
|
||||||
.onErrorMap(cause -> new IOException("Failed to verify checksum of database \""
|
.onErrorMap(cause -> new IOException("Failed to verify checksum of database \""
|
||||||
@ -1181,22 +1307,20 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Mono<LLSnapshot> takeSnapshot() {
|
public Mono<LLSnapshot> takeSnapshot() {
|
||||||
return Mono
|
return Mono.fromCallable(() -> {
|
||||||
.fromCallable(() -> snapshotTime.recordCallable(() -> {
|
|
||||||
var closeReadLock = closeLock.readLock();
|
var closeReadLock = closeLock.readLock();
|
||||||
try {
|
try {
|
||||||
if (closed) {
|
ensureOpen();
|
||||||
throw new IllegalStateException("Database closed");
|
return snapshotTime.recordCallable(() -> {
|
||||||
}
|
|
||||||
var snapshot = db.getSnapshot();
|
var snapshot = db.getSnapshot();
|
||||||
long currentSnapshotSequenceNumber = nextSnapshotNumbers.getAndIncrement();
|
long currentSnapshotSequenceNumber = nextSnapshotNumbers.getAndIncrement();
|
||||||
this.snapshotsHandles.put(currentSnapshotSequenceNumber, snapshot);
|
this.snapshotsHandles.put(currentSnapshotSequenceNumber, snapshot);
|
||||||
return new LLSnapshot(currentSnapshotSequenceNumber);
|
return new LLSnapshot(currentSnapshotSequenceNumber);
|
||||||
|
});
|
||||||
} finally {
|
} finally {
|
||||||
closeLock.unlockRead(closeReadLock);
|
closeLock.unlockRead(closeReadLock);
|
||||||
}
|
}
|
||||||
}))
|
}).subscribeOn(dbRScheduler);
|
||||||
.subscribeOn(dbRScheduler);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -1205,9 +1329,6 @@ public class LLLocalKeyValueDatabase implements LLKeyValueDatabase {
|
|||||||
.<Void>fromCallable(() -> {
|
.<Void>fromCallable(() -> {
|
||||||
var closeReadLock = closeLock.readLock();
|
var closeReadLock = closeLock.readLock();
|
||||||
try {
|
try {
|
||||||
if (closed) {
|
|
||||||
throw new IllegalStateException("Database closed");
|
|
||||||
}
|
|
||||||
Snapshot dbSnapshot = this.snapshotsHandles.remove(snapshot.getSequenceNumber());
|
Snapshot dbSnapshot = this.snapshotsHandles.remove(snapshot.getSequenceNumber());
|
||||||
if (dbSnapshot == null) {
|
if (dbSnapshot == null) {
|
||||||
throw new IOException("Snapshot " + snapshot.getSequenceNumber() + " not found!");
|
throw new IOException("Snapshot " + snapshot.getSequenceNumber() + " not found!");
|
||||||
|
@ -7,6 +7,7 @@ import java.nio.charset.StandardCharsets;
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.apache.logging.log4j.Logger;
|
import org.apache.logging.log4j.Logger;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
import org.rocksdb.ColumnFamilyHandle;
|
import org.rocksdb.ColumnFamilyHandle;
|
||||||
import org.rocksdb.CompactionJobInfo;
|
import org.rocksdb.CompactionJobInfo;
|
||||||
import org.rocksdb.CompactionOptions;
|
import org.rocksdb.CompactionOptions;
|
||||||
@ -94,4 +95,18 @@ public class RocksDBUtils {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void ensureOpen(RocksDB db, @Nullable ColumnFamilyHandle cfh) {
|
||||||
|
if (Schedulers.isInNonBlockingThread()) {
|
||||||
|
throw new UnsupportedOperationException("Called in a nonblocking thread");
|
||||||
|
}
|
||||||
|
ensureOwned(db);
|
||||||
|
ensureOwned(cfh);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void ensureOwned(@Nullable org.rocksdb.RocksObject rocksObject) {
|
||||||
|
if (rocksObject != null && !rocksObject.isOwningHandle()) {
|
||||||
|
throw new IllegalStateException("Not owning handle");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user