Search in sources :

Example 56 with Transaction

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

the class BunchedMapTest method insertTwoKeys.

@Test
public void insertTwoKeys() throws ExecutionException, InterruptedException {
    final Tuple value = Tuple.from("hello", "there");
    final List<Tuple> firstTuples = LongStream.range(100L, 110L).boxed().map(Tuple::from).collect(Collectors.toList());
    final List<Tuple> secondTuples = LongStream.range(120L, 130L).boxed().map(Tuple::from).collect(Collectors.toList());
    db.run(tr -> {
        firstTuples.forEach(t -> map.put(tr, bmSubspace, t, value).join());
        secondTuples.forEach(t -> map.put(tr, bmSubspace, t, value).join());
        List<KeyValue> rangeKVs = tr.getRange(bmSubspace.range()).asList().join();
        assertEquals(2, rangeKVs.size());
        firstTuples.forEach(t -> assertTrue(map.containsKey(tr, bmSubspace, t).join(), t.toString() + " not in map"));
        secondTuples.forEach(t -> assertTrue(map.containsKey(tr, bmSubspace, t).join(), t.toString() + " not in map"));
        return null;
    });
    try (Transaction tr = db.createTransaction()) {
        // Insert in the middle.
        List<Tuple> middleTuples = Stream.of(115L, 118L, 119L, 114L).map(Tuple::from).collect(Collectors.toList());
        Tuple minSoFar = null;
        for (int i = 0; i < middleTuples.size(); i++) {
            Tuple t = middleTuples.get(i);
            map.put(tr, bmSubspace, t, value).join();
            minSoFar = (minSoFar == null || t.compareTo(minSoFar) < 0) ? t : minSoFar;
            for (int j = 0; j < middleTuples.size(); j++) {
                assertEquals(j <= i, map.containsKey(tr, bmSubspace, middleTuples.get(j)).get());
            }
            List<KeyValue> rangeKVs = tr.getRange(bmSubspace.range()).asList().join();
            assertEquals(3, rangeKVs.size());
            List<Tuple> keys = rangeKVs.stream().map(KeyValue::getKey).map(bmSubspace::unpack).collect(Collectors.toList());
            assertEquals(Arrays.asList(Tuple.from(100L), minSoFar, Tuple.from(120L)), keys);
        }
        tr.cancel();
    }
    try (Transaction tr = db.createTransaction()) {
        // Remove a key from the end of first tuple collection.
        assertTrue(map.remove(tr, bmSubspace, Tuple.from(109L)).get().isPresent());
        assertFalse(map.remove(tr, bmSubspace, Tuple.from(109L)).get().isPresent());
        map.put(tr, bmSubspace, Tuple.from(110L), value).get();
        List<KeyValue> rangeKVs = tr.getRange(bmSubspace.range()).asList().get();
        assertEquals(2, rangeKVs.size());
        // Now insert in the middle to force it to split.
        map.put(tr, bmSubspace, Tuple.from(109L), value).get();
        rangeKVs = tr.getRange(bmSubspace.range()).asList().get();
        assertEquals(3, rangeKVs.size());
        List<Tuple> keys = rangeKVs.stream().map(KeyValue::getKey).map(bmSubspace::unpack).collect(Collectors.toList());
        assertEquals(Arrays.asList(Tuple.from(100L), Tuple.from(105L), Tuple.from(120L)), keys);
        tr.cancel();
    }
}
Also used : KeyValue(com.apple.foundationdb.KeyValue) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple) Test(org.junit.jupiter.api.Test)

Example 57 with Transaction

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

the class BunchedMapTest method verifyBoundaryKeys.

