From 9e789aed8f7c40d040b9845229f4dc51e63c3dd6 Mon Sep 17 00:00:00 2001 From: qaate47 Date: Fri, 1 Mar 2024 12:18:54 +0100 Subject: [PATCH] GH-455 Disable delete bitmap feature --- .../qendpoint/store/EndpointStore.java | 10 ++++++++++ .../qendpoint/store/EndpointStoreConnection.java | 16 +++++++++++++++- .../store/EndpointStoreTripleIterator.java | 10 ++++++++-- 3 files changed, 33 insertions(+), 3 deletions(-) diff --git a/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStore.java b/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStore.java index 479ba76a..992bc8e5 100644 --- a/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStore.java +++ b/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStore.java @@ -85,6 +85,10 @@ public class EndpointStore extends AbstractNotifyingSail { * enable the merge join, default true */ public static final String OPTION_QENDPOINT_MERGE_JOIN = "qendpoint.mergejoin"; + /** + * disable delete bitmaps, default false + */ + public static final String OPTION_QENDPOINT_DELETE_DISABLE = "qendpoint.delete.disable"; private static final AtomicLong ENDPOINT_DEBUG_ID_GEN = new AtomicLong(); private static final Logger logger = LoggerFactory.getLogger(EndpointStore.class); private final long debugId; @@ -113,6 +117,7 @@ public class EndpointStore extends AbstractNotifyingSail { // setting to put the delete map only in memory, i.e don't write to disk private final boolean inMemDeletes; private final boolean loadIntoMemory; + private final boolean deleteDisabled; // bitmaps used to mark if the subject, predicate, object elements in HDT // are used in the rdf4j delta store @@ -175,6 +180,7 @@ public EndpointStore(EndpointFiles files, HDTOptions spec, boolean inMemDeletes, throws IOException { // load HDT file this.spec = (spec = HDTOptions.ofNullable(spec)); + deleteDisabled = spec.getBoolean(OPTION_QENDPOINT_DELETE_DISABLE, false); validOrders = getHDTSpec().getEnumSet(HDTOptionsKeys.BITMAPTRIPLES_INDEX_OTHERS, TripleComponentOrder.class); validOrders.add(TripleComponentOrder.SPO); // we need at least SPO @@ -1215,6 +1221,10 @@ public long getGraphsCount(HDT hdt) { return hdt.getDictionary().supportGraphs() ? hdt.getDictionary().getNgraphs() : 1; } + public boolean isDeleteDisabled() { + return deleteDisabled; + } + public long getGraphsCount() { return getGraphsCount(this.hdt); } diff --git a/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreConnection.java b/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreConnection.java index 3e2ef82d..8c512674 100644 --- a/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreConnection.java +++ b/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreConnection.java @@ -503,7 +503,8 @@ protected long sizeInternal(Resource... contexts) throws SailException { long sizeNativeB = connB_read.size(contexts); long sizeHdt = this.endpoint.getHdt().getTriples().getNumberOfElements(); - long sizeDeleted = this.endpoint.getDeleteBitMap(TripleComponentOrder.SPO).getHandle().countOnes(); + long sizeDeleted = endpoint.isDeleteDisabled() ? 0 + : this.endpoint.getDeleteBitMap(TripleComponentOrder.SPO).getHandle().countOnes(); logger.info("---------------------------"); logger.info("Size native A:" + sizeNativeA); logger.info("Size native B:" + sizeNativeB); @@ -519,6 +520,10 @@ public void removeStatement(UpdateContext op, Resource subj, IRI pred, Value obj if (MergeRunnableStopPoint.disableRequest) throw new MergeRunnableStopPoint.MergeRunnableException("connections request disabled"); + if (endpoint.isDeleteDisabled()) { + throw new SailException("This sail doesn't support deletion"); + } + isWriteConnection = true; Resource newSubj; @@ -585,6 +590,9 @@ private boolean tripleDoesntExistInHDT(TripleID tripleID) { // if iterator is empty then the given triple doesn't exist in HDT if (iter.hasNext()) { TripleID tid = iter.next(); + if (endpoint.isDeleteDisabled()) { + return false; + } long index = iter.getLastTriplePosition(); return this.endpoint .getDeleteBitMap( @@ -601,6 +609,9 @@ private boolean quadDoesntExistInHDT(TripleID tripleID) { // if iterator is empty then the given triple 't' doesn't exist in HDT if (iter.hasNext()) { TripleID tid = iter.next(); + if (endpoint.isDeleteDisabled()) { + return false; + } long index = iter.getLastTriplePosition(); return this.endpoint .getDeleteBitMap( @@ -612,6 +623,9 @@ private boolean quadDoesntExistInHDT(TripleID tripleID) { private void assignBitMapDeletes(TripleID tid, Resource subj, IRI pred, Value obj, Resource[] contexts, long[] contextIds) throws SailException { + if (endpoint.isDeleteDisabled()) { + throw new SailException("This endpoint doesn't support deletion"); + } long s = tid.getSubject(); long p = tid.getPredicate(); long o = tid.getObject(); diff --git a/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreTripleIterator.java b/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreTripleIterator.java index cd2e202a..2427cea5 100644 --- a/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreTripleIterator.java +++ b/qendpoint-store/src/main/java/com/the_qa_company/qendpoint/store/EndpointStoreTripleIterator.java @@ -52,10 +52,16 @@ public boolean hasNext() { // iterate over the result of hdt while (iterator.hasNext()) { TripleID tripleID = iterator.next(); - long index = iterator.getLastTriplePosition(); + long index; + if (endpoint.isDeleteDisabled()) { + index = -1; + } else { + index = iterator.getLastTriplePosition(); + } TripleComponentOrder order = iterator.isLastTriplePositionBoundToOrder() ? iterator.getOrder() : TripleComponentOrder.SPO; - if (!endpoint.getDeleteBitMap(order).access(tripleID.isQuad() ? tripleID.getGraph() - 1 : 0, index)) { + if (endpoint.isDeleteDisabled() || !endpoint.getDeleteBitMap(order) + .access(tripleID.isQuad() ? tripleID.getGraph() - 1 : 0, index)) { Resource subject = endpoint.getHdtConverter().idToSubjectHDTResource(tripleID.getSubject()); IRI predicate = endpoint.getHdtConverter().idToPredicateHDTResource(tripleID.getPredicate()); Value object = endpoint.getHdtConverter().idToObjectHDTResource(tripleID.getObject());