Skip to content

Commit

Permalink
Wrap logic of gcIds into read txn to fix problem with read lock.
Browse files Browse the repository at this point in the history
  • Loading branch information
kenwenzel committed May 20, 2024
1 parent 66a3ca0 commit 6011a45
Showing 1 changed file with 34 additions and 35 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -558,10 +558,7 @@ private void resizeMap(long txn, long requiredSize) throws IOException {
if (autoGrow) {
if (LmdbUtil.requiresResize(mapSize, pageSize, txn, requiredSize)) {
// map is full, resize
boolean suspendReadTxn = txn != writeTxn;
if (suspendReadTxn) {
txnLock.readLock().unlock();
}
txnLock.readLock().unlock();
txnLock.writeLock().lock();
try {
boolean activeWriteTxn = writeTxn != 0;
Expand All @@ -582,9 +579,7 @@ private void resizeMap(long txn, long requiredSize) throws IOException {
}
} finally {
txnLock.writeLock().unlock();
if (suspendReadTxn) {
txnLock.readLock().lock();
}
txnLock.readLock().lock();
}
}
}
Expand Down Expand Up @@ -904,37 +899,41 @@ public long getId(Value value, boolean create) throws IOException {

public void gcIds(Collection<Long> ids, Collection<Long> nextIds) throws IOException {
if (!ids.isEmpty()) {
// contains IDs for data types and namespaces which are freed by garbage collecting literals and URIs
resizeMap(writeTxn, 2 * ids.size() * (1 + Long.BYTES + 2 + Long.BYTES));

final Collection<Long> finalIds = ids;
final Collection<Long> finalNextIds = nextIds;
writeTransaction((stack, writeTxn) -> {
MDBVal revIdVal = MDBVal.calloc(stack);
MDBVal idVal = MDBVal.calloc(stack);
MDBVal dataVal = MDBVal.calloc(stack);

ByteBuffer revIdBb = stack.malloc(1 + Long.BYTES + 2 + Long.BYTES);
Varint.writeUnsigned(revIdBb, revision.getRevisionId());
int revLength = revIdBb.position();
for (Long id : finalIds) {
revIdBb.position(revLength).limit(revIdBb.capacity());
revIdVal.mv_data(id2data(revIdBb, id).flip());
// check if id has internal references and therefore cannot be deleted
idVal.mv_data(revIdBb.slice().position(revLength));
if (mdb_get(writeTxn, refCountsDbi, idVal, dataVal) == 0) {
continue;
// wrap into read txn as resizeMap expects an active surrounding read txn
readTransaction(env, (stack1, txn1) -> {
// contains IDs for data types and namespaces which are freed by garbage collecting literals and URIs
resizeMap(writeTxn, 2 * ids.size() * (1 + Long.BYTES + 2 + Long.BYTES));

final Collection<Long> finalIds = ids;
final Collection<Long> finalNextIds = nextIds;
writeTransaction((stack, writeTxn) -> {
MDBVal revIdVal = MDBVal.calloc(stack);
MDBVal idVal = MDBVal.calloc(stack);
MDBVal dataVal = MDBVal.calloc(stack);

ByteBuffer revIdBb = stack.malloc(1 + Long.BYTES + 2 + Long.BYTES);
Varint.writeUnsigned(revIdBb, revision.getRevisionId());
int revLength = revIdBb.position();
for (Long id : finalIds) {
revIdBb.position(revLength).limit(revIdBb.capacity());
revIdVal.mv_data(id2data(revIdBb, id).flip());
// check if id has internal references and therefore cannot be deleted
idVal.mv_data(revIdBb.slice().position(revLength));
if (mdb_get(writeTxn, refCountsDbi, idVal, dataVal) == 0) {
continue;
}
// mark id as unused
E(mdb_put(writeTxn, unusedDbi, revIdVal, dataVal, 0));
}
// mark id as unused
E(mdb_put(writeTxn, unusedDbi, revIdVal, dataVal, 0));
}

deleteValueToIdMappings(stack, writeTxn, finalIds, finalNextIds);
deleteValueToIdMappings(stack, writeTxn, finalIds, finalNextIds);

invalidateRevisionOnCommit = true;
if (nextValueEvictionTime < 0) {
nextValueEvictionTime = System.currentTimeMillis() + VALUE_EVICTION_INTERVAL;
}
invalidateRevisionOnCommit = true;
if (nextValueEvictionTime < 0) {
nextValueEvictionTime = System.currentTimeMillis() + VALUE_EVICTION_INTERVAL;
}
return null;
});
return null;
});
}
Expand Down

0 comments on commit 6011a45

Please sign in to comment.