use of io.pravega.client.tables.TableEntry in project pravega by pravega.
the class KeyValueTableTestBase method checkPrimaryKeyIterator.
private void checkPrimaryKeyIterator(KeyValueTable keyValueTable, Versions versions, int iteration) {
val itemsAtOnce = getSecondaryKeyCount() / 5;
forEveryPrimaryKey((pk, secondaryKeys) -> {
// Get all Table Keys and sort them.
val allKeys = secondaryKeys.stream().map(sk -> new TableKey(pk, sk)).sorted(KEY_COMPARATOR).collect(Collectors.toList());
val allEntries = allKeys.stream().map(k -> new TableEntry(k, versions.get(getUniqueKeyId(k.getPrimaryKey(), k.getSecondaryKey())), getValue(k.getPrimaryKey(), k.getSecondaryKey(), iteration))).collect(Collectors.toList());
// Issue various iterators (range) and verify against expected values.
for (int startIndex = 0; startIndex < allKeys.size() / 2; startIndex++) {
val endIndex = allKeys.size() - startIndex;
val expectedKeys = allKeys.subList(startIndex, endIndex);
val iterator = keyValueTable.iterator().maxIterationSize(itemsAtOnce).forPrimaryKey(pk, expectedKeys.get(0).getSecondaryKey(), expectedKeys.get(expectedKeys.size() - 1).getSecondaryKey());
val iteratorKeys = new ArrayList<TableKey>();
iterator.keys().collectRemaining(ii -> iteratorKeys.addAll(ii.getItems())).join();
AssertExtensions.assertListEquals("Unexpected keys returned from iterator.keys()", expectedKeys, iteratorKeys, this::areEqual);
val expectedEntries = allEntries.subList(startIndex, endIndex);
val iteratorEntries = new ArrayList<TableEntry>();
iterator.entries().collectRemaining(ii -> iteratorEntries.addAll(ii.getItems())).join();
AssertExtensions.assertListEquals("Unexpected entries returned from iterator.entries()", expectedEntries, iteratorEntries, (e1, e2) -> areEqual(e1, e2) && e1.getVersion().equals(e2.getVersion()));
}
});
}
use of io.pravega.client.tables.TableEntry in project pravega by pravega.
the class KeyValueTableTestBase method checkValues.
private void checkValues(int iteration, Map<ByteBuffer, Version> keyVersions, KeyValueTable kvt) {
// Using single get.
for (val k : keyVersions.entrySet()) {
val expectedValue = k.getValue() == null ? null : new TableEntry(new TableKey(k.getKey()), k.getValue(), getValue(k.getKey(), iteration));
val actualEntry = kvt.get(new TableKey(k.getKey())).join();
Assert.assertTrue(areEqual(expectedValue, actualEntry));
boolean exists = kvt.exists(new TableKey(k.getKey())).join();
Assert.assertEquals(expectedValue != null, exists);
}
// Using multi-get.
val requestKeys = new ArrayList<>(keyVersions.entrySet());
val entries = kvt.getAll(requestKeys.stream().map(k -> new TableKey(k.getKey())).collect(Collectors.toList())).join();
Assert.assertEquals(keyVersions.size(), entries.size());
for (int i = 0; i < requestKeys.size(); i++) {
val k = requestKeys.get(i);
val expectedValue = k.getValue() == null ? null : new TableEntry(new TableKey(k.getKey()), k.getValue(), getValue(k.getKey(), iteration));
val actualEntry = entries.get(i);
Assert.assertTrue(areEqual(expectedValue, actualEntry));
}
}
use of io.pravega.client.tables.TableEntry in project pravega by pravega.
the class KeyValueTableImpl method getAll.
@Override
public CompletableFuture<List<TableEntry>> getAll(@NonNull Iterable<TableKey> keys) {
Exceptions.checkNotClosed(this.closed.get(), this);
val bySegment = new HashMap<TableSegment, KeyGroup>();
val count = new AtomicInteger(0);
keys.forEach(k -> {
TableSegment ts = this.selector.getTableSegment(k.getPrimaryKey());
KeyGroup g = bySegment.computeIfAbsent(ts, t -> new KeyGroup());
g.add(this.entryHelper.serializeKey(k), count.getAndIncrement());
});
val futures = new HashMap<TableSegment, CompletableFuture<List<TableSegmentEntry>>>();
bySegment.forEach((ts, kg) -> futures.put(ts, ts.get(kg.keys.iterator())));
return Futures.allOf(futures.values()).thenApply(v -> {
val r = new TableEntry[count.get()];
futures.forEach((ts, f) -> {
KeyGroup kg = bySegment.get(ts);
assert f.isDone() : "incomplete CompletableFuture returned by Futures.allOf";
val segmentResult = f.join();
assert segmentResult.size() == kg.ordinals.size() : "segmentResult count mismatch";
for (int i = 0; i < kg.ordinals.size(); i++) {
assert r[kg.ordinals.get(i)] == null : "overlapping ordinals";
r[kg.ordinals.get(i)] = this.entryHelper.fromTableSegmentEntry(ts, segmentResult.get(i));
}
});
return Arrays.asList(r);
});
}
use of io.pravega.client.tables.TableEntry 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.TableEntry 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());
}
Aggregations