Search in sources :

Example 36 with Tuple

use of com.apple.foundationdb.tuple.Tuple in project fdb-record-layer by FoundationDB.

the class BunchedMapScanTest method testScanMulti.

private void testScanMulti(int limit, boolean reverse, List<List<Tuple>> keyLists, @Nonnull BiFunction<Transaction, byte[], BunchedMapMultiIterator<Tuple, Tuple, Long>> iteratorFunction) {
    try (Transaction tr = db.createTransaction()) {
        byte[] continuation = null;
        List<BunchedMapScanEntry<Tuple, Tuple, Long>> entryList = new ArrayList<>();
        BunchedMapScanEntry<Tuple, Tuple, Long> lastEntry = null;
        do {
            BunchedMapMultiIterator<Tuple, Tuple, Long> iterator = iteratorFunction.apply(tr, continuation);
            int returned = 0;
            while (iterator.hasNext()) {
                BunchedMapScanEntry<Tuple, Tuple, Long> toAdd = iterator.peek();
                assertEquals(toAdd, iterator.next());
                if (lastEntry != null) {
                    if (toAdd.getSubspaceTag().equals(lastEntry.getSubspaceTag())) {
                        assertEquals(reverse ? 1 : -1, Integer.signum(lastEntry.getKey().compareTo(toAdd.getKey())));
                    } else {
                        assertEquals(reverse ? 1 : -1, Integer.signum(lastEntry.getSubspaceTag().compareTo(toAdd.getSubspaceTag())));
                    }
                }
                entryList.add(toAdd);
                lastEntry = toAdd;
                returned++;
            }
            continuation = iterator.getContinuation();
            if (limit == ReadTransaction.ROW_LIMIT_UNLIMITED || returned < limit) {
                assertNull(continuation);
            } else {
                assertNotNull(continuation);
            }
        } while (continuation != null);
        if (reverse) {
            entryList = Lists.reverse(entryList);
        }
        Long tag = null;
        int pos = 0;
        int totalRead = 0;
        for (BunchedMapScanEntry<Tuple, Tuple, Long> entry : entryList) {
            if (tag == null || !tag.equals(entry.getSubspaceTag())) {
                if (tag != null) {
                    assertEquals(tag + 1, entry.getSubspaceTag().longValue());
                }
                tag = entry.getSubspaceTag();
                pos = 0;
            }
            assertEquals(keyLists.get(tag.intValue()).get(pos), entry.getKey());
            assertEquals(value, entry.getValue());
            assertEquals(subSubspaces.get(tag.intValue()), entry.getSubspace());
            pos++;
            totalRead++;
        }
        int totalToSee = keyLists.stream().mapToInt(List::size).sum();
        assertEquals(totalToSee, totalRead);
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) ReadTransaction(com.apple.foundationdb.ReadTransaction) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple)

Example 37 with Tuple

use of com.apple.foundationdb.tuple.Tuple in project fdb-record-layer by FoundationDB.

the class BunchedMapScanTest method continuationWithDeletes.