private void verifyBoundaryKeys(@Nonnull List<Tuple> boundaryKeys) throws ExecutionException, InterruptedException {
    try (Transaction tr = db.createTransaction()) {
        map.verifyIntegrity(tr, bmSubspace).get();
        List<KeyValue> rangeKVs = tr.getRange(bmSubspace.range()).asList().get();
        List<Tuple> actualBoundaryKeys = rangeKVs.stream().map(KeyValue::getKey).map(bmSubspace::unpack).collect(Collectors.toList());
        List<Map.Entry<Tuple, Tuple>> entryList = rangeKVs.stream().flatMap(kv -> serializer.deserializeEntries(bmSubspace.unpack(kv.getKey()), kv.getValue()).stream()).collect(Collectors.toList());
        System.out.println(entryList);
        assertEquals(boundaryKeys, actualBoundaryKeys);
        tr.cancel();
    }
}
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) Transaction(com.apple.foundationdb.Transaction) Tuple(com.apple.foundationdb.tuple.Tuple)

Example 58 with Transaction

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

the class RangeSetTest method concurrentWithInsert.

// Test out a few of the wild and wacky things that can happen when there are insertions going concurrently.
@Test
@Tag(Tags.Slow)
public void concurrentWithInsert() {
    final List<byte[]> keys = createKeys();
    final List<Range> ranges = new ArrayList<>();
    // Two disjoint ranges -- both should succeed.
    Transaction tr1 = db.createTransaction();
    Transaction tr2 = db.createTransaction();
    Range r1 = new Range(new byte[] { 0x01 }, new byte[] { 0x02 });
    Range r2 = new Range(new byte[] { 0x02 }, new byte[] { 0x03 });
    CompletableFuture<Boolean> future1 = rs.insertRange(tr1, r1);
    CompletableFuture<Boolean> future2 = rs.insertRange(tr2, r2);
    assertTrue(future1.join(), "Range 1 did not do insertion.");
    assertTrue(future2.join(), "Range 2 did not do insertion.");
    tr1.commit().join();
    tr2.commit().join();
    ranges.add(r1);
    ranges.add(r2);
    checkConsistent(ranges, keys);
    checkIncreasing();
    // Two non-disjoint ranges. The second should fail.
    tr1 = db.createTransaction();
    tr2 = db.createTransaction();
    r1 = new Range(new byte[] { 0x03 }, new byte[] { 0x05 });
    r2 = new Range(new byte[] { 0x04 }, new byte[] { 0x06 });
    future1 = rs.insertRange(tr1, r1);
    future2 = rs.insertRange(tr2, r2);
    assertTrue(future1.join(), "Range 1 did not do insertion");
    assertTrue(future2.join(), "Range 2 did not do insertion");
    tr1.commit().join();
    tr2.commit().handle((vignore, e) -> {
        assertNotNull(e, "No error thrown from commit");
        assertTrue(e instanceof FDBException, "Non-FDBException " + e.toString());
        FDBException fdbe = (FDBException) e;
        assertEquals(FDBError.NOT_COMMITTED.code(), fdbe.getCode(), "Did not get not-committed error.");
        return vignore;
    }).join();
    ranges.add(r1);
    checkConsistent(ranges, keys);
    checkIncreasing();
    // Read during write - the reads in the range should fail.
    r1 = new Range(new byte[] { 0x07 }, new byte[] { 0x08 });
    List<byte[]> specificKeys = Arrays.asList(new byte[] { 0x06, (byte) 0xff }, new byte[] { 0x07 }, new byte[] { 0x07, 0x00 }, new byte[] { 0x07, 0x10 }, new byte[] { 0x08 }, new byte[] { 0x08, 0x00 }, new byte[] { 0x08, 0x10 }, new byte[] { 0x09 });
    tr1 = db.createTransaction();
    List<Transaction> transactions = specificKeys.stream().map(ignore -> db.createTransaction()).collect(Collectors.toList());
    // Add write conflict ranges to each key so that they are not read only.
    transactions.forEach(tr -> tr.addWriteConflictKey(DEADC0DE));
    future1 = rs.insertRange(tr1, r1);
    List<CompletableFuture<Boolean>> futures = new ArrayList<>();
    for (int i = 0; i < specificKeys.size(); i++) {
        futures.add(rs.contains(transactions.get(i), specificKeys.get(i)));
    }
    assertTrue(future1.join(), "Range 1 did not do insertion");
    futures.forEach(future -> assertFalse(future.join(), "Key should not be present"));
    tr1.commit().join();
    Range range = r1;
    for (int i = 0; i < transactions.size(); i++) {
        final int index = i;
        transactions.get(i).commit().handle((vignore, e) -> {
            byte[] key = specificKeys.get(index);
            String repr = ByteArrayUtil.printable(key);
            if (ByteArrayUtil.compareUnsigned(range.begin, key) <= 0 && ByteArrayUtil.compareUnsigned(key, range.end) < 0) {
                assertNotNull(e, "No error from commit when key is " + repr);
                assertTrue(e instanceof FDBException, "Non-FDBException " + e.toString() + " with key " + repr);
                FDBException fdbe = (FDBException) e;
                assertEquals(FDBError.NOT_COMMITTED.code(), fdbe.getCode(), "Did not get non-committed error when key is " + repr);
            } else {
                assertNull(e, "Error when key is " + repr);
            }
            return vignore;
        }).join();
    }
    ranges.add(r1);
    checkConsistent(ranges, keys);
    checkIncreasing();
}
Also used : Assertions.assertThrows(org.junit.jupiter.api.Assertions.assertThrows) BeforeEach(org.junit.jupiter.api.BeforeEach) Assertions.assertNotNull(org.junit.jupiter.api.Assertions.assertNotNull) FDB(com.apple.foundationdb.FDB) Arrays(java.util.Arrays) FDBTestBase(com.apple.foundationdb.FDBTestBase) Assertions.assertNull(org.junit.jupiter.api.Assertions.assertNull) CompletableFuture(java.util.concurrent.CompletableFuture) Database(com.apple.foundationdb.Database) Subspace(com.apple.foundationdb.subspace.Subspace) ArrayList(java.util.ArrayList) Transaction(com.apple.foundationdb.Transaction) Range(com.apple.foundationdb.Range) Assertions.assertFalse(org.junit.jupiter.api.Assertions.assertFalse) FDBError(com.apple.foundationdb.FDBError) ByteArrayUtil.compareUnsigned(com.apple.foundationdb.tuple.ByteArrayUtil.compareUnsigned) Tag(org.junit.jupiter.api.Tag) Assertions.assertEquals(org.junit.jupiter.api.Assertions.assertEquals) Nonnull(javax.annotation.Nonnull) ByteArrayUtil.printable(com.apple.foundationdb.tuple.ByteArrayUtil.printable) ByteArrayUtil(com.apple.foundationdb.tuple.ByteArrayUtil) KeyValue(com.apple.foundationdb.KeyValue) Tags(com.apple.test.Tags) DirectoryLayer(com.apple.foundationdb.directory.DirectoryLayer) Collectors(java.util.stream.Collectors) Test(org.junit.jupiter.api.Test) Assertions.assertArrayEquals(org.junit.jupiter.api.Assertions.assertArrayEquals) List(java.util.List) PathUtil(com.apple.foundationdb.directory.PathUtil) FDBException(com.apple.foundationdb.FDBException) Assertions.assertTrue(org.junit.jupiter.api.Assertions.assertTrue) ArrayList(java.util.ArrayList) FDBException(com.apple.foundationdb.FDBException) Range(com.apple.foundationdb.Range) CompletableFuture(java.util.concurrent.CompletableFuture) Transaction(com.apple.foundationdb.Transaction) Test(org.junit.jupiter.api.Test) Tag(org.junit.jupiter.api.Tag)

