use of org.apache.bookkeeper.api.kv.result.KeyValue in project bookkeeper by apache.
the class TableWriteView method rDelete.
default CompletableFuture<KeyValue<K, V>> rDelete(K key, long expectedRevision) {
Txn<K, V> txn = txn(key);
txn.If(opFactory().compareModRevision(CompareResult.EQUAL, key, expectedRevision)).Then(opFactory().newDelete(key, Options.deleteAndGet()));
return txn.commit().thenCompose(result -> {
try {
if (result.isSuccess()) {
DeleteResult<K, V> deleteResult = (DeleteResult<K, V>) result.results().get(0);
if (deleteResult.prevKvs().isEmpty()) {
return FutureUtils.value(null);
} else {
List<KeyValue<K, V>> prevKvs = deleteResult.getPrevKvsAndClear();
return FutureUtils.value(prevKvs.get(0));
}
} else {
return FutureUtils.exception(new KvApiException(Code.BAD_REVISION, "Failed to rDelete key " + key + " (mod_rev = " + expectedRevision + ")"));
}
} finally {
result.close();
}
});
}
use of org.apache.bookkeeper.api.kv.result.KeyValue in project bookkeeper by apache.
the class TestMVCCAsyncBytesStoreImpl method testPutGetDeleteRanges.
@Test
public void testPutGetDeleteRanges() throws Exception {
this.streamName = "test-put-kvs";
StateStoreSpec spec = initSpec(streamName);
result(store.init(spec));
int numPairs = 100;
List<PutResult<byte[], byte[]>> kvs = writeKVs(numPairs, true);
assertEquals(numPairs, kvs.size());
for (PutResult<byte[], byte[]> kv : kvs) {
assertEquals(Code.OK, kv.code());
assertNull(kv.prevKv());
kv.close();
}
verifyRange(20, 70, 2, 2, 0);
List<KeyValue<byte[], byte[]>> prevKvs = result(store.deleteRange(getKey(20), getKey(70)));
assertNotNull(prevKvs);
verifyRecords(prevKvs, 20, 70, 2, 2, 0);
prevKvs.forEach(KeyValue::close);
prevKvs = result(store.range(getKey(20), getKey(70)));
assertTrue(prevKvs.isEmpty());
}
use of org.apache.bookkeeper.api.kv.result.KeyValue in project bookkeeper by apache.
the class TestMVCCAsyncBytesStoreImpl method testBasicOps.
@Test
public void testBasicOps() throws Exception {
this.streamName = "test-basic-ops";
StateStoreSpec spec = initSpec(streamName);
result(store.init(spec));
// normal put
{
assertNull(result(store.get(getKey(0))));
result(store.put(getKey(0), getValue(0)));
assertArrayEquals(getValue(0), result(store.get(getKey(0))));
}
// putIfAbsent
{
// failure case
assertArrayEquals(getValue(0), result(store.putIfAbsent(getKey(0), getValue(99))));
assertArrayEquals(getValue(0), result(store.get(getKey(0))));
// success case
byte[] key1 = getKey(1);
assertNull(result(store.putIfAbsent(key1, getValue(1))));
assertArrayEquals(getValue(1), result(store.get(key1)));
}
// vPut
{
// key-not-found case
int key = 2;
int initialVal = 2;
int casVal = 99;
try {
result(store.vPut(getKey(key), getValue(initialVal), 100L));
fail("key2 doesn't exist yet");
} catch (MVCCStoreException e) {
assertEquals(Code.KEY_NOT_FOUND, e.getCode());
}
// vPut(k, v, -1L)
try {
result(store.vPut(getKey(key), getValue(initialVal), -1L));
fail("key2 doesn't exist yet");
} catch (MVCCStoreException e) {
assertEquals(Code.KEY_NOT_FOUND, e.getCode());
}
// put(key2, v)
assertNull(result(store.putIfAbsent(getKey(key), getValue(initialVal))));
// vPut(key2, v, 0)
assertEquals(1L, result(store.vPut(getKey(key), getValue(casVal), 0)).longValue());
assertArrayEquals(getValue(casVal), result(store.get(getKey(key))));
}
// rPut
{
// key-not-found case
int key = 3;
int initialVal = 3;
int casVal = 99;
try {
result(store.rPut(getKey(key), getValue(initialVal), 100L));
fail("key2 doesn't exist yet");
} catch (MVCCStoreException e) {
assertEquals(Code.KEY_NOT_FOUND, e.getCode());
}
// vPut(k, v, -1L)
try {
result(store.rPut(getKey(key), getValue(initialVal), -1L));
fail("key2 doesn't exist yet");
} catch (MVCCStoreException e) {
assertEquals(Code.KEY_NOT_FOUND, e.getCode());
}
// put(key2, v)
assertNull(result(store.putIfAbsent(getKey(key), getValue(initialVal))));
KeyValue<byte[], byte[]> kv = result(store.getKeyValue(getKey(key)));
long revision = kv.modifiedRevision();
assertArrayEquals(getValue(initialVal), kv.value());
// vPut(key2, v, 0)
assertEquals(revision + 1, result(store.rPut(getKey(key), getValue(casVal), revision)).longValue());
assertArrayEquals(getValue(casVal), result(store.get(getKey(key))));
}
// delete(k)
{
// key not found
assertNull(result(store.delete(getKey(99))));
// key exists
int key = 0;
assertArrayEquals(getValue(key), result(store.get(getKey(key))));
assertArrayEquals(getValue(key), result(store.delete(getKey(key))));
assertNull(result(store.get(getKey(key))));
}
// delete(k, v)
{
// key not found
assertNull(result(store.delete(getKey(99))));
// key exists
int key = 1;
assertArrayEquals(getValue(key), result(store.get(getKey(key))));
assertFalse(result(store.delete(getKey(key), getValue(99))));
assertArrayEquals(getValue(key), result(store.get(getKey(key))));
assertTrue(result(store.delete(getKey(key), getValue(key))));
assertNull(result(store.get(getKey(key))));
}
// vDelete
{
int key = 2;
@Cleanup KeyValue<byte[], byte[]> kv = result(store.getKeyValue(getKey(key)));
long expectedVersion = kv.version();
try {
result(store.vDelete(getKey(key), expectedVersion + 1));
fail("should fail to delete a key with wrong version");
} catch (MVCCStoreException e) {
assertEquals(Code.BAD_REVISION, e.getCode());
}
// vDelete(k, -1L)
try {
result(store.vDelete(getKey(key), -1L));
fail("Should fail to delete a key with version(-1)");
} catch (MVCCStoreException e) {
assertEquals(Code.BAD_REVISION, e.getCode());
}
// vDelete(key2, version)
@Cleanup KeyValue<byte[], byte[]> deletedKv = (result(store.vDelete(getKey(key), expectedVersion)));
assertNotNull(deletedKv);
assertEquals(kv.createRevision(), deletedKv.createRevision());
assertEquals(kv.modifiedRevision(), deletedKv.modifiedRevision());
assertEquals(kv.version(), deletedKv.version());
assertArrayEquals(kv.value(), deletedKv.value());
assertNull(result(store.get(getKey(key))));
}
// rPut
{
int key = 3;
@Cleanup KeyValue<byte[], byte[]> kv = result(store.getKeyValue(getKey(key)));
long expectedRevision = kv.modifiedRevision();
try {
result(store.rDelete(getKey(key), expectedRevision + 1));
fail("should fail to delete a key with wrong revision");
} catch (MVCCStoreException e) {
assertEquals(Code.BAD_REVISION, e.getCode());
}
// rDelete(k, -1L)
try {
result(store.rDelete(getKey(key), -1L));
fail("Should fail to delete a key with revision(-1)");
} catch (MVCCStoreException e) {
assertEquals(Code.BAD_REVISION, e.getCode());
}
// rDelete(key2, revision)
@Cleanup KeyValue<byte[], byte[]> deletedKv = (result(store.rDelete(getKey(key), expectedRevision)));
assertNotNull(deletedKv);
assertEquals(kv.createRevision(), deletedKv.createRevision());
assertEquals(kv.modifiedRevision(), deletedKv.modifiedRevision());
assertEquals(kv.version(), deletedKv.version());
assertArrayEquals(kv.value(), deletedKv.value());
assertNull(result(store.get(getKey(key))));
}
// increment failure
{
int ki = 3;
byte[] key = getKey(ki);
result(store.put(key, getValue(ki)));
try {
result(store.increment(key, 100L));
fail("Can't increment a non-number key");
} catch (MVCCStoreException e) {
assertEquals(Code.ILLEGAL_OP, e.getCode());
}
}
// increment success
{
int ki = 4;
byte[] key = getKey(ki);
for (int i = 0; i < 5; i++) {
result(store.increment(key, 100L));
@Cleanup KeyValue<byte[], byte[]> kv = result(store.getKeyValue(key));
assertEquals(100L * (i + 1), kv.numberValue());
}
}
}
use of org.apache.bookkeeper.api.kv.result.KeyValue in project bookkeeper by apache.
the class MVCCStoreImpl method processRange.
synchronized RangeResult<K, V> processRange(RangeOp<K, V> rangeOp) {
checkStoreOpen();
// parameters
final K key = rangeOp.key();
final K endKey = rangeOp.option().endKey();
// result
final RangeResultImpl<K, V> result = resultFactory.newRangeResult(-1L);
// raw key
byte[] rawKey = (null != key) ? keyCoder.encode(key) : NULL_START_KEY;
if (null == endKey) {
// point lookup
MVCCRecord record = getKeyRecord(key, rawKey);
try {
if (null == record || !record.test(rangeOp.option())) {
result.count(0);
result.kvs(Collections.emptyList());
} else {
result.count(1);
result.kvs(Lists.newArrayList(record.asKVRecord(recordFactory, key, valCoder)));
}
result.more(false);
result.code(Code.OK);
return result;
} finally {
if (null != record) {
record.recycle();
}
}
}
byte[] rawEndKey = (null != endKey) ? keyCoder.encode(endKey) : NULL_END_KEY;
Pair<byte[], byte[]> realRange = getRealRange(rawKey, rawEndKey);
rawKey = realRange.getLeft();
rawEndKey = realRange.getRight();
// range lookup
List<byte[]> keys = Lists.newArrayList();
List<MVCCRecord> records = Lists.newArrayList();
MutableLong numKvs = new MutableLong(0L);
try {
boolean hasMore = getKeyRecords(rawKey, rawEndKey, keys, records, numKvs, rangeOp.option(), rangeOp.option().limit(), false);
List<KeyValue<K, V>> kvs = toKvs(keys, records);
result.code(Code.OK);
result.kvs(kvs);
result.count(kvs.size());
result.more(hasMore);
} finally {
records.forEach(MVCCRecord::recycle);
}
return result;
}
use of org.apache.bookkeeper.api.kv.result.KeyValue in project bookkeeper by apache.
the class MVCCAsyncStore method rDelete.
@Override
default CompletableFuture<KeyValue<K, V>> rDelete(K k, long expectedRevision) {
TxnOp<K, V> op = getOpFactory().newTxn().If(newCompareModRevision(CompareResult.EQUAL, k, expectedRevision)).Then(getOpFactory().newDelete(k, Options.deleteAndGet())).build();
return txn(op).thenCompose(result -> {
try {
Code code = result.code();
if (Code.OK == code && !result.isSuccess()) {
code = Code.BAD_REVISION;
}
if (Code.OK == code) {
List<Result<K, V>> subResults = result.results();
DeleteResult<K, V> deleteResult = (DeleteResult<K, V>) subResults.get(0);
List<KeyValue<K, V>> prevKvs = deleteResult.getPrevKvsAndClear();
if (prevKvs.isEmpty()) {
return FutureUtils.value(null);
} else {
return FutureUtils.value(prevKvs.get(0));
}
} else {
return failWithCode(code, "Failed to rDelete key " + k + " (mod_rev=" + expectedRevision + ") to store " + name());
}
} finally {
result.close();
}
});
}
Aggregations