private void continuationWithDeletes(int limit, boolean reverse) {
    try (Transaction tr = db.createTransaction()) {
        byte[] continuation = null;
        List<Tuple> readKeys = new ArrayList<>();
        do {
            List<Tuple> mostRecentReadKeys = new ArrayList<>();
            int returned = 0;
            BunchedMapIterator<Tuple, Tuple> bunchedMapIterator = map.scan(tr, subSubspaces.get(1), continuation, limit, reverse);
            while (bunchedMapIterator.hasNext()) {
                Tuple toAdd = bunchedMapIterator.peek().getKey();
                assertEquals(toAdd, bunchedMapIterator.next().getKey());
                mostRecentReadKeys.add(toAdd);
                returned += 1;
            }
            assertFalse(bunchedMapIterator.hasNext());
            assertThrows(NoSuchElementException.class, bunchedMapIterator::peek);
            assertThrows(NoSuchElementException.class, bunchedMapIterator::next);
            continuation = bunchedMapIterator.getContinuation();
            if (returned != limit) {
                assertNull(continuation);
            } else {
                assertNotNull(continuation);
            }
            // Remove all of the keys that were most recently read.
            mostRecentReadKeys.forEach(k -> map.remove(tr, subSubspaces.get(1), k).join());
            readKeys.addAll(mostRecentReadKeys);
        } while (continuation != null);
        if (reverse) {
            readKeys = Lists.reverse(readKeys);
        }
        List<Tuple> expectedKeys = IntStream.range(0, keys.size()).filter(i -> i % subSubspaces.size() == 1).mapToObj(keys::get).collect(Collectors.toList());
        assertEquals(expectedKeys, readKeys);
        tr.cancel();
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) ReadTransaction(com.apple.foundationdb.ReadTransaction) ArrayList(java.util.ArrayList) Tuple(com.apple.foundationdb.tuple.Tuple)

Example 38 with Tuple

use of com.apple.foundationdb.tuple.Tuple in project fdb-record-layer by FoundationDB.

the class BunchedMapScanTest method scanWithConflict.

@Test
public void scanWithConflict() throws InterruptedException, ExecutionException {
    clearAndPopulate();
    try (Transaction tr1 = db.createTransaction();
        Transaction tr2 = db.createTransaction()) {
        CompletableFuture.allOf(tr1.getReadVersion(), tr2.getReadVersion()).get();
        BunchedMapIterator<Tuple, Tuple> iterator = map.scan(tr1, bmSubspace);
        int count = MoreAsyncUtil.reduce(iterator, 0, (oldCount, item) -> oldCount + 1).get();
        assertEquals(keys.size(), count);
        tr1.addWriteConflictKey(Tuple.from(count).pack());
        assertFalse(map.put(tr2, bmSubspace, Tuple.from(keys.get(keys.size() - 1).getLong(0) + 1), value).get().isPresent());
        tr2.commit().get();
        CompletionException e = assertThrows(CompletionException.class, () -> tr1.commit().join());
        assertNotNull(e.getCause());
        assertTrue(e.getCause() instanceof FDBException);
        FDBException fdbE = (FDBException) e.getCause();
        assertEquals(FDBError.NOT_COMMITTED.code(), fdbE.getCode());
    }
    byte[] continuation = null;
    for (int i = 0; i < keys.size(); i++) {
    }
    try (Transaction tr1 = db.createTransaction();
        Transaction tr2 = db.createTransaction()) {
        CompletableFuture.allOf(tr1.getReadVersion(), tr2.getReadVersion()).get();
        BunchedMapIterator<Tuple, Tuple> iterator = map.scan(tr1, bmSubspace);
    }
}
Also used : IntStream(java.util.stream.IntStream) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) FDB(com.apple.foundationdb.FDB) Arrays(java.util.Arrays) FDBTestBase(com.apple.foundationdb.FDBTestBase) BiFunction(java.util.function.BiFunction) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CompletableFuture(java.util.concurrent.CompletableFuture) Database(com.apple.foundationdb.Database) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) Supplier(java.util.function.Supplier) Subspace(com.apple.foundationdb.subspace.Subspace) ArrayList(java.util.ArrayList) AfterAll(org.junit.jupiter.api.AfterAll) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Lists(com.google.common.collect.Lists) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) FDBError(com.apple.foundationdb.FDBError) BeforeAll(org.junit.jupiter.api.BeforeAll) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Tag(org.junit.jupiter.api.Tag) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) NoSuchElementException(java.util.NoSuchElementException) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) ByteArrayUtil2(com.apple.foundationdb.tuple.ByteArrayUtil2) MoreAsyncUtil(com.apple.foundationdb.async.MoreAsyncUtil) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) LongStream(java.util.stream.LongStream) Tags(com.apple.test.Tags) DirectoryLayer(com.apple.foundationdb.directory.DirectoryLayer) CompletionException(java.util.concurrent.CompletionException) Collectors(java.util.stream.Collectors) ReadTransaction(com.apple.foundationdb.ReadTransaction) Test(org.junit.jupiter.api.Test) ExecutionException(java.util.concurrent.ExecutionException) List(java.util.List) PathUtil(com.apple.foundationdb.directory.PathUtil) Stream(java.util.stream.Stream) FDBException(com.apple.foundationdb.FDBException) TupleHelpers(com.apple.foundationdb.tuple.TupleHelpers) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Comparator(java.util.Comparator) Collections(java.util.Collections) AsyncPeekIterator(com.apple.foundationdb.async.AsyncPeekIterator) Transaction(com.apple.foundationdb.Transaction) ReadTransaction(com.apple.foundationdb.ReadTransaction) CompletionException(java.util.concurrent.CompletionException) FDBException(com.apple.foundationdb.FDBException) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 39 with Tuple

use of com.apple.foundationdb.tuple.Tuple in project fdb-record-layer by FoundationDB.

the class BunchedMapTest method concurrentIllegalUpdates.