Example 59 with Transaction

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

the class RankedSetTest method concurrentAdd.

@Test
public void concurrentAdd() throws Exception {
    // 20 does go onto level 1, 30 and 40 do not. There should be no reason for them to conflict on level 0.
    RankedSet rs = newRankedSet();
    db.run(tr -> {
        rs.add(tr, Tuple.from(20).pack()).join();
        return null;
    });
    Transaction tr1 = db.createTransaction();
    if (TRACE) {
        tr1.options().setDebugTransactionIdentifier("tr1");
        tr1.options().setLogTransaction();
    }
    Transaction tr2 = db.createTransaction();
    if (TRACE) {
        tr2.options().setDebugTransactionIdentifier("tr2");
        tr2.options().setLogTransaction();
    }
    rs.add(tr1, Tuple.from(30).pack()).join();
    rs.add(tr2, Tuple.from(40).pack()).join();
    tr1.commit().join();
    tr2.commit().join();
    db.read(tr -> {
        assertEquals(0L, rs.rank(tr, Tuple.from(20).pack()).join().longValue());
        assertEquals(1L, rs.rank(tr, Tuple.from(30).pack()).join().longValue());
        assertEquals(2L, rs.rank(tr, Tuple.from(40).pack()).join().longValue());
        return null;
    });
}
Also used : Transaction(com.apple.foundationdb.Transaction) Test(org.junit.jupiter.api.Test)

