From 1bee9ef5678c9352abe24c2708c5ed9f5bcf09a5 Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Tue, 31 Oct 2017 17:09:19 -0400 Subject: [PATCH 1/7] update readme wording, example --- .gitignore | 1 + README.md | 30 ++++++------- .../com/upserve/uppend/AppendOnlyStore.java | 15 ++++++- .../upserve/uppend/FileAppendOnlyStore.java | 6 +++ src/main/java/com/upserve/uppend/Uppend.java | 9 +++- .../uppend/cli/benchmark/Benchmark.java | 3 +- .../uppend/AppendOnlyObjectStoreTest.java | 6 +-- .../com/upserve/uppend/DocExamplesTests.java | 45 +++++++++++++++++++ 8 files changed, 89 insertions(+), 26 deletions(-) create mode 100644 src/test/java/com/upserve/uppend/DocExamplesTests.java diff --git a/.gitignore b/.gitignore index 67bcc2f7..2d31ca1b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ .gradle/ build/ +tmp/ diff --git a/README.md b/README.md index ae48fd85..e89f669b 100644 --- a/README.md +++ b/README.md @@ -3,18 +3,9 @@ Uppend: an append-only, key-multivalue store [![Build Status](https://travis-ci.com/upserve/uppend.svg?token=***REMOVED***&branch=add_travis_yml)](https://travis-ci.com/upserve/uppend) [![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.upserve/uppend/badge.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.upserve%22%20AND%20a%3Auppend) -Uppend is an append-only, key-multivalue store, suitable for creating analytics -views from event streams. - -Benefits: - -* Optimized to be I/O constrained on modest hardware - -Tradeoffs: - -* Individual values are immutable -* Assumes a single writer process - +Uppend is an append-only, key-multivalue store which is suitable for streaming +event aggregation. It assumes a single writer process, and appended values are +immutable. Use --- @@ -37,10 +28,17 @@ compile 'com.upserve:uppend:1.0.0' Hello world: ```java -//import com.upserve.uppend.* -DB db = DBMaker.memoryDB().make(); -ConcurrentMap map = db.hashMap("map").make(); -map.put("something", "here"); +AppendOnlyStore db = Uppend.fileStore("tmp/uppend").build(); + +db.append("my-partition", "my-key", "value-1".getBytes()); +db.append("my-partition", "my-key", "value-2".getBytes()); + +db.flush(); + +String values = db.readSequential("my-partition", "my-key") + .map(String::new) + .collect(Collectors.joining(", ")); +// value-1, value-2 ``` Development diff --git a/src/main/java/com/upserve/uppend/AppendOnlyStore.java b/src/main/java/com/upserve/uppend/AppendOnlyStore.java index 6e169376..4ffd7f6e 100644 --- a/src/main/java/com/upserve/uppend/AppendOnlyStore.java +++ b/src/main/java/com/upserve/uppend/AppendOnlyStore.java @@ -27,15 +27,26 @@ public interface AppendOnlyStore extends AutoCloseable, Flushable { void flush(); /** - * Read byte arrays that have been stored under a given key + * Read byte arrays that have been stored under a given key in parallel * * @param partition the partition under which to retrieve * @param key the key under which to retrieve * @throws IllegalArgumentException if partition is invalid - * @return a stream of the stored byte arrays + * @return a parallel stream of the stored byte arrays */ Stream read(String partition, String key); + /** + * Read byte arrays that have been stored under a given key in the order + * they were stored in + * + * @param partition the partition under which to retrieve + * @param key the key under which to retrieve + * @throws IllegalArgumentException if partition is invalid + * @return a stream of the stored byte arrays in storage order + */ + Stream readSequential(String partition, String key); + /** * Enumerate the keys in the data store * diff --git a/src/main/java/com/upserve/uppend/FileAppendOnlyStore.java b/src/main/java/com/upserve/uppend/FileAppendOnlyStore.java index 708d0a2c..1a43cad1 100644 --- a/src/main/java/com/upserve/uppend/FileAppendOnlyStore.java +++ b/src/main/java/com/upserve/uppend/FileAppendOnlyStore.java @@ -74,6 +74,12 @@ public Stream read(String partition, String key) { .mapToObj(blobs::read); } + @Override + public Stream readSequential(String partition, String key) { + return blockValues(partition, key) + .mapToObj(blobs::read); + } + @Override public Stream keys(String partition) { return lookups.keys(partition); diff --git a/src/main/java/com/upserve/uppend/Uppend.java b/src/main/java/com/upserve/uppend/Uppend.java index 5228b284..21161c17 100644 --- a/src/main/java/com/upserve/uppend/Uppend.java +++ b/src/main/java/com/upserve/uppend/Uppend.java @@ -3,6 +3,7 @@ import com.upserve.uppend.cli.Cli; import java.io.*; +import java.nio.file.*; public final class Uppend { public static final String VERSION; @@ -19,8 +20,12 @@ public final class Uppend { private Uppend() { } - public static FileAppendOnlyStoreBuilder fileAppendOnlyStore() { - return new FileAppendOnlyStoreBuilder(); + public static FileAppendOnlyStoreBuilder fileStore(String path) { + return fileStore(Paths.get(path)); + } + + public static FileAppendOnlyStoreBuilder fileStore(Path path) { + return new FileAppendOnlyStoreBuilder().withDir(path); } public static void main(String ... args) throws Exception { diff --git a/src/main/java/com/upserve/uppend/cli/benchmark/Benchmark.java b/src/main/java/com/upserve/uppend/cli/benchmark/Benchmark.java index 84bb3f81..5f018cae 100644 --- a/src/main/java/com/upserve/uppend/cli/benchmark/Benchmark.java +++ b/src/main/java/com/upserve/uppend/cli/benchmark/Benchmark.java @@ -32,8 +32,7 @@ public Benchmark(BenchmarkMode mode, Path path, int maxPartitions, int maxKeys, log.warn("Location already exists: appending to {}", path); } - testInstance = new FileAppendOnlyStoreBuilder() - .withDir(path) + testInstance = Uppend.fileStore(path) .withLongLookupHashSize(hashSize) .withLongLookupWriteCacheSize(cachesize) .withFlushDelaySeconds(flushDelaySeconds) diff --git a/src/test/java/com/upserve/uppend/AppendOnlyObjectStoreTest.java b/src/test/java/com/upserve/uppend/AppendOnlyObjectStoreTest.java index 3fc51ab4..2bd4c34d 100644 --- a/src/test/java/com/upserve/uppend/AppendOnlyObjectStoreTest.java +++ b/src/test/java/com/upserve/uppend/AppendOnlyObjectStoreTest.java @@ -8,10 +8,8 @@ import java.util.Arrays; -import static org.junit.Assert.assertArrayEquals; -import static org.junit.Assert.assertEquals; -import static org.mockito.Mockito.verify; -import static org.mockito.Mockito.when; +import static org.junit.Assert.*; +import static org.mockito.Mockito.*; @RunWith(MockitoJUnitRunner.class) public class AppendOnlyObjectStoreTest { diff --git a/src/test/java/com/upserve/uppend/DocExamplesTests.java b/src/test/java/com/upserve/uppend/DocExamplesTests.java new file mode 100644 index 00000000..d27bf336 --- /dev/null +++ b/src/test/java/com/upserve/uppend/DocExamplesTests.java @@ -0,0 +1,45 @@ +package com.upserve.uppend; + +import com.upserve.uppend.util.SafeDeleting; +import org.junit.Test; + +import java.io.IOException; +import java.nio.file.Paths; +import java.util.stream.Collectors; + +import static org.junit.Assert.*; + +/** + * All snippets and examples from the docs should exist as tests here so that + * the build fails if they stop working. + * + * If you add a new snippet in the README, or the wiki, please also add it + * here, so that it will be continuously tested. + * + * If you update this file, please also update the corresponding document + * section. + */ +public class DocExamplesTests { + @Test + public void testReadme01() throws IOException { + SafeDeleting.removeTempPath(Paths.get("tmp/uppend-test")); + + // *** START SNIPPET *** + AppendOnlyStore db = Uppend.fileStore("tmp/uppend").build(); + + db.append("my-partition", "my-key", "value-1".getBytes()); + db.append("my-partition", "my-key", "value-2".getBytes()); + + db.flush(); + + String values = db.readSequential("my-partition", "my-key") + .map(String::new) + .collect(Collectors.joining(", ")); + // value-1, value-2 + // *** END SNIPPET *** + + assertEquals("value-1, value-2", values); + + SafeDeleting.removeTempPath(Paths.get("tmp/uppend-test")); + } +} From e1aa5ed0574e96192f571e4937388f7805d12185 Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Wed, 1 Nov 2017 08:32:11 -0400 Subject: [PATCH 2/7] change tmp dir in readme --- .gitignore | 1 - README.md | 2 +- src/test/java/com/upserve/uppend/DocExamplesTests.java | 6 +++--- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/.gitignore b/.gitignore index 2d31ca1b..67bcc2f7 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,2 @@ .gradle/ build/ -tmp/ diff --git a/README.md b/README.md index e89f669b..40a2fbcd 100644 --- a/README.md +++ b/README.md @@ -28,7 +28,7 @@ compile 'com.upserve:uppend:1.0.0' Hello world: ```java -AppendOnlyStore db = Uppend.fileStore("tmp/uppend").build(); +AppendOnlyStore db = Uppend.fileStore("build/tmp-db").build(); db.append("my-partition", "my-key", "value-1".getBytes()); db.append("my-partition", "my-key", "value-2".getBytes()); diff --git a/src/test/java/com/upserve/uppend/DocExamplesTests.java b/src/test/java/com/upserve/uppend/DocExamplesTests.java index d27bf336..7c58fc12 100644 --- a/src/test/java/com/upserve/uppend/DocExamplesTests.java +++ b/src/test/java/com/upserve/uppend/DocExamplesTests.java @@ -22,10 +22,10 @@ public class DocExamplesTests { @Test public void testReadme01() throws IOException { - SafeDeleting.removeTempPath(Paths.get("tmp/uppend-test")); + SafeDeleting.removeTempPath(Paths.get("build/tmp-db")); // *** START SNIPPET *** - AppendOnlyStore db = Uppend.fileStore("tmp/uppend").build(); + AppendOnlyStore db = Uppend.fileStore("build/tmp-db").build(); db.append("my-partition", "my-key", "value-1".getBytes()); db.append("my-partition", "my-key", "value-2".getBytes()); @@ -40,6 +40,6 @@ public void testReadme01() throws IOException { assertEquals("value-1, value-2", values); - SafeDeleting.removeTempPath(Paths.get("tmp/uppend-test")); + SafeDeleting.removeTempPath(Paths.get("build/tmp-db")); } } From f9e89a047510b6f9e4363c4da66cb6df66ef6425 Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Wed, 1 Nov 2017 09:51:19 -0400 Subject: [PATCH 3/7] add coverage reports; anticipate oss in badges --- .travis.yml | 2 ++ README.md | 5 +++-- build.gradle | 10 ++++++++++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index d5efb108..c43f32da 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,3 +3,5 @@ sudo: false jdk: - oraclejdk8 script: ./gradlew clean build +after_success: + - bash <(curl -s https://codecov.io/bash) \ No newline at end of file diff --git a/README.md b/README.md index 40a2fbcd..f5b3e678 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,8 @@ Uppend: an append-only, key-multivalue store ============================================ -[![Build Status](https://travis-ci.com/upserve/uppend.svg?token=***REMOVED***&branch=add_travis_yml)](https://travis-ci.com/upserve/uppend) -[![Maven Central](https://maven-badges.herokuapp.com/maven-central/com.upserve/uppend/badge.svg)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.upserve%22%20AND%20a%3Auppend) +[![Build Status](https://img.shields.io/travis/upserve/uppend/master.svg?style=flat-square)](https://travis-ci.org/upserve/uppend) +[![Release Artifact](https://img.shields.io/maven-central/v/com.upserve/uppend.svg?style=flat-square)](https://search.maven.org/#search%7Cga%7C1%7Cg%3A%22com.upserve%22%20AND%20a%3Auppend) +[![Test Coverage](https://img.shields.io/codecov/c/github/upserveuppend/master.svg?style=flat-square)](https://codecov.io/github/upserve/uppend?branch=master) Uppend is an append-only, key-multivalue store which is suitable for streaming event aggregation. It assumes a single writer process, and appended values are diff --git a/build.gradle b/build.gradle index 24a9f5b1..a886b5d7 100644 --- a/build.gradle +++ b/build.gradle @@ -19,6 +19,7 @@ gradleLint.rules += 'unused-dependency' apply plugin: 'java' apply plugin: 'maven' +apply plugin: 'jacoco' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -73,3 +74,12 @@ task fatJar(type: Jar) { from { configurations.compile.collect { it.isDirectory() ? it : zipTree(it) } } with jar } + +jacocoTestReport { + reports { + xml.enabled = true + html.enabled = true + } +} + +check.dependsOn jacocoTestReport From 2d6a3c0eefea0fca4b8a90adbc6874ca3eb1494d Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Mon, 6 Nov 2017 10:17:51 -0500 Subject: [PATCH 4/7] read from memory for write-cached lookups; flush blocks on dirty read --- README.md | 2 -- .../java/com/upserve/uppend/BlockedLongs.java | 18 ++++++++++++++- .../com/upserve/uppend/lookup/LongLookup.java | 22 +++++++++++++++++-- .../com/upserve/uppend/lookup/LookupData.java | 12 ++++++++++ .../upserve/uppend/AppendOnlyStoreTest.java | 13 ----------- .../com/upserve/uppend/DocExamplesTests.java | 2 -- 6 files changed, 49 insertions(+), 20 deletions(-) diff --git a/README.md b/README.md index 26822d01..e02b25f3 100644 --- a/README.md +++ b/README.md @@ -34,8 +34,6 @@ AppendOnlyStore db = Uppend.fileStore("build/tmp-db").build(); db.append("my-partition", "my-key", "value-1".getBytes()); db.append("my-partition", "my-key", "value-2".getBytes()); -db.flush(); - String values = db.readSequential("my-partition", "my-key") .map(String::new) .collect(Collectors.joining(", ")); diff --git a/src/main/java/com/upserve/uppend/BlockedLongs.java b/src/main/java/com/upserve/uppend/BlockedLongs.java index a8758fe3..3b02de53 100644 --- a/src/main/java/com/upserve/uppend/BlockedLongs.java +++ b/src/main/java/com/upserve/uppend/BlockedLongs.java @@ -8,6 +8,7 @@ import java.nio.channels.FileChannel; import java.nio.file.*; import java.util.Arrays; +import java.util.concurrent.atomic.AtomicBoolean; import java.util.function.Supplier; import java.util.stream.LongStream; @@ -29,6 +30,8 @@ public class BlockedLongs implements AutoCloseable, Flushable { private final FileChannel blocksPos; private final MappedByteBuffer posBuf; + private final AtomicBoolean outDirty; + public BlockedLongs(Path file, int valuesPerBlock) { this.file = file; @@ -74,6 +77,8 @@ public BlockedLongs(Path file, int valuesPerBlock) { } catch (IOException e) { throw new UncheckedIOException("unable to init blocks pos file: " + posFile, e); } + + outDirty = new AtomicBoolean(false); } public synchronized long allocate() { @@ -81,6 +86,7 @@ public synchronized long allocate() { synchronized (posBuf) { long pos = getPos(); putPos(pos + blockSize); + outDirty.set(true); return pos; } } @@ -106,12 +112,16 @@ public synchronized void append(long pos, long val) { writeLong(valuePos, val); writeLong(pos, numValuesLong + 1); } + outDirty.set(true); } log.trace("appended value {} to {} at {}", val, file, pos); } public LongStream values(long pos) { log.trace("streaming values from {} at {}", file, pos); + if (outDirty.get()) { + flush(); + } if (pos >= getPos()) { return LongStream.empty(); } @@ -148,6 +158,9 @@ public LongStream values(long pos) { public long lastValue(long pos) { log.trace("reading last value from {} at {}", file, pos); + if (outDirty.get()) { + flush(); + } if (pos >= getPos()) { return -1; } @@ -173,12 +186,13 @@ public long lastValue(long pos) { } } - public void clear() { + public synchronized void clear() { log.debug("clearing {}", file); try { blocks.truncate(0); putPos(0); Arrays.fill(pages, null); + outDirty.set(true); } catch (IOException e) { throw new UncheckedIOException("unable to clear", e); } @@ -195,6 +209,7 @@ public synchronized void close() throws Exception { blocks.close(); posBuf.force(); blocksPos.close(); + outDirty.set(false); } @Override @@ -206,6 +221,7 @@ public synchronized void flush() { } } posBuf.force(); + outDirty.set(false); } private ByteBuffer readBlock(long pos) { diff --git a/src/main/java/com/upserve/uppend/lookup/LongLookup.java b/src/main/java/com/upserve/uppend/lookup/LongLookup.java index a06964a0..02e87bb0 100644 --- a/src/main/java/com/upserve/uppend/lookup/LongLookup.java +++ b/src/main/java/com/upserve/uppend/lookup/LongLookup.java @@ -33,7 +33,6 @@ public class LongLookup implements AutoCloseable, Flushable { public static final int DEFAULT_WRITE_CACHE_SIZE = DEFAULT_HASH_SIZE * 1; private final Path dir; - private final int hashSize; private final int hashBytes; private final int hashFinalByteMask; private final HashFunction hashFunction; @@ -62,7 +61,6 @@ public LongLookup(Path dir, int hashSize, int writeCacheSize) { throw new UncheckedIOException("unable to mkdirs: " + dir, e); } - this.hashSize = hashSize; String hashBinaryString = Integer.toBinaryString(hashSize - 1); hashBytes = (hashBinaryString.length() + 7) / 8; hashFinalByteMask = (1 << (hashBinaryString.length() % 8)) - 1; @@ -95,11 +93,25 @@ protected synchronized boolean removeEldestEntry(Map.Entry eld }; } + /** + * Get the value associated with the given partition and key + * + * @param partition the partition to look up + * @param key the key to look up + * @return the value for the partition and key, or -1 if not found + */ public long get(String partition, String key) { validatePartition(partition); LookupKey lookupKey = new LookupKey(key); Path lenPath = hashAndLengthPath(partition, lookupKey); + + LookupData data = loadFromWriteCacheIfExists(lenPath); + if (data != null) { + long value = data.get(lookupKey); + return value == Long.MIN_VALUE ? -1 : value; + } + Path metaPath = lenPath.resolve("meta"); if (!Files.exists(metaPath)) { log.trace("no metadata for key {} at path {}", key, metaPath); @@ -129,6 +141,12 @@ private LookupData loadFromWriteCache(Path lenPath) { } } + private LookupData loadFromWriteCacheIfExists(Path lenPath) { + synchronized (writeCache) { + return writeCache.get(lenPath); + } + } + public long putIfNotExists(String partition, String key, LongSupplier allocateLongFunc) { validatePartition(partition); LookupKey lookupKey = new LookupKey(key); diff --git a/src/main/java/com/upserve/uppend/lookup/LookupData.java b/src/main/java/com/upserve/uppend/lookup/LookupData.java index 54b6e8bc..43fbb4ad 100644 --- a/src/main/java/com/upserve/uppend/lookup/LookupData.java +++ b/src/main/java/com/upserve/uppend/lookup/LookupData.java @@ -1,6 +1,7 @@ package com.upserve.uppend.lookup; import com.upserve.uppend.util.*; +import it.unimi.dsi.fastutil.Function; import it.unimi.dsi.fastutil.objects.*; import lombok.extern.slf4j.Slf4j; @@ -59,6 +60,17 @@ public LookupData(int keyLength, Path path, Path metadataPath) { isClosed = new AtomicBoolean(false); } + /** + * Return the value associated with the given key + * + * @param key the key to look up + * @return the value associated with the key, or {@code Long.MIN_VALUE} if + * the key was not found + */ + public synchronized long get(LookupKey key) { + return mem.getLong(key); + } + public synchronized void put(LookupKey key, long value) { log.trace("putting {}={} in {}", key, value, path); long existingValue = mem.put(key, value); diff --git a/src/test/java/com/upserve/uppend/AppendOnlyStoreTest.java b/src/test/java/com/upserve/uppend/AppendOnlyStoreTest.java index cea00987..9dc9ff12 100644 --- a/src/test/java/com/upserve/uppend/AppendOnlyStoreTest.java +++ b/src/test/java/com/upserve/uppend/AppendOnlyStoreTest.java @@ -60,7 +60,6 @@ public void testClear() throws Exception { byte[] bytes = genBytes(12); store.append("partition", key, bytes); - flush(); store.clear(); assertEquals(0, store.read("partition", key).count()); } @@ -98,7 +97,6 @@ public void fillTheCache() { public void testReadStream() throws Exception { store.append("partition", "stream", "bar".getBytes()); store.append("partition", "stream", "baz".getBytes()); - flush(); assertArrayEquals(new String[] { "bar", "baz" }, store.read("partition", "stream").map(String::new).sorted().toArray(String[]::new)); } @@ -107,7 +105,6 @@ public void testReadLast() throws Exception { store.append("partition", "stream", "foo".getBytes()); store.append("partition", "stream", "bar".getBytes()); store.append("partition", "stream", "baz".getBytes()); - flush(); byte[] valueBytes = store.readLast("partition", "stream"); assertNotNull(valueBytes); String value = new String(valueBytes); @@ -119,7 +116,6 @@ public void testMultiPartition() throws Exception { store.append("partition", "key", "bar".getBytes()); store.append("partition_bar", "key", "baz".getBytes()); store.append("partition2", "key", "bap".getBytes()); - flush(); assertArrayEquals(new String[] { "bar" }, store.read("partition", "key").map(String::new).toArray(String[]::new)); assertArrayEquals(new String[] { "baz" }, store.read("partition_bar", "key").map(String::new).toArray(String[]::new)); assertArrayEquals(new String[] { "bap" }, store.read("partition2", "key").map(String::new).toArray(String[]::new)); @@ -296,13 +292,4 @@ private byte[] genBytes(int len){ new Random().nextBytes(bytes); return bytes; } - - private void flush() throws Exception { - try { - store.close(); - } catch (Exception e){ - throw new AssertionError("close should not raise: {}", e); - } - store = newStore(); - } } diff --git a/src/test/java/com/upserve/uppend/DocExamplesTests.java b/src/test/java/com/upserve/uppend/DocExamplesTests.java index 7c58fc12..3fd04984 100644 --- a/src/test/java/com/upserve/uppend/DocExamplesTests.java +++ b/src/test/java/com/upserve/uppend/DocExamplesTests.java @@ -30,8 +30,6 @@ public void testReadme01() throws IOException { db.append("my-partition", "my-key", "value-1".getBytes()); db.append("my-partition", "my-key", "value-2".getBytes()); - db.flush(); - String values = db.readSequential("my-partition", "my-key") .map(String::new) .collect(Collectors.joining(", ")); From 79c21f4d151b1d01ef82ff2290a1c7968a17e865 Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Mon, 6 Nov 2017 10:40:51 -0500 Subject: [PATCH 5/7] put version at 0.0.1 --- README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index e02b25f3..131b844f 100644 --- a/README.md +++ b/README.md @@ -17,13 +17,13 @@ Maven: com.upserve uppend - 1.0.0 + 0.0.1 ``` Gradle: ```gradle -compile 'com.upserve:uppend:1.0.0' +compile 'com.upserve:uppend:0.0.1' ``` Hello world: From bdbac77cf2c3eece0504d544e0bdcfa5a6b84e5e Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Mon, 6 Nov 2017 21:02:13 -0500 Subject: [PATCH 6/7] add nexus publishing --- build.gradle | 58 ++++++++++++++++++- .../com/upserve/uppend/AppendOnlyStore.java | 3 + 2 files changed, 60 insertions(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index a886b5d7..27af7837 100644 --- a/build.gradle +++ b/build.gradle @@ -1,3 +1,12 @@ +buildscript { + repositories { + jcenter() + } + dependencies { + classpath 'com.bmuschko:gradle-nexus-plugin:2.3.1' + } +} + plugins { id 'com.palantir.git-version' version '0.9.1' id 'nebula.lint' version '6.7.0' @@ -9,7 +18,7 @@ version gitVersion() group 'com.upserve' -description = """Uppend: fast, append-only key-value store""" +description = """Uppend: fast, append-only key-multivalue store""" task wrapper(type: Wrapper) { gradleVersion = '3.3' @@ -20,6 +29,7 @@ gradleLint.rules += 'unused-dependency' apply plugin: 'java' apply plugin: 'maven' apply plugin: 'jacoco' +apply plugin: 'com.bmuschko.nexus' sourceCompatibility = 1.8 targetCompatibility = 1.8 @@ -83,3 +93,49 @@ jacocoTestReport { } check.dependsOn jacocoTestReport + +modifyPom { + project { + name 'Uppend' + description 'Uppend is an append-only, key-multivalue store.' + url 'https://github.com/upserve/uppend' + inceptionYear '2017' + + scm { + url 'https://github.com/upserve/uppend' + connection 'scm:https://upserve@github.com/upserve/uppend.git' + developerConnection 'scm:git://github.com/upserve/uppend.git' + } + + licenses { + license { + name 'The MIT License' + url 'https://opensource.org/licenses/MIT' + distribution 'repo' + } + } + + developers { + developer { + id 'bfulton' + name 'Bright Fulton' + url 'https://github.com/bfulton' + } + developer { + id 'dstuebe' + name 'David Stuebe' + url 'https://github.com/dstuebe' + } + developer { + id 'jazzdan' + name 'Dan Miller' + url 'https://github.com/jazzdan' + } + developer { + id 'kbarrette' + name 'Keith Barrette' + url 'https://github.com/kbarrette' + } + } + } +} diff --git a/src/main/java/com/upserve/uppend/AppendOnlyStore.java b/src/main/java/com/upserve/uppend/AppendOnlyStore.java index b4f869d8..d25347db 100644 --- a/src/main/java/com/upserve/uppend/AppendOnlyStore.java +++ b/src/main/java/com/upserve/uppend/AppendOnlyStore.java @@ -51,6 +51,9 @@ public interface AppendOnlyStore extends AutoCloseable, Flushable { /** * Read the last byte array that was stored under a given key * + * @param partition the partition under which to retrieve + * @param key the key under which to retrieve + * @throws IllegalArgumentException if partition is invalid * @return the stored byte array, or null if none */ byte[] readLast(String partition, String key); From e0652ce38efd76e87e37d9486247d605fd2a5882 Mon Sep 17 00:00:00 2001 From: Bright Fulton Date: Mon, 6 Nov 2017 21:07:57 -0500 Subject: [PATCH 7/7] fix newline --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index c43f32da..ebb7cd22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,4 +4,4 @@ jdk: - oraclejdk8 script: ./gradlew clean build after_success: - - bash <(curl -s https://codecov.io/bash) \ No newline at end of file + - bash <(curl -s https://codecov.io/bash)