Skip to content

Commit 06f068d

Browse files
Ostrzycielkenwenzel
authored andcommitted
GH-5581: Only use value cache on value resolution
1 parent 400ef53 commit 06f068d

7 files changed

Lines changed: 85 additions & 24 deletions

File tree

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/ValueStore.java

Lines changed: 16 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -527,28 +527,16 @@ private static int nextPowerOfTwo(int n) {
527527
* @throws IOException If an I/O error occurred.
528528
*/
529529
public LmdbValue getLazyValue(long id) throws IOException {
530-
// Check value cache
531-
LmdbValue resultValue = cachedValue(id);
532-
533-
if (resultValue == null) {
534-
switch ((byte) (id & 0x3)) {
535-
case URI_VALUE:
536-
resultValue = new LmdbIRI(lazyRevision, id);
537-
break;
538-
case LITERAL_VALUE:
539-
resultValue = new LmdbLiteral(lazyRevision, id);
540-
break;
541-
case BNODE_VALUE:
542-
resultValue = new LmdbBNode(lazyRevision, id);
543-
break;
544-
default:
545-
throw new IOException("Unsupported value with type id " + (id & 0x3));
546-
}
547-
// Store value in cache
548-
cacheValue(id, resultValue);
530+
switch ((byte) (id & 0x3)) {
531+
case URI_VALUE:
532+
return new LmdbIRI(lazyRevision, id);
533+
case LITERAL_VALUE:
534+
return new LmdbLiteral(lazyRevision, id);
535+
case BNODE_VALUE:
536+
return new LmdbBNode(lazyRevision, id);
537+
default:
538+
throw new IOException("Unsupported value with type id " + (id & 0x3));
549539
}
550-
551-
return resultValue;
552540
}
553541

554542
/**
@@ -589,10 +577,17 @@ public LmdbValue getValue(long id) throws IOException {
589577
* @return <code>true</code> if value could be successfully resolved, else <code>false</code>
590578
*/
591579
public boolean resolveValue(long id, LmdbValue value) {
580+
// Try to get from cache
581+
LmdbValue cached = cachedValue(id);
582+
if (cached != null && this.getRevision().getRevisionId() == cached.getValueStoreRevision().getRevisionId()) {
583+
value.setFromInitializedValue(cached);
584+
return true;
585+
}
592586
try {
593587
byte[] data = getData(id);
594588
if (data != null) {
595589
data2value(id, data, value);
590+
cacheValue(id, value);
596591
return true;
597592
}
598593
} catch (IOException e) {

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/model/LmdbBNode.java

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,16 @@ public ValueStoreRevision getValueStoreRevision() {
6767
return revision;
6868
}
6969

70+
@Override
71+
public void setFromInitializedValue(LmdbValue initializedValue) {
72+
if (initializedValue instanceof LmdbBNode) {
73+
LmdbBNode lmdbBNode = (LmdbBNode) initializedValue;
74+
super.setID(lmdbBNode.getID());
75+
} else {
76+
throw new IllegalArgumentException("Initialized value is not of type LmdbBNode");
77+
}
78+
}
79+
7080
@Override
7181
public long getInternalID() {
7282
return internalID;

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/model/LmdbIRI.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515

1616
import org.eclipse.rdf4j.model.IRI;
1717
import org.eclipse.rdf4j.model.util.URIUtil;
18+
import org.eclipse.rdf4j.sail.SailException;
1819
import org.eclipse.rdf4j.sail.lmdb.ValueStoreRevision;
1920
import org.slf4j.Logger;
2021
import org.slf4j.LoggerFactory;
@@ -86,6 +87,17 @@ public ValueStoreRevision getValueStoreRevision() {
8687
return revision;
8788
}
8889

90+
@Override
91+
public void setFromInitializedValue(LmdbValue initializedValue) {
92+
if (initializedValue instanceof LmdbIRI) {
93+
LmdbIRI initializedIRI = (LmdbIRI) initializedValue;
94+
this.iriString = initializedIRI.iriString;
95+
this.localNameIdx = initializedIRI.localNameIdx;
96+
} else {
97+
throw new SailException("Trying to initialize LmdbIRI from non-IRI value");
98+
}
99+
}
100+
89101
@Override
90102
public long getInternalID() {
91103
return internalID;

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/model/LmdbLiteral.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,19 @@ public ValueStoreRevision getValueStoreRevision() {
147147
return revision;
148148
}
149149

150+
@Override
151+
public void setFromInitializedValue(LmdbValue initializedValue) {
152+
if (initializedValue instanceof LmdbLiteral) {
153+
LmdbLiteral lmdbLiteral = (LmdbLiteral) initializedValue;
154+
this.label = lmdbLiteral.label;
155+
this.language = lmdbLiteral.language;
156+
this.datatype = lmdbLiteral.datatype;
157+
this.coreDatatype = lmdbLiteral.coreDatatype;
158+
} else {
159+
throw new IllegalArgumentException("Initialized value is not of type LmdbLiteral");
160+
}
161+
}
162+
150163
@Override
151164
public long getInternalID() {
152165
return internalID;

core/sail/lmdb/src/main/java/org/eclipse/rdf4j/sail/lmdb/model/LmdbValue.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
*******************************************************************************/
1111
package org.eclipse.rdf4j.sail.lmdb.model;
1212

13+
import org.eclipse.rdf4j.common.annotation.InternalUseOnly;
1314
import org.eclipse.rdf4j.model.Value;
1415
import org.eclipse.rdf4j.sail.lmdb.ValueStoreRevision;
1516

@@ -41,4 +42,14 @@ public interface LmdbValue extends Value {
4142
* @return The revision of the value store that created this value at the time it last set the value's internal ID.
4243
*/
4344
ValueStoreRevision getValueStoreRevision();
45+
46+
/**
47+
* Sets this value's data from an initialized value.
48+
* <p>
49+
* This must be only called within a synchronized block in the init() method of the uninitialized value.
50+
*
51+
* @param initializedValue the initialized value to copy data from
52+
*/
53+
@InternalUseOnly
54+
void setFromInitializedValue(LmdbValue initializedValue);
4455
}

core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/ValueStoreCacheTest.java

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,9 @@
1010
*******************************************************************************/
1111
package org.eclipse.rdf4j.sail.lmdb;
1212

13+
import static org.junit.Assert.assertEquals;
1314
import static org.junit.Assert.assertNotNull;
15+
import static org.junit.Assert.assertNull;
1416
import static org.junit.Assert.assertSame;
1517

1618
import java.io.File;
@@ -38,12 +40,19 @@ void cachedValuePath(@TempDir File dataDir) throws Exception {
3840
IRI iri = vf.createIRI("urn:example:foo");
3941
long id = vs.getId(iri, true);
4042

41-
// Populate cache via lazy retrieval
43+
// On lazy retrieval, the cache should not be touched
4244
LmdbValue v1 = vs.getLazyValue(id);
45+
assertNotNull(v1);
46+
LmdbValue cached1 = vs.cachedValue(id);
47+
assertNull(cached1);
48+
49+
// After initializing the value, it should be cached
50+
assertEquals(v1.stringValue(), "urn:example:foo");
51+
LmdbValue cached2 = vs.cachedValue(id);
52+
assertSame(v1, cached2);
53+
4354
// Direct cache hit
4455
LmdbValue v2 = vs.cachedValue(id);
45-
46-
assertNotNull(v1);
4756
assertSame(v1, v2);
4857
} finally {
4958
store.shutDown();

core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/benchmark/QueryBenchmark.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -79,6 +79,7 @@ public class QueryBenchmark {
7979
private static final String wild_card_chain_with_common_ends;
8080
private static final String sub_select;
8181
private static final String multiple_sub_select;
82+
private static final String count_all;
8283

8384
static {
8485
try {
@@ -116,6 +117,7 @@ public class QueryBenchmark {
116117
sub_select = IOUtils.toString(getResourceAsStream("benchmarkFiles/sub-select.qr"), StandardCharsets.UTF_8);
117118
multiple_sub_select = IOUtils.toString(
118119
getResourceAsStream("benchmarkFiles/multiple-sub-select.qr"), StandardCharsets.UTF_8);
120+
count_all = "SELECT (COUNT(*) as ?c) WHERE { ?s ?p ?o }";
119121

120122
} catch (IOException e) {
121123
throw new RuntimeException(e);
@@ -415,6 +417,15 @@ public long multiple_sub_select() {
415417
}
416418
}
417419

420+
@Benchmark
421+
public long count_all() {
422+
try (SailRepositoryConnection connection = repository.getConnection()) {
423+
return count(connection
424+
.prepareTupleQuery(count_all)
425+
.evaluate());
426+
}
427+
}
428+
418429
// @Benchmark
419430
// public long wild_card_chain_with_common_ends() {
420431
// try (SailRepositoryConnection connection = repository.getConnection()) {

0 commit comments

Comments
 (0)