From fb1f6ebb07ce0c29b47c2bb48850faf78264c2b3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 24 May 2023 10:47:08 +0200 Subject: [PATCH 1/5] update benchmark --- .../memory/benchmark/LoadingBenchmark.java | 20 +++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java b/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java index 6f878f5a1b5..c270b730fc6 100644 --- a/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java +++ b/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java @@ -55,7 +55,7 @@ @Warmup(iterations = 5) @BenchmarkMode({ Mode.AverageTime }) //@Fork(value = 1, jvmArgs = {"-Xms4G", "-Xmx4G", "-XX:+UnlockCommercialFeatures", "-XX:StartFlightRecording=delay=5s,duration=60s,filename=recording.jfr,settings=profile", "-XX:FlightRecorderOptions=samplethreads=true,stackdepth=1024", "-XX:+UnlockDiagnosticVMOptions", "-XX:+DebugNonSafepoints"}) -@Fork(value = 1, jvmArgs = { "-Xms4G", "-Xmx4G" }) +@Fork(value = 3, jvmArgs = { "-Xms4G", "-Xmx4G" }) @Measurement(iterations = 5) @OutputTimeUnit(TimeUnit.MILLISECONDS) public class LoadingBenchmark { @@ -67,12 +67,20 @@ public class LoadingBenchmark { private static final Model realData = getRealData(); public static void main(String[] args) throws RunnerException { - Options opt = new OptionsBuilder() - .include("LoadingBenchmark.*") // adapt to run other benchmark tests - .forks(1) - .build(); +// Options opt = new OptionsBuilder() +// .include("LoadingBenchmark.*") // adapt to run other benchmark tests +// .forks(1) +// .build(); +// +// new Runner(opt).run(); + + LoadingBenchmark loadingBenchmark = new LoadingBenchmark(); + loadingBenchmark.isolationLevel = "NONE"; + for (int i = 0; i < 100; i++) { + System.out.println(i); + loadingBenchmark.loadRealData(); + } - new Runner(opt).run(); } @Benchmark From b4dcc4141549eb752804fca435ed96bde867dfba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 24 May 2023 10:47:20 +0200 Subject: [PATCH 2/5] wip --- .../sail/helpers/AbstractSailConnection.java | 101 ++++++++++++------ .../org/eclipse/rdf4j/sail/memory/FileIO.java | 10 +- .../sail/memory/MemEvaluationStatistics.java | 2 +- .../rdf4j/sail/memory/MemorySailStore.java | 33 ++++-- .../rdf4j/sail/memory/model/MemIRI.java | 28 ++--- .../rdf4j/sail/memory/model/MemResource.java | 4 +- .../sail/memory/model/MemStatementList.java | 24 +++++ .../rdf4j/sail/memory/model/MemValue.java | 2 +- .../sail/memory/model/MemValueFactory.java | 58 +++++----- .../MemValueFactoryConcurrentBenchmark.java | 2 +- 10 files changed, 169 insertions(+), 95 deletions(-) diff --git a/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java b/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java index c6a4e331cd2..98a58e7c64e 100644 --- a/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java +++ b/core/sail/api/src/main/java/org/eclipse/rdf4j/sail/helpers/AbstractSailConnection.java @@ -74,6 +74,7 @@ public abstract class AbstractSailConnection implements SailConnection { private final AbstractSail sailBase; private volatile boolean txnActive; + private static final VarHandle TXN_ACTIVE; private volatile boolean txnPrepared; @@ -91,16 +92,6 @@ public abstract class AbstractSailConnection implements SailConnection { private boolean isOpen = true; private static final VarHandle IS_OPEN; - static { - try { - IS_OPEN = MethodHandles.lookup() - .in(AbstractSailConnection.class) - .findVarHandle(AbstractSailConnection.class, "isOpen", boolean.class); - } catch (ReflectiveOperationException e) { - throw new Error(e); - } - } - /** * Lock used to prevent concurrent calls to update methods like addStatement, clear, commit, etc. within a * transaction. @@ -138,17 +129,20 @@ public abstract class AbstractSailConnection implements SailConnection { private IsolationLevel transactionIsolationLevel; - // used to decide if we need to call flush() + // Used to decide if we need to call flush(). Use the VarHandles below in relase/acquire mode instead. private volatile boolean statementsAdded; private volatile boolean statementsRemoved; + private static final VarHandle STATEMENTS_ADDED; + private static final VarHandle STATEMENTS_REMOVED; + /*--------------* * Constructors * *--------------*/ public AbstractSailConnection(AbstractSail sailBase) { this.sailBase = sailBase; - txnActive = false; + TXN_ACTIVE.setRelease(this, false); if (debugEnabled) { activeIterationsDebug = new ConcurrentHashMap<>(); } else { @@ -177,7 +171,7 @@ protected void verifyIsOpen() throws SailException { * @throws SailException if no transaction is active. */ protected void verifyIsActive() throws SailException { - if (!isActive()) { + if (!((boolean) TXN_ACTIVE.getAcquire(this))) { throw new SailException("No active transaction"); } } @@ -215,7 +209,7 @@ public void begin(IsolationLevel isolationLevel) throws SailException { } startTransactionInternal(); - txnActive = true; + TXN_ACTIVE.setRelease(this, true); } finally { updateLock.unlock(); } @@ -268,7 +262,7 @@ public final void close() throws SailException { try { forceCloseActiveOperations(); - if (txnActive) { + if ((boolean) TXN_ACTIVE.getAcquire(this)) { logger.warn("Rolling back transaction due to connection close", debugEnabled ? new Throwable() : null); try { @@ -276,7 +270,7 @@ public final void close() throws SailException { // rollback method will try to obtain a connection lock rollbackInternal(); } finally { - txnActive = false; + TXN_ACTIVE.setRelease(this, false); txnPrepared = false; } } @@ -417,7 +411,7 @@ public final long size(Resource... contexts) throws SailException { } protected final boolean transactionActive() { - return txnActive; + return (boolean) TXN_ACTIVE.getAcquire(this); } /** @@ -459,7 +453,7 @@ public final void prepare() throws SailException { updateLock.lock(); try { - if (txnActive) { + if ((boolean) TXN_ACTIVE.getAcquire(this)) { prepareInternal(); txnPrepared = true; } @@ -489,12 +483,12 @@ public final void commit() throws SailException { updateLock.lock(); try { - if (txnActive) { + if ((boolean) TXN_ACTIVE.getAcquire(this)) { if (!txnPrepared) { prepareInternal(); } commitInternal(); - txnActive = false; + TXN_ACTIVE.setRelease(this, false); txnPrepared = false; } } finally { @@ -525,11 +519,11 @@ public final void rollback() throws SailException { updateLock.lock(); try { - if (txnActive) { + if ((boolean) TXN_ACTIVE.getAcquire(this)) { try { rollbackInternal(); } finally { - txnActive = false; + TXN_ACTIVE.setRelease(this, false); txnPrepared = false; } } else { @@ -553,7 +547,8 @@ public final void addStatement(Resource subj, IRI pred, Value obj, Resource... c flushPendingUpdates(); } addStatement(null, subj, pred, obj, contexts); - statementsAdded = true; + + STATEMENTS_ADDED.setRelease(this, true); } @Override @@ -562,7 +557,7 @@ public final void removeStatements(Resource subj, IRI pred, Value obj, Resource. flushPendingUpdates(); } removeStatement(null, subj, pred, obj, contexts); - statementsRemoved = true; + STATEMENTS_REMOVED.setRelease(this, true); } @Override @@ -604,7 +599,7 @@ public void addStatement(UpdateContext op, Resource subj, IRI pred, Value obj, R startUpdate(op); } } - statementsAdded = true; + STATEMENTS_ADDED.setRelease(this, true); } /** @@ -632,7 +627,7 @@ public void removeStatement(UpdateContext op, Resource subj, IRI pred, Value obj startUpdate(op); } } - statementsRemoved = true; + STATEMENTS_REMOVED.setRelease(this, true); } @Override @@ -703,7 +698,7 @@ public final void clear(Resource... contexts) throws SailException { try { verifyIsActive(); clearInternal(contexts); - statementsRemoved = true; + STATEMENTS_REMOVED.setRelease(this, true); } finally { updateLock.unlock(); } @@ -836,19 +831,20 @@ public final void clearNamespaces() throws SailException { @Override public boolean pendingRemovals() { - return statementsRemoved; + return (boolean) STATEMENTS_REMOVED.getAcquire(this); + } protected boolean pendingAdds() { - return statementsAdded; + return (boolean) STATEMENTS_ADDED.getAcquire(this); } protected void setStatementsAdded() { - statementsAdded = true; + STATEMENTS_ADDED.setRelease(this, true); } protected void setStatementsRemoved() { - statementsRemoved = true; + STATEMENTS_REMOVED.setRelease(this, true); } @Deprecated(forRemoval = true) @@ -992,9 +988,10 @@ private void forceCloseActiveOperations() throws SailException { * @throws SailException */ private void flushPendingUpdates() throws SailException { - if ((statementsAdded || statementsRemoved) && isActive()) { + if ((pendingAdds() || pendingRemovals()) && isActive()) { if (isActive()) { synchronized (this) { + // we are inside a synchornized block so there isn't much point using the VarHandle if ((statementsAdded || statementsRemoved) && isActive()) { flush(); statementsAdded = false; @@ -1128,4 +1125,44 @@ public synchronized void release() { } } } + + static { + try { + IS_OPEN = MethodHandles.lookup() + .in(AbstractSailConnection.class) + .findVarHandle(AbstractSailConnection.class, "isOpen", boolean.class); + } catch (ReflectiveOperationException e) { + throw new Error(e); + } + } + + static { + try { + TXN_ACTIVE = MethodHandles.lookup() + .in(AbstractSailConnection.class) + .findVarHandle(AbstractSailConnection.class, "txnActive", boolean.class); + } catch (ReflectiveOperationException e) { + throw new Error(e); + } + } + + static { + try { + STATEMENTS_REMOVED = MethodHandles.lookup() + .in(AbstractSailConnection.class) + .findVarHandle(AbstractSailConnection.class, "statementsRemoved", boolean.class); + } catch (ReflectiveOperationException e) { + throw new Error(e); + } + } + + static { + try { + STATEMENTS_ADDED = MethodHandles.lookup() + .in(AbstractSailConnection.class) + .findVarHandle(AbstractSailConnection.class, "statementsAdded", boolean.class); + } catch (ReflectiveOperationException e) { + throw new Error(e); + } + } } diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/FileIO.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/FileIO.java index 8bd76bdcb82..6d04b0e1d06 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/FileIO.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/FileIO.java @@ -82,7 +82,7 @@ class FileIO { public static final int INF_QUAD_MARKER = 5; - public static final int URI_MARKER = 6; + public static final int IRI_MARKER = 6; public static final int BNODE_MARKER = 7; @@ -270,7 +270,7 @@ private void readStatement(boolean hasContext, boolean isExplicit, DataInputStre private void writeValue(Value value, DataOutputStream dataOut) throws IOException { if (value.isIRI()) { - dataOut.writeByte(URI_MARKER); + dataOut.writeByte(IRI_MARKER); writeString(((IRI) value).stringValue(), dataOut); } else if (value.isBNode()) { dataOut.writeByte(BNODE_MARKER); @@ -301,9 +301,9 @@ private void writeValue(Value value, DataOutputStream dataOut) throws IOExceptio private Value readValue(DataInputStream dataIn) throws IOException, ClassCastException { int valueTypeMarker = dataIn.readByte(); - if (valueTypeMarker == URI_MARKER) { - String uriString = readString(dataIn); - return vf.createIRI(uriString); + if (valueTypeMarker == IRI_MARKER) { + String iriString = readString(dataIn); + return vf.createIRI(iriString); } else if (valueTypeMarker == BNODE_MARKER) { String bnodeID = readString(dataIn); return vf.createBNode(bnodeID); diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemEvaluationStatistics.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemEvaluationStatistics.java index 25b63b5b659..0f0184aa6b5 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemEvaluationStatistics.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemEvaluationStatistics.java @@ -98,7 +98,7 @@ private int minStatementCount(Value subj, Value pred, Value obj, Value context) } if (pred != null) { - MemIRI memPred = valueFactory.getMemURI((IRI) pred); + MemIRI memPred = valueFactory.getMemIRI((IRI) pred); if (memPred != null) { minListSizes = Math.min(minListSizes, memPred.getPredicateStatementCount()); if (minListSizes == 0) { diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java index 90340613807..c85b48a4d66 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/MemorySailStore.java @@ -213,7 +213,7 @@ private CloseableIteration createStatementIterator( return EMPTY_ITERATION; } - MemIRI memPred = valueFactory.getMemURI(pred); + MemIRI memPred = valueFactory.getMemIRI(pred); if (pred != null && memPred == null) { // non-existent predicate return EMPTY_ITERATION; @@ -345,7 +345,7 @@ private CloseableIteration createTripleIterator(Resour return EMPTY_TRIPLE_ITERATION; } - MemIRI memPred = valueFactory.getMemURI(pred); + MemIRI memPred = valueFactory.getMemIRI(pred); if (pred != null && memPred == null) { // non-existent predicate return EMPTY_TRIPLE_ITERATION; @@ -592,7 +592,7 @@ public String toString() { } else { sb.append("inferred "); } - if (txnLock) { + if ((boolean) TXN_LOCK.getAcquire(this)) { sb.append("snapshot ").append(nextSnapshot); } else { sb.append(super.toString()); @@ -635,7 +635,7 @@ public synchronized void prepare() throws SailException { @Override public synchronized void flush() throws SailException { - if (txnLock) { + if ((boolean) TXN_LOCK.getAcquire(this)) { invalidateCache(); currentSnapshot = Math.max(currentSnapshot, nextSnapshot); if (requireCleanup) { @@ -653,8 +653,8 @@ public void close() { reservedSnapshot.release(); } } finally { - boolean toCloseTxnLock = txnLock; - txnLock = false; + boolean toCloseTxnLock = (boolean) TXN_LOCK.getAcquire(this); + TXN_LOCK.setRelease(this, false); if (toCloseTxnLock) { txnLockManager.unlock(); } @@ -792,7 +792,7 @@ private void innerDeprecate(Statement statement, int nextSnapshot) { } private void acquireExclusiveTransactionLock() throws SailException { - if (!txnLock) { + if (!(boolean) TXN_LOCK.getAcquire(this)) { synchronized (this) { if (!txnLock) { txnLockManager.lock(); @@ -812,7 +812,7 @@ private MemStatement addStatement(Resource subj, IRI pred, Value obj, Resource c // Get or create MemValues for the operands MemResource memSubj = valueFactory.getOrCreateMemResource(subj); - MemIRI memPred = valueFactory.getOrCreateMemURI(pred); + MemIRI memPred = valueFactory.getOrCreateMemIRI(pred); MemValue memObj = valueFactory.getOrCreateMemValue(obj); MemResource memContext = context == null ? null : valueFactory.getOrCreateMemResource(context); @@ -1118,7 +1118,7 @@ public ReservedSnapshot reserve(int snapshot, Object reservedBy) { } } - LongAdder longAdder = activeSnapshots.computeIfAbsent(snapshot, (k) -> new LongAdder()); + LongAdder longAdder = activeSnapshots.computeIfAbsent(snapshot, k -> new LongAdder()); longAdder.increment(); return new ReservedSnapshot(snapshot, reservedBy, debug, longAdder, activeSnapshots, @@ -1162,7 +1162,7 @@ public ReservedSnapshot(int snapshot, Object reservedBy, boolean debug, this.frequency = frequency; this.highestEverReservedSnapshot = highestEverReservedSnapshot; cleanable = cleaner.register(reservedBy, () -> { - int tempSnapshot = ((int) SNAPSHOT.getVolatile(this)); + int tempSnapshot = (int) SNAPSHOT.getVolatile(this); if (tempSnapshot != SNAPSHOT_RELEASED) { String message = "Releasing MemorySailStore snapshot {} which was reserved and never released (possibly unclosed MemorySailDataset or MemorySailSink)."; if (stackTraceForDebugging != null) { @@ -1201,4 +1201,17 @@ public void release() { } } + + private static final VarHandle TXN_LOCK; + + static { + try { + TXN_LOCK = MethodHandles.lookup() + .in(MemorySailSink.class) + .findVarHandle(MemorySailSink.class, "txnLock", boolean.class); + } catch (ReflectiveOperationException e) { + throw new Error(e); + } + } + } diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java index e21fc8f9408..d15a49d89ea 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java @@ -16,7 +16,7 @@ import org.eclipse.rdf4j.model.Value; /** - * A MemoryStore-specific implementation of URI that stores separated namespace and local name information to enable + * A MemoryStore-specific implementation of IRI that stores separated namespace and local name information to enable * reuse of namespace String objects (reducing memory usage) and that gives it node properties. */ public class MemIRI extends MemResource implements IRI { @@ -28,32 +28,32 @@ public class MemIRI extends MemResource implements IRI { *------------*/ /** - * The URI's namespace. + * The IRI's namespace. */ private final String namespace; /** - * The URI's local name. + * The IRI's local name. */ private final String localName; /** - * The object that created this MemURI. + * The object that created this MemIRI. */ transient private final Object creator; /** - * The MemURI's hash code, 0 if not yet initialized. + * The MemIRI's hash code, 0 if not yet initialized. */ private volatile int hashCode = 0; /** - * The list of statements for which this MemURI is the predicate. + * The list of statements for which this MemIRI is the predicate. */ transient private final MemStatementList predicateStatements = new MemStatementList(); /** - * The list of statements for which this MemURI is the object. + * The list of statements for which this MemIRI is the object. */ transient private final MemStatementList objectStatements = new MemStatementList(); @@ -62,11 +62,11 @@ public class MemIRI extends MemResource implements IRI { *--------------*/ /** - * Creates a new MemURI for a URI. + * Creates a new MemIRI for a IRI. * - * @param creator The object that is creating this MemURI. - * @param namespace namespace part of URI. - * @param localName localname part of URI. + * @param creator The object that is creating this MemIRI. + * @param namespace namespace part of IRI. + * @param localName localname part of IRI. */ public MemIRI(Object creator, String namespace, String localName) { this.creator = creator; @@ -176,7 +176,7 @@ public boolean hasStatements() { } /** - * Gets the list of statements for which this MemURI is the predicate. + * Gets the list of statements for which this MemIRI is the predicate. * * @return a MemStatementList containing the statements. */ @@ -185,7 +185,7 @@ public MemStatementList getPredicateStatementList() { } /** - * Gets the number of Statements for which this MemURI is the predicate. + * Gets the number of Statements for which this MemIRI is the predicate. * * @return An integer larger than or equal to 0. */ @@ -194,7 +194,7 @@ public int getPredicateStatementCount() { } /** - * Adds a statement to this MemURI's list of statements for which it is the predicate. + * Adds a statement to this MemIRI's list of statements for which it is the predicate. */ public void addPredicateStatement(MemStatement st) throws InterruptedException { predicateStatements.add(st); diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemResource.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemResource.java index ca9c588a5af..549075d85df 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemResource.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemResource.java @@ -18,12 +18,12 @@ public abstract class MemResource implements MemValue, Resource { /** - * The list of statements for which this MemURI is the subject. + * The list of statements for which this MemIRI is the subject. */ transient final MemStatementList subjectStatements = new MemStatementList(); /** - * The list of statements for which this MemURI represents the context. + * The list of statements for which this MemIRI represents the context. */ transient final MemStatementList contextStatements = new MemStatementList(); diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java index 10dc1800001..d75a5d97fe6 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java @@ -328,6 +328,30 @@ public void setPrioritiseCleanup(boolean prioritiseCleanup) { } } + boolean verifySizeForTesting() { + MemStatement[] statements1 = getStatementsWithoutInterrupt(); + int size = 0; + for (int i = 0; i < statements1.length; i++) { + if (statements1[i] != null) { + size++; + } + } + return size == size(); + + } + + int getRealSizeForTesting() { + MemStatement[] statements1 = getStatementsWithoutInterrupt(); + int size = 0; + for (int i = 0; i < statements1.length; i++) { + if (statements1[i] != null) { + size++; + } + } + return size; + + } + static { try { SIZE = MethodHandles.lookup() diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValue.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValue.java index c16778eb318..c3477280ec6 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValue.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValue.java @@ -22,7 +22,7 @@ public interface MemValue extends Value { *-----------*/ /** - * A shared empty MemStatementList that is returned by MemURI and MemBNode to represent an empty list. The use of a + * A shared empty MemStatementList that is returned by MemIRI and MemBNode to represent an empty list. The use of a * shared list reduces memory usage. */ MemStatementList EMPTY_LIST = new MemStatementList(0); diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValueFactory.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValueFactory.java index e2a12b6577a..b85d12a3ce1 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValueFactory.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemValueFactory.java @@ -42,7 +42,7 @@ public class MemValueFactory extends AbstractValueFactory { *------------*/ /** - * Registry containing the set of MemURI objects as used by a MemoryStore. This registry enables the reuse of + * Registry containing the set of MemIRI objects as used by a MemoryStore. This registry enables the reuse of * objects, minimizing the number of objects in main memory. */ private final WeakObjectRegistry iriRegistry = new WeakObjectRegistry<>(); @@ -66,7 +66,7 @@ public class MemValueFactory extends AbstractValueFactory { private final WeakObjectRegistry literalRegistry = new WeakObjectRegistry<>(); /** - * Registry containing the set of namespce strings as used by MemURI objects in a MemoryStore. This registry enables + * Registry containing the set of namespce strings as used by MemIRI objects in a MemoryStore. This registry enables * the reuse of objects, minimizing the number of objects in main memory. */ private final WeakObjectRegistry namespaceRegistry = new WeakObjectRegistry<>(); @@ -103,7 +103,7 @@ public MemValue getMemValue(Value value) { if (value == null) { return null; } else if (value.isIRI()) { - return getMemURI((IRI) value); + return getMemIRI((IRI) value); } else if (value.isBNode()) { return getMemBNode((BNode) value); } else if (value.isTriple()) { @@ -122,26 +122,26 @@ public MemResource getMemResource(Resource resource) { if (resource == null) { return null; } else if (resource.isIRI()) { - return getMemURI((IRI) resource); + return getMemIRI((IRI) resource); } else if (resource.isBNode()) { return getMemBNode((BNode) resource); } else if (resource.isTriple()) { return getMemTriple((Triple) resource); } else { - throw new IllegalArgumentException("resource is not a URI or BNode: " + resource); + throw new IllegalArgumentException("resource is not an IRI or BNode: " + resource); } } /** * See getMemValue() for description. */ - public MemIRI getMemURI(IRI uri) { - if (uri == null) { + public MemIRI getMemIRI(IRI iri) { + if (iri == null) { return null; - } else if (isOwnMemIRI(uri)) { - return (MemIRI) uri; + } else if (isOwnMemIRI(iri)) { + return (MemIRI) iri; } else { - return iriRegistry.get(uri); + return iriRegistry.get(iri); } } @@ -203,15 +203,15 @@ private boolean isOwnMemIRI(IRI value) { } /** - * Gets all URIs that are managed by this value factory. + * Gets all IRIs that are managed by this value factory. *

