diff --git a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java index d88d7dc0d7..c25c6f12b2 100644 --- a/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java +++ b/core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java @@ -899,37 +899,41 @@ public long getId(Value value, boolean create) throws IOException { public void gcIds(Collection ids, Collection 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 finalIds = ids; - final Collection 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 finalIds = ids; + final Collection 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; }); }