diff --git a/.github/workflows/develop-status.yml b/.github/workflows/develop-status.yml index 76301ef8fbe..193d1754297 100644 --- a/.github/workflows/develop-status.yml +++ b/.github/workflows/develop-status.yml @@ -20,7 +20,7 @@ jobs: with: java-version: ${{ matrix.jdk }} - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk${{ matrix.jdk }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/main-status.yml b/.github/workflows/main-status.yml index fdf918fb68e..aa50c4590c0 100644 --- a/.github/workflows/main-status.yml +++ b/.github/workflows/main-status.yml @@ -20,7 +20,7 @@ jobs: with: java-version: ${{ matrix.jdk }} - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk${{ matrix.jdk }}-maven-${{ hashFiles('**/pom.xml') }} diff --git a/.github/workflows/pr-verify.yml b/.github/workflows/pr-verify.yml index c89ed189e98..16443b76af1 100644 --- a/.github/workflows/pr-verify.yml +++ b/.github/workflows/pr-verify.yml @@ -15,7 +15,7 @@ jobs: with: java-version: ${{ matrix.jdk }} - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk${{ matrix.jdk }}-maven-${{ hashFiles('**/pom.xml') }} @@ -48,7 +48,7 @@ jobs: with: java-version: 11 - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk11-maven-${{ hashFiles('**/pom.xml') }} @@ -81,7 +81,7 @@ jobs: with: java-version: 11 - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk11-maven-${{ hashFiles('**/pom.xml') }} @@ -107,7 +107,7 @@ jobs: with: java-version: 11 - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk11-maven-${{ hashFiles('**/pom.xml') }} @@ -133,7 +133,7 @@ jobs: with: java-version: 11 - name: Cache local Maven repository - uses: actions/cache@v2 + uses: actions/cache@v4 with: path: ~/.m2/repository key: ${{ runner.os }}-jdk11-maven-${{ hashFiles('**/pom.xml') }} 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 a0ef94ce123..313acb6ea11 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 @@ -1252,6 +1252,7 @@ protected void clearCaches() { valueIDCache.clear(); namespaceCache.clear(); namespaceIDCache.clear(); + commonVocabulary.clear(); } /** diff --git a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/ValueStoreTest.java b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/ValueStoreTest.java index fff2bf17b11..724ed3102fa 100644 --- a/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/ValueStoreTest.java +++ b/core/sail/lmdb/src/test/java/org/eclipse/rdf4j/sail/lmdb/ValueStoreTest.java @@ -25,14 +25,19 @@ import java.util.List; import java.util.Random; import java.util.Set; +import java.util.stream.Collectors; import org.eclipse.rdf4j.model.IRI; import org.eclipse.rdf4j.model.Literal; import org.eclipse.rdf4j.model.Value; +import org.eclipse.rdf4j.model.util.Values; +import org.eclipse.rdf4j.model.vocabulary.RDF; +import org.eclipse.rdf4j.model.vocabulary.RDFS; import org.eclipse.rdf4j.model.vocabulary.XSD; import org.eclipse.rdf4j.sail.lmdb.config.LmdbStoreConfig; import org.eclipse.rdf4j.sail.lmdb.model.LmdbLiteral; import org.eclipse.rdf4j.sail.lmdb.model.LmdbValue; +import org.junit.Assert; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -58,49 +63,53 @@ private ValueStore createValueStore() throws IOException { @Test public void testGcValues() throws Exception { - Random random = new Random(1337); - LmdbValue values[] = new LmdbValue[1000]; + Value values[] = new Value[] { + RDF.TYPE, RDFS.CLASS, + Values.iri("some:iri"), + Values.literal("This is a literal.") + }; + long ids[] = new long[values.length]; valueStore.startTransaction(true); for (int i = 0; i < values.length; i++) { - values[i] = valueStore.createLiteral("This is a random literal:" + random.nextLong()); - valueStore.storeValue(values[i]); + ids[i] = valueStore.storeValue(values[i]); } valueStore.commit(); ValueStoreRevision revBefore = valueStore.getRevision(); valueStore.startTransaction(true); - Set ids = new HashSet<>(); - for (int i = 0; i < 30; i++) { - ids.add(values[i].getInternalID()); - } - valueStore.gcIds(ids, new HashSet<>()); + Set idsToGc = new HashSet<>(Arrays.stream(ids).boxed().collect(Collectors.toList())); + valueStore.gcIds(idsToGc, new HashSet<>()); valueStore.commit(); ValueStoreRevision revAfter = valueStore.getRevision(); - assertNotEquals("revisions must change after gc of IDs", revBefore, revAfter); - Arrays.fill(values, null); - // GC would collect revision at some point in time - // just add revision ID to free list for this test as forcing GC is not possible + for (int i = 0; i < values.length; i++) { + Assert.assertEquals(LmdbValue.UNKNOWN_ID, valueStore.getId(values[i])); + Assert.assertTrue(valueStore.getValue(ids[i]) != null); + } + + // simulate GC of unused revisions valueStore.unusedRevisionIds.add(revBefore.getRevisionId()); valueStore.forceEvictionOfValues(); valueStore.startTransaction(true); valueStore.commit(); + for (int i = 0; i < values.length; i++) { + Assert.assertEquals(LmdbValue.UNKNOWN_ID, valueStore.getId(values[i])); + Assert.assertTrue(valueStore.getValue(ids[i]) != null); + } + valueStore.startTransaction(true); - for (int i = 0; i < 30; i++) { - LmdbValue value = valueStore.createLiteral("This is a random literal:" + random.nextLong()); - values[i] = value; - valueStore.storeValue(value); + for (int i = 0; i < values.length; i++) { // this ID should have been reused - ids.remove(value.getInternalID()); + idsToGc.remove(valueStore.storeValue(values[i])); } valueStore.commit(); - assertEquals("IDs should have been reused", Collections.emptySet(), ids); + assertEquals("IDs should have been reused", Collections.emptySet(), idsToGc); } @Test diff --git a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailValidationException.java b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailValidationException.java index 24e50c2c61d..abee864a097 100644 --- a/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailValidationException.java +++ b/core/sail/shacl/src/main/java/org/eclipse/rdf4j/sail/shacl/ShaclSailValidationException.java @@ -25,6 +25,7 @@ public class ShaclSailValidationException extends SailException implements ValidationException { private final ValidationReport validationReport; + private Model cachedModel = null; ShaclSailValidationException(ValidationReport validationReport) { super("Failed SHACL validation"); @@ -36,6 +37,9 @@ public class ShaclSailValidationException extends SailException implements Valid */ @Override public Model validationReportAsModel() { + if (cachedModel != null) { + return cachedModel; + } Model model = getValidationReport().asModel(); model.setNamespace(RSX.NS); @@ -45,6 +49,8 @@ public Model validationReportAsModel() { model.setNamespace(RDF.NS); model.setNamespace(RDFS.NS); + cachedModel = model; + return model; }