diff --git a/README.md b/README.md index a46e269..fbdfd4f 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,17 @@ PalDB is an embeddable persistent key-value store with very fast read performanc PalDB's JAR is only 65K and has a single dependency (snappy, which isn't mandatory). It's also very easy to use with just a few configuration parameters. +**This is separate evolution of original PalDB.** + +Improvements from PalDB 1.0.2 +------------------- +- StoreReader is now fully thread-safe without any performance decrease. +- StoreReader and StoreWriter can be used with generics (StoreReader and StoreWriter) +- Typesafe ``PalDBConfigBuilder`` for easier configuration +- There are no limits on how many keys you can store +- Duplicates could be optionally allowed +- Bloom filters could be enabled for even better read performance in some cases + Performance ----------- diff --git a/pom.xml b/pom.xml index 2045845..a049446 100644 --- a/pom.xml +++ b/pom.xml @@ -6,7 +6,7 @@ net.soundvibe paldb - 2.0.1 + 2.0.2 jar paldb Embeddable persistent write-once key-value store diff --git a/src/main/java/com/linkedin/paldb/api/Serializer.java b/src/main/java/com/linkedin/paldb/api/Serializer.java index 064e7c5..d10f32e 100644 --- a/src/main/java/com/linkedin/paldb/api/Serializer.java +++ b/src/main/java/com/linkedin/paldb/api/Serializer.java @@ -29,9 +29,9 @@ * configuration.registerSerializer(new PointSerializer()); * * - * @param class type + * @param class type */ -public interface Serializer extends Serializable { +public interface Serializer extends Serializable { /** * Writes the instance input to the data output. @@ -39,7 +39,7 @@ public interface Serializer extends Serializable { * @param input instance * @throws IOException if an io error occurs */ - void write(DataOutput dataOutput, K input) throws IOException; + void write(DataOutput dataOutput, T input) throws IOException; /** * Reads the data input and creates the instance. @@ -48,7 +48,7 @@ public interface Serializer extends Serializable { * @return new instance of type K. * @throws IOException if an io error occurs */ - K read(DataInput dataInput) throws IOException; + T read(DataInput dataInput) throws IOException; - Class serializedClass(); + Class serializedClass(); } diff --git a/src/main/java/com/linkedin/paldb/impl/StorageWriter.java b/src/main/java/com/linkedin/paldb/impl/StorageWriter.java index c23c17d..a890a5b 100644 --- a/src/main/java/com/linkedin/paldb/impl/StorageWriter.java +++ b/src/main/java/com/linkedin/paldb/impl/StorageWriter.java @@ -361,7 +361,6 @@ private File buildIndex(int keyLength, BloomFilter bloomFilter) throws IOExcepti } finally { Arrays.fill(indexBuffers, null); indexBuffers = null; - System.gc(); if (tempIndexFile.delete()) { log.info("Temporary index file {} has been deleted", tempIndexFile.getName()); } diff --git a/src/test/java/com/linkedin/paldb/impl/TestStore.java b/src/test/java/com/linkedin/paldb/impl/TestStore.java index 939bac5..8aa3221 100644 --- a/src/test/java/com/linkedin/paldb/impl/TestStore.java +++ b/src/test/java/com/linkedin/paldb/impl/TestStore.java @@ -535,6 +535,39 @@ void should_allow_duplicates() { } } + @Test + void should_not_allow_put_null_keys() { + try (StoreWriter writer = PalDB.createWriter(storeFile)) { + assertThrows(NullPointerException.class, () -> writer.put((String)null, EMPTY_VALUE)); + assertThrows(NullPointerException.class, () -> writer.putAll((String[])null, new byte[][]{})); + } + } + + @Test + void should_not_allow_getting_null_keys() { + try (StoreWriter writer = PalDB.createWriter(storeFile)) { + writer.put("any value", EMPTY_VALUE); + } + + try (StoreReader reader = PalDB.createReader(storeFile)) { + assertThrows(NullPointerException.class, () -> reader.get(null)); + } + } + + @Test + void should_not_find_when_bloom_filter_enabled() { + var config = PalDBConfigBuilder.create() + .withEnableBloomFilter(true).build(); + try (StoreWriter writer = PalDB.createWriter(storeFile, config)) { + writer.put("abc", EMPTY_VALUE); + } + + try (StoreReader reader = PalDB.createReader(storeFile, config)) { + assertNull(reader.get("foo")); + assertArrayEquals(EMPTY_VALUE, reader.get("abc")); + } + } + private static final byte[] EMPTY_VALUE = new byte[0]; @Test diff --git a/src/test/java/com/linkedin/paldb/utils/BloomFilterTest.java b/src/test/java/com/linkedin/paldb/utils/BloomFilterTest.java index 16df3e2..95bb56d 100644 --- a/src/test/java/com/linkedin/paldb/utils/BloomFilterTest.java +++ b/src/test/java/com/linkedin/paldb/utils/BloomFilterTest.java @@ -77,6 +77,14 @@ void should_be_equal() { assertEquals(sut1, sut2); } + @Test + void should_return_same_bits() { + var bits = new long[Math.max(1, (int) Math.ceil((double) 6235225 / Long.SIZE))]; + var sut = new BloomFilter(4, 6235225, bits); + + assertArrayEquals(bits, sut.bits()); + } + @Test void correctness() { System.out.println("Testing correctness.\n"+