@Test
public void concurrentIllegalUpdates() throws ExecutionException, InterruptedException {
    final Tuple value = Tuple.from(Tuple.from((Object) null));
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(0L), value).join();
        map.put(tr1, bmSubspace, Tuple.from(5L), value).join();
        map.put(tr2, bmSubspace, Tuple.from(3L), value).join();
    }, false, Collections.singletonList(Tuple.from(0L)));
    try (Transaction tr = db.createTransaction()) {
        tr.clear(bmSubspace.range());
        tr.commit().get();
    }
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(5L), value).join();
        map.put(tr1, bmSubspace, Tuple.from(0L), value).join();
        map.put(tr2, bmSubspace, Tuple.from(3L), value).join();
    }, false, Collections.singletonList(Tuple.from(0L)));
    try (Transaction tr = db.createTransaction()) {
        tr.clear(bmSubspace.range());
        tr.commit().get();
    }
    final List<Tuple> tuples = LongStream.range(100L, 115L).boxed().map(Tuple::from).collect(Collectors.toList());
    db.run(tr -> {
        tr.clear(bmSubspace.range());
        tuples.forEach(t -> map.put(tr, bmSubspace, t, value).join());
        return null;
    });
    // Case 1: Transaction reads the value of a boundary key while
    // that boundary is updated.
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(116L), value).join();
        assertEquals(value, map.get(tr2, bmSubspace, Tuple.from(110L)).join().get());
    }, false, Arrays.asList(Tuple.from(100L), Tuple.from(110L)));
    // Case 2: Transaction reads the same key while
    // a put goes onto the same key and changes the value.
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(105L), value.add(3.14d)).join();
        assertEquals(value, map.get(tr2, bmSubspace, Tuple.from(105L)).join().get());
    }, false, Arrays.asList(Tuple.from(100L), Tuple.from(110L)));
    assertEquals(value.add(3.14d), map.get(db, bmSubspace, Tuple.from(105L)).get().get());
    // Case 3: One put changes a value while another put tries to set it to
    // the same value.
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(105L), value).join();
        map.put(tr2, bmSubspace, Tuple.from(105L), value.add(3.14d)).join();
    }, false, Arrays.asList(Tuple.from(100L), Tuple.from(110L)));
    assertEquals(value, map.get(db, bmSubspace, Tuple.from(105L)).get().get());
    // Case 4: Two puts happen at the same value at the same time.
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(105L), value.add(3.14d)).join();
        map.put(tr2, bmSubspace, Tuple.from(105L), value.add(2.72d)).join();
    }, false, Arrays.asList(Tuple.from(100L), Tuple.from(110L)));
    assertEquals(value.add(3.14d), map.get(db, bmSubspace, Tuple.from(105L)).get().get());
    // Case 5: Something attempts to re-write something in the
    // interior of the boundary while writing
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(116L), value.add(3.14d)).join();
        map.put(tr2, bmSubspace, Tuple.from(117L), value).join();
    }, false, Arrays.asList(Tuple.from(100L), Tuple.from(110L)));
    assertFalse(map.containsKey(db, bmSubspace, Tuple.from(117L)).get());
    // Case 6: Write a value that would end up being overwritten in a split
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(102L, null), value).join();
        map.put(tr2, bmSubspace, Tuple.from(107L), value.add(3.14d)).join();
    }, false, Arrays.asList(Tuple.from(100L), Tuple.from(104L), Tuple.from(110L)));
    assertEquals(value, map.get(db, bmSubspace, Tuple.from(107L)).get().get());
    // Case 7: Write a key before the current value that eats the value
    // from a boundary key while another transaction does the same thing
    // (Note that this test fails if the read conflict ranges are added
    // after the writes, so this tests to make sure that that is done
    // properly.)
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(98L), value).join();
        map.put(tr2, bmSubspace, Tuple.from(99L), value).join();
    }, false, Arrays.asList(Tuple.from(98L), Tuple.from(104L), Tuple.from(110L)));
    // Case 8: The same as case 7, but the greater key wins instead of
    // the smaller key
    runWithTwoTrs((tr1, tr2) -> {
        map.put(tr1, bmSubspace, Tuple.from(97L), value).join();
        map.put(tr2, bmSubspace, Tuple.from(96L), value).join();
    }, false, Arrays.asList(Tuple.from(97L), Tuple.from(104L), Tuple.from(110L)));
    try (Transaction tr = db.createTransaction()) {
        List<Map.Entry<Tuple, Tuple>> entryList = AsyncUtil.collectRemaining(map.scan(tr, bmSubspace)).get();
        System.out.println(entryList);
    }
}
Also used : Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 40 with Tuple

use of com.apple.foundationdb.tuple.Tuple in project fdb-record-layer by FoundationDB.

the class BunchedMapTest method insertSingleKey.