Example 60 with Transaction

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

the class RankedSetTest method concurrentRemove.

@Test
public void concurrentRemove() throws Exception {
    RankedSet rs = newRankedSet();
    db.run(tr -> {
        // Create a higher level entry.
        rs.add(tr, Tuple.from(20).pack()).join();
        return null;
    });
    Transaction tr1 = db.createTransaction();
    if (TRACE) {
        tr1.options().setDebugTransactionIdentifier("tr1");
        tr1.options().setLogTransaction();
    }
    Transaction tr2 = db.createTransaction();
    if (TRACE) {
        tr2.options().setDebugTransactionIdentifier("tr2");
        tr2.options().setLogTransaction();
    }
    // Will remove from all levels.
    rs.remove(tr1, Tuple.from(20).pack()).join();
    // Needs to increment the leftmost entry, not the one being removed.
    rs.add(tr2, Tuple.from(30).pack()).join();
    tr1.commit().join();
    assertThrows(CompletionException.class, () -> tr2.commit().join());
    db.run(tr -> {
        rs.add(tr, Tuple.from(30).pack()).join();
        return null;
    });
    db.read(tr -> {
        // If the overlapping commit had succeeded, it would have incremented the 20 entry at level 1, so 20 would be returned here.
        assertEquals(30, Tuple.fromBytes(rs.getNth(tr, 0).join()).getLong(0));
        return null;
    });
}
Also used : Transaction(com.apple.foundationdb.Transaction) Test(org.junit.jupiter.api.Test)

Aggregations

Transaction (com.apple.foundationdb.Transaction)84 ReadTransaction (com.apple.foundationdb.ReadTransaction)34 Tuple (com.apple.foundationdb.tuple.Tuple)34 Test (org.junit.jupiter.api.Test)33 Nonnull (javax.annotation.Nonnull)28 ArrayList (java.util.ArrayList)26 List (java.util.List)26 CompletableFuture (java.util.concurrent.CompletableFuture)26 AsyncUtil (com.apple.foundationdb.async.AsyncUtil)22 Subspace (com.apple.foundationdb.subspace.Subspace)21 Collectors (java.util.stream.Collectors)19 Nullable (javax.annotation.Nullable)19 KeyValue (com.apple.foundationdb.KeyValue)18 Map (java.util.Map)18 KeyValueLogMessage (com.apple.foundationdb.record.logging.KeyValueLogMessage)17 Range (com.apple.foundationdb.Range)16 RecordCoreException (com.apple.foundationdb.record.RecordCoreException)16 AtomicReference (java.util.concurrent.atomic.AtomicReference)16 Collections (java.util.Collections)15 RecordCursor (com.apple.foundationdb.record.RecordCursor)14