* Warning: This method is not synchronized. * - * @return An unmodifiable Set of MemURI objects. + * @return An unmodifiable Set of MemIRI objects. * @deprecated Use getMemIRIsIterator() instead. */ @Deprecated(forRemoval = true, since = "4.0.0") - public Set getMemURIs() { + public Set getMemIRIs() { return Collections.unmodifiableSet(iriRegistry); } @@ -233,7 +233,7 @@ public Set getMemBNodes() { *

* Warning: This method is not synchronized. * - * @return An unmodifiable Set of MemURI objects. + * @return An unmodifiable Set of MemIRI objects. * @deprecated Use getMemLiteralsIterator() instead. */ @Deprecated(forRemoval = true, since = "4.0.0") @@ -242,7 +242,7 @@ public Set getMemLiterals() { } /** - * Gets all URIs that are managed by this value factory. + * Gets all IRIs that are managed by this value factory. * * @return An autocloseable iterator. */ @@ -291,32 +291,32 @@ public MemValue getOrCreateMemValue(Value value) { */ public MemResource getOrCreateMemResource(Resource resource) { if (resource.isIRI()) { - return getOrCreateMemURI((IRI) resource); + return getOrCreateMemIRI((IRI) resource); } else if (resource.isBNode()) { return getOrCreateMemBNode((BNode) resource); } else if (resource.isTriple()) { return getOrCreateMemTriple((Triple) resource); } else { - throw new IllegalArgumentException("resource is not a URI or BNode: " + resource); + throw new IllegalArgumentException("resource is not an IRI or BNode: " + resource); } } /** * See {@link #getOrCreateMemValue(Value)} for description. */ - public MemIRI getOrCreateMemURI(IRI uri) { - if (isOwnMemIRI(uri)) { - return (MemIRI) uri; + public MemIRI getOrCreateMemIRI(IRI iri) { + if (isOwnMemIRI(iri)) { + return (MemIRI) iri; } - return iriRegistry.getOrAdd(uri, () -> { + return iriRegistry.getOrAdd(iri, () -> { - String namespace = uri.getNamespace(); + String namespace = iri.getNamespace(); String sharedNamespace = namespaceRegistry.getOrAdd(namespace, () -> namespace); - // Create a MemURI and add it to the registry - return new MemIRI(this, sharedNamespace, uri.getLocalName()); + // Create a MemIRI and add it to the registry + return new MemIRI(this, sharedNamespace, iri.getLocalName()); }); } @@ -384,7 +384,7 @@ private MemTriple getOrCreateMemTriple(Triple triple) { if (memTriple == null) { // Create a MemTriple and add it to the registry MemTriple newMemTriple = new MemTriple(this, getOrCreateMemResource(triple.getSubject()), - getOrCreateMemURI(triple.getPredicate()), getOrCreateMemValue(triple.getObject())); + getOrCreateMemIRI(triple.getPredicate()), getOrCreateMemValue(triple.getObject())); boolean wasNew = tripleRegistry.add(newMemTriple); if (!wasNew) { @@ -399,8 +399,8 @@ private MemTriple getOrCreateMemTriple(Triple triple) { } @Override - public IRI createIRI(String uri) { - return getOrCreateMemURI(super.createIRI(uri)); + public IRI createIRI(String iri) { + return getOrCreateMemIRI(super.createIRI(iri)); } @Override @@ -408,7 +408,7 @@ public IRI createIRI(String namespace, String localName) { return iriRegistry.getOrAdd(SimpleValueFactory.getInstance().createIRI(namespace, localName), () -> { if (namespace.indexOf(':') == -1) { - throw new IllegalArgumentException("Not a valid (absolute) URI: " + namespace + localName); + throw new IllegalArgumentException("Not a valid (absolute) IRI: " + namespace + localName); } String correctNamespace; @@ -426,7 +426,7 @@ public IRI createIRI(String namespace, String localName) { String sharedNamespace = namespaceRegistry.getOrAdd(correctNamespace, () -> correctNamespace); - // Create a MemURI and add it to the registry + // Create a MemIRI and add it to the registry return new MemIRI(this, sharedNamespace, correctLocalName); }); diff --git a/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/MemValueFactoryConcurrentBenchmark.java b/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/MemValueFactoryConcurrentBenchmark.java index 4f5b02057cb..7b83c383db4 100644 --- a/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/MemValueFactoryConcurrentBenchmark.java +++ b/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/MemValueFactoryConcurrentBenchmark.java @@ -155,7 +155,7 @@ public void readHeavy(Blackhole blackhole) throws Exception { Random r = new Random(random.nextInt()); for (int i = 0; i < BUCKET_SIZE; i++) { MemIRI orCreateMemURI = valueFactory - .getOrCreateMemURI(Values.iri("http://example.com", "" + r.nextInt(BUCKET_SIZE / 10))); + .getOrCreateMemIRI(Values.iri("http://example.com", "" + r.nextInt(BUCKET_SIZE / 10))); blackhole.consume(orCreateMemURI); } }); From 94612bc5563905c3e6beb85474aabc94b2583a75 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 24 May 2023 12:33:45 +0200 Subject: [PATCH 3/5] fix --- .../sail/memory/model/MemStatementList.java | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java index d75a5d97fe6..10dc1800001 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemStatementList.java @@ -328,30 +328,6 @@ public void setPrioritiseCleanup(boolean prioritiseCleanup) { } } - boolean verifySizeForTesting() { - MemStatement[] statements1 = getStatementsWithoutInterrupt(); - int size = 0; - for (int i = 0; i < statements1.length; i++) { - if (statements1[i] != null) { - size++; - } - } - return size == size(); - - } - - int getRealSizeForTesting() { - MemStatement[] statements1 = getStatementsWithoutInterrupt(); - int size = 0; - for (int i = 0; i < statements1.length; i++) { - if (statements1[i] != null) { - size++; - } - } - return size; - - } - static { try { SIZE = MethodHandles.lookup() From 0afd7ec5f67ee896ff98fca552f45f0226d641cd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 24 May 2023 12:33:58 +0200 Subject: [PATCH 4/5] update benchmarks --- .../eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java b/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java index c270b730fc6..adef9774fbe 100644 --- a/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java +++ b/core/sail/memory/src/test/java/org/eclipse/rdf4j/sail/memory/benchmark/LoadingBenchmark.java @@ -76,7 +76,7 @@ public static void main(String[] args) throws RunnerException { LoadingBenchmark loadingBenchmark = new LoadingBenchmark(); loadingBenchmark.isolationLevel = "NONE"; - for (int i = 0; i < 100; i++) { + for (int i = 0; i < 500; i++) { System.out.println(i); loadingBenchmark.loadRealData(); } From 2f12e0513a636cfe9a6144ca6df3ca1bd94458df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ha=CC=8Avard=20Ottestad?= Date: Wed, 24 May 2023 12:43:06 +0200 Subject: [PATCH 5/5] update the cached string value to match the one that it is compared to --- .../rdf4j/sail/memory/model/MemIRI.java | 26 +++++++++++++++---- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java index d15a49d89ea..c53fb5b223a 100644 --- a/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java +++ b/core/sail/memory/src/main/java/org/eclipse/rdf4j/sail/memory/model/MemIRI.java @@ -127,10 +127,17 @@ public boolean equals(Object o) { // two different MemIRI from the same MemoryStore can not be equal. return false; } - return namespace.length() == oMemIRI.namespace.length() && - localName.length() == oMemIRI.localName.length() && - namespace.equals(oMemIRI.namespace) && - localName.equals(oMemIRI.localName); + boolean equalLengtsh = namespace.length() == oMemIRI.namespace.length() && + localName.length() == oMemIRI.localName.length(); + + if (equalLengtsh) { + if (namespace.equals(oMemIRI.namespace)) { + if (localName.equals(oMemIRI.localName)) { + return true; + } + } + } + return false; } @@ -142,7 +149,16 @@ public boolean equals(Object o) { if (toStringCache != null) { String stringValue = toStringCache.get(); if (stringValue != null) { - return stringValue.equals(oStr); + if (oStr == stringValue) { + return true; + } else { + boolean equals = stringValue.equals(oStr); + if (equals) { + toStringCache = new SoftReference<>(oStr); + } + return equals; + } + } }