@Test
public void insertSingleKey() {
    List<Tuple> testTuples = Stream.of(1066L, 1776L, 1415L, 800L).map(Tuple::from).collect(Collectors.toList());
    Tuple value = Tuple.from(1415L);
    db.run(tr -> {
        Tuple minSoFar = null;
        for (int i = 0; i < testTuples.size(); i++) {
            Tuple key = testTuples.get(i);
            minSoFar = (minSoFar == null || key.compareTo(minSoFar) < 0) ? key : minSoFar;
            map.put(tr, bmSubspace, key, value).join();
            for (int j = 0; j < testTuples.size(); j++) {
                assertEquals(j <= i, map.containsKey(tr, bmSubspace, testTuples.get(j)).join());
            }
            List<KeyValue> rangeKVs = tr.getRange(bmSubspace.range()).asList().join();
            assertEquals(1, rangeKVs.size());
            assertArrayEquals(bmSubspace.pack(minSoFar), rangeKVs.get(0).getKey());
            List<Map.Entry<Tuple, Tuple>> entryList = testTuples.subList(0, i + 1).stream().sorted().map(t -> new AbstractMap.SimpleImmutableEntry<>(t, value)).collect(Collectors.toList());
            assertArrayEquals(serializer.serializeEntries(entryList), rangeKVs.get(0).getValue());
        }
        return null;
    });
}
Also used : BeforeEach(org.junit.jupiter.api.BeforeEach) FDB(com.apple.foundationdb.FDB) Arrays(java.util.Arrays) FDBTestBase(com.apple.foundationdb.FDBTestBase) Random(java.util.Random) Disabled(org.junit.jupiter.api.Disabled) Subspace(com.apple.foundationdb.subspace.Subspace) MutationType(com.apple.foundationdb.MutationType) AfterAll(org.junit.jupiter.api.AfterAll) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) FDBError(com.apple.foundationdb.FDBError) BeforeAll(org.junit.jupiter.api.BeforeAll) AtomicInteger(java.util.concurrent.atomic.AtomicInteger) Map(java.util.Map) Tag(org.junit.jupiter.api.Tag) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) KeyValue(com.apple.foundationdb.KeyValue) DirectoryLayer(com.apple.foundationdb.directory.DirectoryLayer) UUID(java.util.UUID) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) List(java.util.List) Stream(java.util.stream.Stream) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) Assertions.fail(org.junit.jupiter.api.Assertions.fail) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) AsyncIterator(com.apple.foundationdb.async.AsyncIterator) AtomicBoolean(java.util.concurrent.atomic.AtomicBoolean) CompletableFuture(java.util.concurrent.CompletableFuture) Database(com.apple.foundationdb.Database) AsyncUtil(com.apple.foundationdb.async.AsyncUtil) AtomicReference(java.util.concurrent.atomic.AtomicReference) ArrayList(java.util.ArrayList) LoggableException(com.apple.foundationdb.util.LoggableException) BiConsumer(java.util.function.BiConsumer) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) Nullable(javax.annotation.Nullable) LongStream(java.util.stream.LongStream) Versionstamp(com.apple.foundationdb.tuple.Versionstamp) Tags(com.apple.test.Tags) ExecutionException(java.util.concurrent.ExecutionException) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) AtomicLong(java.util.concurrent.atomic.AtomicLong) AbstractMap(java.util.AbstractMap) PathUtil(com.apple.foundationdb.directory.PathUtil) TreeMap(java.util.TreeMap) FDBException(com.apple.foundationdb.FDBException) KeySelector(com.apple.foundationdb.KeySelector) Comparator(java.util.Comparator) Collections(java.util.Collections) KeyValue(com.apple.foundationdb.KeyValue) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Aggregations

Tuple (com.apple.foundationdb.tuple.Tuple)163 Nonnull (javax.annotation.Nonnull)80 List (java.util.List)66 Test (org.junit.jupiter.api.Test)66 TupleRange (com.apple.foundationdb.record.TupleRange)62 ArrayList (java.util.ArrayList)57 Message (com.google.protobuf.Message)56 Nullable (javax.annotation.Nullable)50 IndexEntry (com.apple.foundationdb.record.IndexEntry)48 Index (com.apple.foundationdb.record.metadata.Index)47 Subspace (com.apple.foundationdb.subspace.Subspace)47 CompletableFuture (java.util.concurrent.CompletableFuture)46 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)45 ScanProperties (com.apple.foundationdb.record.ScanProperties)43 FDBRecordContext (com.apple.foundationdb.record.provider.foundationdb.FDBRecordContext)42 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)41 Collectors (java.util.stream.Collectors)41 Collections (java.util.Collections)40 Transaction (com.apple.foundationdb.Transaction)38 RecordCursor (com.apple.foundationdb.record.RecordCursor)38