use of io.pravega.client.tables.TableKey in project pravega by pravega.
the class TableEntryHelper method fromTableSegmentEntry.
TableEntry fromTableSegmentEntry(TableSegment s, TableSegmentEntry e) {
if (e == null) {
return null;
}
Version version = new VersionImpl(s.getSegmentId(), e.getKey().getVersion());
TableKey key = fromTableSegmentKey(e.getKey());
ByteBuffer value = deserializeValue(e.getValue());
return new TableEntry(key, version, value);
}
use of io.pravega.client.tables.TableKey in project pravega by pravega.
the class KeyValueTableIteratorImplTests method testTableKeyComparator.
/**
* Tests the {@link KeyValueTableIteratorImpl.TableKeyComparator} class.
*/
@Test
public void testTableKeyComparator() {
val c = new KeyValueTableIteratorImpl.TableKeyComparator();
val buffers = IntStream.range(0, 256).mapToObj(i -> ByteBuffer.wrap(new byte[] { (byte) i })).collect(Collectors.toList());
for (int i = 0; i < buffers.size(); i++) {
for (int j = 0; j < buffers.size(); j++) {
int expected = (int) Math.signum(j - i);
int actual = (int) Math.signum(c.compare(buffers.get(j), buffers.get(i)));
Assert.assertEquals("Unexpected comparison for " + i + " vs " + j, expected, actual);
}
}
// Test individual keys.
val key1 = new TableKey(buffers.get(0), buffers.get(1));
val key2 = new TableKey(buffers.get(0), buffers.get(2));
val key3 = new TableKey(buffers.get(1), buffers.get(1));
Assert.assertEquals(0, c.compare(key1, key1));
AssertExtensions.assertLessThan("", 0, c.compare(key1, key2));
AssertExtensions.assertLessThan("", 0, c.compare(key1, key3));
AssertExtensions.assertLessThan("", 0, c.compare(key2, key3));
AssertExtensions.assertGreaterThan("", 0, c.compare(key2, key1));
AssertExtensions.assertGreaterThan("", 0, c.compare(key3, key1));
AssertExtensions.assertGreaterThan("", 0, c.compare(key3, key2));
// Keys with no secondary keys.
val key4 = new TableKey(buffers.get(0));
val key5 = new TableKey(buffers.get(1));
Assert.assertEquals(0, c.compare(key4, key4));
AssertExtensions.assertLessThan("", 0, c.compare(key4, key5));
AssertExtensions.assertGreaterThan("", 0, c.compare(key5, key4));
}
use of io.pravega.client.tables.TableKey in project pravega by pravega.
the class KeyValueTableIteratorImplTests method testIteratorSingleSegment.
/**
* Tests the iterator when there is a single segment involved.
*/
@Test
public void testIteratorSingleSegment() {
val pk = newBuffer(DEFAULT_CONFIG.getPrimaryKeyLength());
val sk1 = newBuffer(DEFAULT_CONFIG.getSecondaryKeyLength());
val sk2 = newBuffer(DEFAULT_CONFIG.getSecondaryKeyLength());
val maxIterationSize = 10;
val allEntries = IntStream.range(0, maxIterationSize).mapToObj(i -> new AbstractMap.SimpleImmutableEntry<>(newBuffer(TOTAL_KEY_LENGTH), newBuffer(5))).collect(Collectors.toList());
val mockSegment = mock(TableSegment.class);
when(mockSegment.keyIterator(any())).thenAnswer(arg -> {
val iteratorArgs = (SegmentIteratorArgs) arg.getArgument(0);
checkSegmentIteratorArgs(iteratorArgs, pk, sk1, sk2, maxIterationSize);
val keys = allEntries.stream().map(e -> new TableSegmentKey(Unpooled.wrappedBuffer(e.getKey()), TableSegmentKeyVersion.NO_VERSION)).collect(Collectors.toList());
return AsyncIterator.singleton(new IteratorItem<>(keys));
});
when(mockSegment.entryIterator(any())).thenAnswer(arg -> {
val iteratorArgs = (SegmentIteratorArgs) arg.getArgument(0);
checkSegmentIteratorArgs(iteratorArgs, pk, sk1, sk2, maxIterationSize);
val entries = allEntries.stream().map(e -> new TableSegmentEntry(new TableSegmentKey(Unpooled.wrappedBuffer(e.getKey()), TableSegmentKeyVersion.NO_VERSION), Unpooled.wrappedBuffer(e.getValue()))).collect(Collectors.toList());
return AsyncIterator.singleton(new IteratorItem<>(entries));
});
val selector = mock(SegmentSelector.class);
when(selector.getKvt()).thenReturn(KVT);
when(selector.getSegmentCount()).thenReturn(DEFAULT_CONFIG.getPartitionCount());
val segmentRequests = new HashSet<ByteBuffer>();
when(selector.getTableSegment(any())).thenAnswer(arg -> {
val key = (ByteBuffer) arg.getArgument(0);
segmentRequests.add(key.duplicate());
return mockSegment;
});
val entryHelper = new TableEntryHelper(selector, DEFAULT_CONFIG);
val b = new KeyValueTableIteratorImpl.Builder(DEFAULT_CONFIG, entryHelper, executorService()).maxIterationSize(maxIterationSize);
// Everything up until here has been verified in the Builder unit tests (no need to do it again).
// Create a Primary Key range iterator.
val iterator = b.forPrimaryKey(pk, sk1, sk2);
// Issue a Key iterator and then an Entry iterator, then collect all the results.
val iteratorKeys = new ArrayList<TableKey>();
iterator.keys().collectRemaining(ii -> iteratorKeys.addAll(ii.getItems())).join();
val iteratorEntries = new ArrayList<TableEntry>();
iterator.entries().collectRemaining(ii -> iteratorEntries.addAll(ii.getItems())).join();
// Validate the results are as expected.
Assert.assertEquals(allEntries.size(), iteratorKeys.size());
Assert.assertEquals(allEntries.size(), iteratorEntries.size());
for (int i = 0; i < allEntries.size(); i++) {
val expected = allEntries.get(i);
val actualKey = iteratorKeys.get(i);
val actualEntry = iteratorEntries.get(i);
Assert.assertEquals(Unpooled.wrappedBuffer(expected.getKey()), entryHelper.serializeKey(actualKey.getPrimaryKey(), actualKey.getSecondaryKey()));
Assert.assertEquals(actualKey, actualEntry.getKey());
Assert.assertEquals(expected.getValue(), actualEntry.getValue());
}
Assert.assertEquals("Only expecting 1 segment to be requested.", 1, segmentRequests.size());
}
use of io.pravega.client.tables.TableKey in project pravega by pravega.
the class KeyValueTableTestBase method testSingleKeyUpdates.
/**
* Tests the ability to perform single-key updates and replacements. These methods are exercised:
* - {@link KeyValueTable#update} with {@link Put} instances.
* - {@link KeyValueTable#get} and {@link KeyValueTable#getAll}.
*/
@Test
public void testSingleKeyUpdates() {
val versions = new Versions();
@Cleanup val kvt = createKeyValueTable();
// Put (unconditional update).
val iteration = new AtomicInteger(0);
forEveryKey((pk, sk) -> {
val value = getValue(pk, sk, iteration.get());
Version kv = kvt.update(new Put(new TableKey(pk, sk), value)).join();
versions.add(getUniqueKeyId(pk, sk), kv);
});
checkValues(iteration.get(), versions, kvt);
// Put (conditional update (not insertion)).
iteration.incrementAndGet();
forEveryKey((pk, sk) -> {
val value = getValue(pk, sk, iteration.get());
val keyId = getUniqueKeyId(pk, sk);
val existingVersion = versions.get(keyId);
// Verify that conditions are checked both for segment names and their versions.
val pkValue = Math.abs(PK_SERIALIZER.deserialize(pk));
Version badVersion = alterVersion(existingVersion, pkValue % 2 == 0, pkValue % 2 == 1);
AssertExtensions.assertSuppliedFutureThrows("update(Put-Conditional) did not throw for bad version.", () -> kvt.update(new Put(new TableKey(pk, sk), value, badVersion)), ex -> ex instanceof BadKeyVersionException);
Version kv = kvt.update(new Put(new TableKey(pk, sk), value, existingVersion)).join();
versions.add(keyId, kv);
});
checkValues(iteration.get(), versions, kvt);
}
use of io.pravega.client.tables.TableKey in project pravega by pravega.
the class KeyValueTableTestBase method testLargeEntryBatchRetrieval.
/**
* Verify that multi-get retrieval from a single segment of keys totalling more than the limit(s) works correctly.
*/
@Test
public void testLargeEntryBatchRetrieval() {
val keyCount = TableSegment.MAXIMUM_BATCH_KEY_COUNT;
Function<Integer, byte[]> getValue = keyId -> {
val result = new byte[Long.BYTES];
BitConverter.writeInt(result, 0, keyId + 1);
return result;
};
@Cleanup val kvt = createKeyValueTable();
// Update the entries one-by-one to make sure we do not exceed the max lengths at this step.
val allKeys = new ArrayList<TableKey>();
for (int keyId = 0; keyId < keyCount; keyId++) {
val pk = new byte[getPrimaryKeyLength()];
val sk = new byte[getSecondaryKeyLength()];
BitConverter.writeLong(pk, 0, keyId);
BitConverter.writeInt(sk, 0, keyId);
val value = getValue.apply(keyId);
kvt.update(new Put(new TableKey(ByteBuffer.wrap(pk), ByteBuffer.wrap(sk)), ByteBuffer.wrap(value))).join();
allKeys.add(new TableKey(ByteBuffer.wrap(pk), ByteBuffer.wrap(sk)));
}
// Bulk-get all the keys. This should work regardless of the size of the data returned; the KeyValueTable and
// TableSegment internally should break down the requests and handle this properly.
val getResult = kvt.getAll(allKeys).join();
Assert.assertEquals("Unexpected number of keys returned.", allKeys.size(), getResult.size());
for (int keyId = 0; keyId < allKeys.size(); keyId++) {
val r = getResult.get(keyId);
val expectedKey = allKeys.get(keyId);
Assert.assertTrue("Unexpected key at index " + keyId, areEqual(expectedKey, r.getKey()));
val expectedValue = getValue.apply(keyId);
Assert.assertEquals("Unexpected value at index " + keyId, ByteBuffer.wrap(expectedValue), r.getValue());
}
}
Aggregations