Search in sources :

Example 11 with TableKey

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);
}
Also used : TableEntry(io.pravega.client.tables.TableEntry) Version(io.pravega.client.tables.Version) TableKey(io.pravega.client.tables.TableKey) ByteBuffer(java.nio.ByteBuffer)

Example 12 with TableKey

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));
}
Also used : lombok.val(lombok.val) IntStream(java.util.stream.IntStream) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Arrays(java.util.Arrays) AssertExtensions(io.pravega.test.common.AssertExtensions) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) KeyValueTableConfiguration(io.pravega.client.tables.KeyValueTableConfiguration) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) Unpooled(io.netty.buffer.Unpooled) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ByteBufferUtils(io.pravega.common.util.ByteBufferUtils) KeyValueTableInfo(io.pravega.client.admin.KeyValueTableInfo) LeakDetectorTestSuite(io.pravega.test.common.LeakDetectorTestSuite) TableEntry(io.pravega.client.tables.TableEntry) KeyValueTableIterator(io.pravega.client.tables.KeyValueTableIterator) lombok.val(lombok.val) IteratorItem(io.pravega.client.tables.IteratorItem) AsyncIterator(io.pravega.common.util.AsyncIterator) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Collectors(java.util.stream.Collectors) AbstractMap(java.util.AbstractMap) List(java.util.List) TableKey(io.pravega.client.tables.TableKey) Assert(org.junit.Assert) Mockito.mock(org.mockito.Mockito.mock) TableKey(io.pravega.client.tables.TableKey) Test(org.junit.Test)

Example 13 with TableKey

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());
}
Also used : lombok.val(lombok.val) IntStream(java.util.stream.IntStream) ArgumentMatchers.any(org.mockito.ArgumentMatchers.any) Arrays(java.util.Arrays) AssertExtensions(io.pravega.test.common.AssertExtensions) Random(java.util.Random) CompletableFuture(java.util.concurrent.CompletableFuture) KeyValueTableConfiguration(io.pravega.client.tables.KeyValueTableConfiguration) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) Unpooled(io.netty.buffer.Unpooled) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) ByteBufferUtils(io.pravega.common.util.ByteBufferUtils) KeyValueTableInfo(io.pravega.client.admin.KeyValueTableInfo) LeakDetectorTestSuite(io.pravega.test.common.LeakDetectorTestSuite) TableEntry(io.pravega.client.tables.TableEntry) KeyValueTableIterator(io.pravega.client.tables.KeyValueTableIterator) lombok.val(lombok.val) IteratorItem(io.pravega.client.tables.IteratorItem) AsyncIterator(io.pravega.common.util.AsyncIterator) Test(org.junit.Test) Mockito.when(org.mockito.Mockito.when) Collectors(java.util.stream.Collectors) AbstractMap(java.util.AbstractMap) List(java.util.List) TableKey(io.pravega.client.tables.TableKey) Assert(org.junit.Assert) Mockito.mock(org.mockito.Mockito.mock) ArrayList(java.util.ArrayList) ByteBuffer(java.nio.ByteBuffer) HashSet(java.util.HashSet) Test(org.junit.Test)

Example 14 with TableKey

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);
}
Also used : lombok.val(lombok.val) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Version(io.pravega.client.tables.Version) TableKey(io.pravega.client.tables.TableKey) Cleanup(lombok.Cleanup) Put(io.pravega.client.tables.Put) Test(org.junit.Test)

Example 15 with TableKey

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());
    }
}
Also used : lombok.val(lombok.val) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Insert(io.pravega.client.tables.Insert) IntStream(java.util.stream.IntStream) Put(io.pravega.client.tables.Put) Getter(lombok.Getter) AssertExtensions(io.pravega.test.common.AssertExtensions) Cleanup(lombok.Cleanup) HashMap(java.util.HashMap) Random(java.util.Random) KeyValueTableConfiguration(io.pravega.client.tables.KeyValueTableConfiguration) BitConverter(io.pravega.common.util.BitConverter) Function(java.util.function.Function) ByteBuffer(java.nio.ByteBuffer) ArrayList(java.util.ArrayList) AccessLevel(lombok.AccessLevel) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) KeyValueTableInfo(io.pravega.client.admin.KeyValueTableInfo) Duration(java.time.Duration) Map(java.util.Map) BiConsumer(java.util.function.BiConsumer) Timeout(org.junit.rules.Timeout) Nullable(javax.annotation.Nullable) Before(org.junit.Before) Serializer(io.pravega.client.stream.Serializer) LeakDetectorTestSuite(io.pravega.test.common.LeakDetectorTestSuite) TableEntry(io.pravega.client.tables.TableEntry) ConcurrentHashMap(java.util.concurrent.ConcurrentHashMap) lombok.val(lombok.val) Test(org.junit.Test) Collectors(java.util.stream.Collectors) Version(io.pravega.client.tables.Version) TimeUnit(java.util.concurrent.TimeUnit) TableModification(io.pravega.client.tables.TableModification) List(java.util.List) Rule(org.junit.Rule) KeyValueTable(io.pravega.client.tables.KeyValueTable) TableKey(io.pravega.client.tables.TableKey) Assert(org.junit.Assert) BadKeyVersionException(io.pravega.client.tables.BadKeyVersionException) Remove(io.pravega.client.tables.Remove) ArrayList(java.util.ArrayList) TableKey(io.pravega.client.tables.TableKey) Cleanup(lombok.Cleanup) Put(io.pravega.client.tables.Put) Test(org.junit.Test)

Aggregations

TableKey (io.pravega.client.tables.TableKey)19 lombok.val (lombok.val)18 Test (org.junit.Test)18 TableEntry (io.pravega.client.tables.TableEntry)14 ByteBuffer (java.nio.ByteBuffer)14 ArrayList (java.util.ArrayList)14 Random (java.util.Random)14 KeyValueTableInfo (io.pravega.client.admin.KeyValueTableInfo)13 KeyValueTableConfiguration (io.pravega.client.tables.KeyValueTableConfiguration)13 Version (io.pravega.client.tables.Version)13 AssertExtensions (io.pravega.test.common.AssertExtensions)13 LeakDetectorTestSuite (io.pravega.test.common.LeakDetectorTestSuite)13 List (java.util.List)13 Function (java.util.function.Function)13 Collectors (java.util.stream.Collectors)13 IntStream (java.util.stream.IntStream)13 Cleanup (lombok.Cleanup)13 Assert (org.junit.Assert)13 BadKeyVersionException (io.pravega.client.tables.BadKeyVersionException)12 Insert (io.pravega.client.tables.Insert)12