diff --git a/nitrite-jackson-mapper/pom.xml b/nitrite-jackson-mapper/pom.xml index 19eac32ac..0753b3019 100644 --- a/nitrite-jackson-mapper/pom.xml +++ b/nitrite-jackson-mapper/pom.xml @@ -70,7 +70,12 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl test diff --git a/nitrite-jackson-mapper/src/test/resources/log4j2.xml b/nitrite-jackson-mapper/src/test/resources/log4j2.xml index ece1f583c..e5ec45775 100644 --- a/nitrite-jackson-mapper/src/test/resources/log4j2.xml +++ b/nitrite-jackson-mapper/src/test/resources/log4j2.xml @@ -14,17 +14,17 @@ ~ limitations under the License. --> - + - + - + diff --git a/nitrite-mvstore-adapter/pom.xml b/nitrite-mvstore-adapter/pom.xml index 7dd883cea..b3d43b473 100644 --- a/nitrite-mvstore-adapter/pom.xml +++ b/nitrite-mvstore-adapter/pom.xml @@ -70,7 +70,12 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl test diff --git a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java index dbb1fc5a2..f185d2dd6 100644 --- a/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java +++ b/nitrite-mvstore-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java @@ -21,6 +21,7 @@ import jakarta.xml.bind.annotation.XmlSchemaType; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.time.StopWatch; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -35,18 +36,18 @@ import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; +import static org.dizitart.no2.collection.UpdateOptions.updateOptions; +import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -109,6 +110,57 @@ public void stressTest() { assertEquals(counter, size); } + @Test + @Ignore + public void testIssue902() { + NitriteCollection nitriteCollection = db.getCollection("testIssue902"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "name"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "age"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "address"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "email"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "phone"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateOfBirth"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "company"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "balance"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "isActive"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "guid"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "index"); + + for (int i = 0; i < 10; i++) { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + for (int j = 0; j < 30000; j++) { + Document document = Document.createDocument(); + document.put("name", "name" + j); + document.put("age", j); + document.put("address", "address" + j); + document.put("email", "email" + j); + document.put("phone", "phone" + j); + document.put("dateOfBirth", "dateOfBirth" + j); + document.put("company", "company" + j); + document.put("balance", j); + document.put("isActive", true); + document.put("guid", UUID.randomUUID().toString()); + document.put("index", j); + nitriteCollection.insert(document); + } + stopWatch.stop(); + log.error("Time taken to insert 30000 records: " + stopWatch.getTime()); + } + + if (db.hasUnsavedChanges()) { + db.commit(); + } + + Document updatedDocument = Document.createDocument("unrelatedField", "unrelatedValue"); + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + nitriteCollection.update(where("balance").eq(200000), updatedDocument, updateOptions(false)); + stopWatch.stop(); + + log.error("Time taken to update 1 record: " + stopWatch.getTime()); + } + @Test public void testIssue41() { collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "number"); diff --git a/nitrite-mvstore-adapter/src/test/resources/log4j2.xml b/nitrite-mvstore-adapter/src/test/resources/log4j2.xml index ece1f583c..e5ec45775 100644 --- a/nitrite-mvstore-adapter/src/test/resources/log4j2.xml +++ b/nitrite-mvstore-adapter/src/test/resources/log4j2.xml @@ -14,17 +14,17 @@ ~ limitations under the License. --> - + - + - + diff --git a/nitrite-rocksdb-adapter/pom.xml b/nitrite-rocksdb-adapter/pom.xml index 97bf2ff2d..ad0bfd459 100644 --- a/nitrite-rocksdb-adapter/pom.xml +++ b/nitrite-rocksdb-adapter/pom.xml @@ -74,7 +74,12 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl test diff --git a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java index c1dca3c58..7d85df533 100644 --- a/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java +++ b/nitrite-rocksdb-adapter/src/test/java/org/dizitart/no2/integration/NitriteStressTest.java @@ -21,6 +21,7 @@ import jakarta.xml.bind.annotation.XmlSchemaType; import lombok.Data; import lombok.extern.slf4j.Slf4j; +import org.apache.commons.lang3.time.StopWatch; import org.dizitart.no2.Nitrite; import org.dizitart.no2.collection.Document; import org.dizitart.no2.collection.DocumentCursor; @@ -35,18 +36,18 @@ import org.dizitart.no2.repository.annotations.Id; import org.dizitart.no2.repository.annotations.Index; import org.dizitart.no2.repository.annotations.Indices; -import org.junit.After; -import org.junit.Before; -import org.junit.Rule; -import org.junit.Test; +import org.junit.*; import uk.co.jemos.podam.api.PodamFactory; import uk.co.jemos.podam.api.PodamFactoryImpl; import java.util.ArrayList; import java.util.List; import java.util.Random; +import java.util.UUID; import java.util.concurrent.atomic.AtomicLong; +import static org.dizitart.no2.collection.UpdateOptions.updateOptions; +import static org.dizitart.no2.filters.FluentFilter.where; import static org.dizitart.no2.integration.TestUtil.*; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertNotNull; @@ -108,6 +109,57 @@ public void stressTest() { assertEquals(counter, size); } + @Test + @Ignore + public void testIssue902() { + NitriteCollection nitriteCollection = db.getCollection("testIssue902"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "name"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "age"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "address"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "email"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "phone"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "dateOfBirth"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "company"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "balance"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "isActive"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.UNIQUE), "guid"); + nitriteCollection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "index"); + + for (int i = 0; i < 10; i++) { + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + for (int j = 0; j < 3000; j++) { + Document document = Document.createDocument(); + document.put("name", "name" + j); + document.put("age", j); + document.put("address", "address" + j); + document.put("email", "email" + j); + document.put("phone", "phone" + j); + document.put("dateOfBirth", "dateOfBirth" + j); + document.put("company", "company" + j); + document.put("balance", j); + document.put("isActive", true); + document.put("guid", UUID.randomUUID().toString()); + document.put("index", j); + nitriteCollection.insert(document); + } + stopWatch.stop(); + log.error("Time taken to insert 30000 records: " + stopWatch.getTime()); + } + + if (db.hasUnsavedChanges()) { + db.commit(); + } + + Document updatedDocument = Document.createDocument("unrelatedField", "unrelatedValue"); + StopWatch stopWatch = new StopWatch(); + stopWatch.start(); + nitriteCollection.update(where("balance").eq(200000), updatedDocument, updateOptions(false)); + stopWatch.stop(); + + log.error("Time taken to update 1 record: " + stopWatch.getTime()); + } + @Test public void testIssue41() { collection.createIndex(IndexOptions.indexOptions(IndexType.NON_UNIQUE), "number"); diff --git a/nitrite-rocksdb-adapter/src/test/resources/log4j2.xml b/nitrite-rocksdb-adapter/src/test/resources/log4j2.xml index ece1f583c..e5ec45775 100644 --- a/nitrite-rocksdb-adapter/src/test/resources/log4j2.xml +++ b/nitrite-rocksdb-adapter/src/test/resources/log4j2.xml @@ -14,17 +14,17 @@ ~ limitations under the License. --> - + - + - + diff --git a/nitrite-spatial/pom.xml b/nitrite-spatial/pom.xml index eabd9e157..5094d4da2 100644 --- a/nitrite-spatial/pom.xml +++ b/nitrite-spatial/pom.xml @@ -62,6 +62,21 @@ nitrite-mvstore-adapter test + + org.apache.logging.log4j + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl + test + + + org.apache.logging.log4j + log4j-core + test + diff --git a/nitrite-spatial/src/test/resources/log4j2.xml b/nitrite-spatial/src/test/resources/log4j2.xml new file mode 100644 index 000000000..e5ec45775 --- /dev/null +++ b/nitrite-spatial/src/test/resources/log4j2.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/nitrite-support/pom.xml b/nitrite-support/pom.xml index 62105d19e..130e42245 100644 --- a/nitrite-support/pom.xml +++ b/nitrite-support/pom.xml @@ -73,6 +73,21 @@ snakeyaml test + + org.apache.logging.log4j + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl + test + + + org.apache.logging.log4j + log4j-core + test + diff --git a/nitrite-support/src/test/resources/log4j2.xml b/nitrite-support/src/test/resources/log4j2.xml index ece1f583c..e5ec45775 100644 --- a/nitrite-support/src/test/resources/log4j2.xml +++ b/nitrite-support/src/test/resources/log4j2.xml @@ -14,17 +14,17 @@ ~ limitations under the License. --> - + - + - + diff --git a/nitrite/pom.xml b/nitrite/pom.xml index 923641bf1..2dbdd71cc 100644 --- a/nitrite/pom.xml +++ b/nitrite/pom.xml @@ -69,7 +69,12 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl test diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java index 918ed7832..0b17b1b37 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/NitriteCollection.java @@ -82,14 +82,13 @@ public interface NitriteCollection extends PersistentCollection { * @param documents other documents to insert in a batch. * @return the result of write operation. * @throws ValidationException if {@code document} is {@code null}. - * @throws InvalidIdException if the {@code _id} value contains non - * comparable type, i.e. + * @throws InvalidIdException if the {@code _id} value contains non-comparable type, i.e. * type that does not implement * {@link Comparable}. * @throws UniqueConstraintException if the value of {@code _id} value clashes * with the id * of another document in the collection. - * @throws UniqueConstraintException if a field of the document is indexed and + * @throws UniqueConstraintException if a field of the document is indexed, and * it violates the unique constraint in the * collection(if any). * @see NitriteId diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java index 31fece0a9..b705f4a3c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/DocumentIndexWriter.java @@ -64,15 +64,21 @@ void removeIndexEntry(Document document) { } } - void updateIndexEntry(Document oldDocument, Document newDocument) { + void updateIndexEntry(Document oldDocument, Document newDocument, Document updatedFields) { Collection indexEntries = indexOperations.listIndexes(); + // filter out the index which is not affected by the update if (indexEntries != null) { for (IndexDescriptor indexDescriptor : indexEntries) { - String indexType = indexDescriptor.getIndexType(); - NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); + Fields fields = indexDescriptor.getFields(); + + // if the index is affected by the update + if (DocumentUtils.isAffectedByUpdate(fields, updatedFields)) { + String indexType = indexDescriptor.getIndexType(); + NitriteIndexer nitriteIndexer = nitriteConfig.findIndexer(indexType); - removeIndexEntryInternal(indexDescriptor, oldDocument, nitriteIndexer); - writeIndexEntryInternal(indexDescriptor, newDocument, nitriteIndexer); + removeIndexEntryInternal(indexDescriptor, oldDocument, nitriteIndexer); + writeIndexEntryInternal(indexDescriptor, newDocument, nitriteIndexer); + } } } } diff --git a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java index 8a7f73118..3c37e67ee 100644 --- a/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java +++ b/nitrite/src/main/java/org/dizitart/no2/collection/operation/WriteOperations.java @@ -175,7 +175,7 @@ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) log.debug("Updated document with id {} in {}", nitriteId, nitriteMap.getName()); try { - documentIndexWriter.updateIndexEntry(oldDocument, processed); + documentIndexWriter.updateIndexEntry(oldDocument, processed, document); // if 'update' only contains id value, affected count = 0 if (document.size() > 0) { @@ -185,7 +185,7 @@ WriteResult update(Filter filter, Document update, UpdateOptions updateOptions) log.error("Error while writing index entry for document with id : {} in {}", nitriteId, nitriteMap.getName(), e); nitriteMap.put(nitriteId, oldDocument); - documentIndexWriter.updateIndexEntry(processed, oldDocument); + documentIndexWriter.updateIndexEntry(processed, oldDocument, document); throw e; } diff --git a/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java b/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java index 6ad241682..47742567c 100644 --- a/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java +++ b/nitrite/src/main/java/org/dizitart/no2/common/util/DocumentUtils.java @@ -78,6 +78,15 @@ public static FieldValues getValues(Document document, Fields fields) { return fieldValues; } + public static boolean isAffectedByUpdate(Fields fields, Document updatedFields) { + for (String field : fields.getFieldNames()) { + if (updatedFields.containsKey(field)) { + return true; + } + } + return false; + } + private static Document removeValues(Document document) { if (document == null) return null; Document newDoc = Document.createDocument(); diff --git a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java index 827dec075..42edb9745 100644 --- a/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java +++ b/nitrite/src/test/java/org/dizitart/no2/collection/operation/DocumentIndexWriterTest.java @@ -69,7 +69,7 @@ public void testUpdateIndexEntry() { doReturn(new UniqueIndexer()).when(nitriteConfig).findIndexer(IndexType.UNIQUE); doReturn(new InMemoryStore()).when(nitriteConfig).getNitriteStore(); - (new DocumentIndexWriter(nitriteConfig, indexOperations)).updateIndexEntry(createDocument("a", 1), createDocument("a", 2)); + (new DocumentIndexWriter(nitriteConfig, indexOperations)).updateIndexEntry(createDocument("a", 1), createDocument("a", 2), createDocument("a", 3)); verify(indexOperations).listIndexes(); } } diff --git a/nitrite/src/test/resources/log4j2.xml b/nitrite/src/test/resources/log4j2.xml index ece1f583c..e5ec45775 100644 --- a/nitrite/src/test/resources/log4j2.xml +++ b/nitrite/src/test/resources/log4j2.xml @@ -14,17 +14,17 @@ ~ limitations under the License. --> - + - + - + diff --git a/pom.xml b/pom.xml index c98464fa5..287436715 100644 --- a/pom.xml +++ b/pom.xml @@ -209,7 +209,13 @@ org.apache.logging.log4j - log4j-slf4j-impl + log4j-api + ${log4j.version} + test + + + org.apache.logging.log4j + log4j-slf4j2-impl ${log4j.version} test diff --git a/potassium-nitrite/pom.xml b/potassium-nitrite/pom.xml index 2ec6ed0ab..0df7d9025 100644 --- a/potassium-nitrite/pom.xml +++ b/potassium-nitrite/pom.xml @@ -68,6 +68,10 @@ org.jetbrains.kotlin kotlin-reflect + + org.jetbrains.kotlinx + kotlinx-serialization-json + org.projectlombok lombok @@ -105,8 +109,19 @@ test - org.jetbrains.kotlinx - kotlinx-serialization-json + org.apache.logging.log4j + log4j-api + test + + + org.apache.logging.log4j + log4j-slf4j2-impl + test + + + org.apache.logging.log4j + log4j-core + test diff --git a/potassium-nitrite/src/test/resources/log4j2.xml b/potassium-nitrite/src/test/resources/log4j2.xml new file mode 100644 index 000000000..e5ec45775 --- /dev/null +++ b/potassium-nitrite/src/test/resources/log4j2.xml @@ -0,0 +1,31 @@ + + + + + + + + + + + + + + + + + \ No newline at end of file