コード例 #1
0
        public async Task Test_CommittedVersion_On_ReadOnly_Transactions()
        {
            //note: until CommitAsync() is called, the value of the committed version is unspecified, but current implementation returns -1

            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    long ver = tr.GetCommittedVersion();
                    Assert.That(ver, Is.EqualTo(-1), "Initial committed version");

                    var _ = await tr.GetAsync(location.Encode("foo"));

                    // until the transction commits, the committed version will stay -1
                    ver = tr.GetCommittedVersion();
                    Assert.That(ver, Is.EqualTo(-1), "Committed version after a single read");

                    // committing a read only transaction

                    await tr.CommitAsync();

                    ver = tr.GetCommittedVersion();
                    Assert.That(ver, Is.EqualTo(-1), "Read-only comiitted transaction have a committed version of -1");
                }

                db.Debug_Dump();
            }
        }
コード例 #2
0
        public async Task Test_CommittedVersion_On_Write_Transactions()
        {
            //note: until CommitAsync() is called, the value of the committed version is unspecified, but current implementation returns -1

            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    // take the read version (to compare with the committed version below)
                    long readVersion = await tr.GetReadVersionAsync();

                    long ver = tr.GetCommittedVersion();
                    Assert.That(ver, Is.EqualTo(-1), "Initial committed version");

                    tr.Set(location.Encode("foo"), Slice.FromString("bar"));

                    // until the transction commits, the committed version should still be -1
                    ver = tr.GetCommittedVersion();
                    Assert.That(ver, Is.EqualTo(-1), "Committed version after a single write");

                    // committing a read only transaction

                    await tr.CommitAsync();

                    ver = tr.GetCommittedVersion();
                    Assert.That(ver, Is.GreaterThanOrEqualTo(readVersion), "Committed version of write transaction should be >= the read version");
                }

                db.Debug_Dump();
            }
        }
コード例 #3
0
        public async Task Test_Atomic()
        {
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                var key1  = location.Encode(1);
                var key2  = location.Encode(2);
                var key16 = location.Encode(16);

                for (int i = 0; i < 10; i++)
                {
                    using (var tr = db.BeginTransaction(this.Cancellation))
                    {
                        tr.AtomicAdd(key1, Slice.FromFixed64(1));
                        tr.AtomicAdd(key2, Slice.FromFixed64(2));
                        tr.AtomicAdd(key16, Slice.FromFixed64(16));

                        await tr.CommitAsync();
                    }
                }

                db.Debug_Dump();

                // Collect memory
                Trace.WriteLine("### GARBAGE COLLECT! ###");
                db.Collect();
                db.Debug_Dump();
            }
        }
コード例 #4
0
        public async Task Test_Use_Simple_Layer()
        {
            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                var location = db.GlobalSpace;

                var map   = new FdbMap <int, string>("Foos", db.GlobalSpace.Partition.ByKey("Foos"), KeyValueEncoders.Values.StringEncoder);
                var index = new FdbIndex <int, string>("Foos.ByColor", db.GlobalSpace.Partition.ByKey("Foos", "Color"));

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    map.Set(tr, 3, @"{ ""name"": ""Juliet"", ""color"": ""red"" }");
                    map.Set(tr, 2, @"{ ""name"": ""Joey"", ""color"": ""blue"" }");
                    map.Set(tr, 1, @"{ ""name"": ""Bob"", ""color"": ""red"" }");

                    index.Add(tr, 3, "red");
                    index.Add(tr, 2, "blue");
                    index.Add(tr, 1, "red");

                    await tr.CommitAsync();
                }

                db.Debug_Dump(true);

                //// Collect memory
                //Trace.WriteLine("### GARBAGE COLLECT! ###");
                //db.Collect();
                //db.Debug_Dump();
            }
        }
コード例 #5
0
        public async Task Test_GetKey()
        {
            Slice key;
            Slice value;

            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    tr.Set(db.Pack(0), Slice.FromString("first"));
                    tr.Set(db.Pack(10), Slice.FromString("ten"));
                    tr.Set(db.Pack(20), Slice.FromString("ten ten"));
                    tr.Set(db.Pack(42), Slice.FromString("narf!"));
                    tr.Set(db.Pack(100), Slice.FromString("a hundred missipis"));
                    await tr.CommitAsync();
                }

                db.Debug_Dump();

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    value = await tr.GetAsync(db.Pack(42));

                    Console.WriteLine(value);
                    Assert.That(value.ToString(), Is.EqualTo("narf!"));

                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterOrEqual(db.Pack(42)));

                    Assert.That(key, Is.EqualTo(db.Pack(42)));

                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(db.Pack(42)));

                    Assert.That(key, Is.EqualTo(db.Pack(100)));

                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessOrEqual(db.Pack(42)));

                    Assert.That(key, Is.EqualTo(db.Pack(42)));

                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessThan(db.Pack(42)));

                    Assert.That(key, Is.EqualTo(db.Pack(20)));

                    var keys = await tr.GetKeysAsync(new[]
                    {
                        FdbKeySelector.FirstGreaterOrEqual(db.Pack(42)),
                        FdbKeySelector.FirstGreaterThan(db.Pack(42)),
                        FdbKeySelector.LastLessOrEqual(db.Pack(42)),
                        FdbKeySelector.LastLessThan(db.Pack(42))
                    });

                    Assert.That(keys.Length, Is.EqualTo(4));
                    Assert.That(keys[0], Is.EqualTo(db.Pack(42)));
                    Assert.That(keys[1], Is.EqualTo(db.Pack(100)));
                    Assert.That(keys[2], Is.EqualTo(db.Pack(42)));
                    Assert.That(keys[3], Is.EqualTo(db.Pack(20)));

                    await tr.CommitAsync();
                }
            }
        }
コード例 #6
0
        public async Task Test_Compare_Implementations()
        {
            for (int mode = 1; mode <= 6; mode++)
            {
                Console.WriteLine("#### SCENARIO " + mode + " ####");

                using (var db = await Fdb.OpenAsync(this.Cancellation))
                {
                    using (var tr = db.BeginTransaction(this.Cancellation))
                    {
                        await tr.GetReadVersionAsync();

                        switch (mode)
                        {
                        case 1: await Scenario1(tr); break;

                        case 2: await Scenario2(tr); break;

                        case 3: await Scenario3(tr); break;

                        case 4: await Scenario4(tr); break;

                        case 5: await Scenario5(tr); break;

                        case 6: await Scenario6(tr); break;
                        }

                        await tr.CommitAsync();
                    }
                }

                using (var db = MemoryDatabase.CreateNew("DB"))
                {
                    using (var tr = db.BeginTransaction(FdbTransactionMode.Default, this.Cancellation))
                    {
                        await tr.GetReadVersionAsync();

                        switch (mode)
                        {
                        case 1: await Scenario1(tr); break;

                        case 2: await Scenario2(tr); break;

                        case 3: await Scenario3(tr); break;

                        case 4: await Scenario4(tr); break;

                        case 5: await Scenario5(tr); break;

                        case 6: await Scenario6(tr); break;
                        }

                        await tr.CommitAsync();
                    }

                    db.Debug_Dump();
                }
            }
        }
コード例 #7
0
        public async Task Test_Can_BulkLoad_Data_Random_Unordered()
        {
            const int N = 1 * 1000 * 1000;

            // insert N randomized items

            Console.WriteLine("Warmup...");
            using (var db = MemoryDatabase.CreateNew("WARMUP"))
            {
                await db.BulkLoadAsync(Enumerable.Range(0, 100).Select(i => new KeyValuePair <Slice, Slice>(db.Keys.Encode(i), Slice.FromFixed32(i))).ToList(), ordered : false);
            }

            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                var location = db.Keys;

                Console.WriteLine("Generating " + N.ToString("N0") + " keys...");
                var data = new KeyValuePair <Slice, Slice> [N];
                var ints = new int[N];
                var rnd  = new Random();
                for (int i = 0; i < N; i++)
                {
                    data[i] = new KeyValuePair <Slice, Slice>(
                        location.Encode(i),
                        Slice.FromFixed32(i)
                        );
                    ints[i] = rnd.Next(int.MaxValue);
                }
                Console.WriteLine("Shuffling...");
                Array.Sort(ints, data);

                Console.WriteLine("Inserting ...");

                var sw = Stopwatch.StartNew();
                await db.BulkLoadAsync(data, ordered : false);

                sw.Stop();
                DumpResult("BulkLoadRndSort", N, 1, sw.Elapsed);

                db.Debug_Dump();

                for (int i = 0; i < 100 * 1000; i++)
                {
                    int x = rnd.Next(N);
                    using (var tx = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        var res = await tx.GetAsync(location.Encode(x)).ConfigureAwait(false);

                        Assert.That(res.ToInt32(), Is.EqualTo(x));
                    }
                }
            }
        }
コード例 #8
0
        public async Task Test_Can_BulkLoad_Data_Sequential_Unordered()
        {
            const int N = 1 * 1000 * 1000;

            // insert N sequential items, but without specifying "ordered = true" to force a sort of all levels

            Console.WriteLine("Warmup...");
            using (var db = MemoryDatabase.CreateNew("WARMUP"))
            {
                await db.BulkLoadAsync(Enumerable.Range(0, 100).Select(i => new KeyValuePair <Slice, Slice>(db.Pack(i), Slice.FromFixed32(i))).ToList(), ordered : false);
            }

            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                Console.WriteLine("Generating " + N.ToString("N0") + " keys...");
                var data = new KeyValuePair <Slice, Slice> [N];
                var rnd  = new Random();
                for (int i = 0; i < N; i++)
                {
                    data[i] = new KeyValuePair <Slice, Slice>(
                        db.Pack(i),
                        Slice.FromFixed32(i)
                        );
                }

                Console.WriteLine("Inserting ...");
                var sw = Stopwatch.StartNew();
                await db.BulkLoadAsync(data, ordered : false);

                sw.Stop();
                DumpResult("BulkLoadSeqSort", N, 1, sw.Elapsed);

                db.Debug_Dump();

                for (int i = 0; i < 100 * 1000; i++)
                {
                    int x = rnd.Next(N);
                    using (var tx = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        var res = await tx.GetAsync(db.Pack(x)).ConfigureAwait(false);

                        Assert.That(res.ToInt32(), Is.EqualTo(x));
                    }
                }
            }
        }
コード例 #9
0
        public async Task Test_Hello_World()
        {
            using (var db = MemoryDatabase.CreateNew("DB", FdbSubspace.Empty, false))
            {
                var key = db.Keys.Encode("hello");

                // v1
                await db.WriteAsync((tr) => tr.Set(key, Slice.FromString("World!")), this.Cancellation);

                db.Debug_Dump();
                var data = await db.ReadAsync((tr) => tr.GetAsync(key), this.Cancellation);

                Assert.That(data.ToUnicode(), Is.EqualTo("World!"));

                // v2
                await db.WriteAsync((tr) => tr.Set(key, Slice.FromString("Le Monde!")), this.Cancellation);

                db.Debug_Dump();
                data = await db.ReadAsync((tr) => tr.GetAsync(key), this.Cancellation);

                Assert.That(data.ToUnicode(), Is.EqualTo("Le Monde!"));

                using (var tr1 = db.BeginTransaction(this.Cancellation))
                {
                    await tr1.GetReadVersionAsync();

                    await db.WriteAsync((tr2) => tr2.Set(key, Slice.FromString("Sekai!")), this.Cancellation);

                    db.Debug_Dump();

                    data = await tr1.GetAsync(key);

                    Assert.That(data.ToUnicode(), Is.EqualTo("Le Monde!"));
                }

                data = await db.ReadAsync((tr) => tr.GetAsync(key), this.Cancellation);

                Assert.That(data.ToUnicode(), Is.EqualTo("Sekai!"));

                // Collect memory
                Trace.WriteLine("### GARBAGE COLLECT! ###");
                db.Collect();
                db.Debug_Dump();
            }
        }
コード例 #10
0
        public async Task Test_CommittedVersion_After_Reset()
        {
            //note: until CommitAsync() is called, the value of the committed version is unspecified, but current implementation returns -1

            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    // take the read version (to compare with the committed version below)
                    long rv1 = await tr.GetReadVersionAsync();

                    // do something and commit
                    tr.Set(location.Encode("foo"), Slice.FromString("bar"));
                    await tr.CommitAsync();

                    long cv1 = tr.GetCommittedVersion();
                    Console.WriteLine("COMMIT: " + rv1 + " / " + cv1);
                    Assert.That(cv1, Is.GreaterThanOrEqualTo(rv1), "Committed version of write transaction should be >= the read version");

                    // reset the transaction
                    tr.Reset();

                    long rv2 = await tr.GetReadVersionAsync();

                    long cv2 = tr.GetCommittedVersion();
                    Console.WriteLine("RESET: " + rv2 + " / " + cv2);
                    //Note: the current fdb_c client does not revert the commited version to -1 ... ?
                    //Assert.That(cv2, Is.EqualTo(-1), "Committed version should go back to -1 after reset");

                    // read-only + commit
                    await tr.GetAsync(location.Encode("foo"));

                    await tr.CommitAsync();

                    cv2 = tr.GetCommittedVersion();
                    Console.WriteLine("COMMIT2: " + rv2 + " / " + cv2);
                    Assert.That(cv2, Is.EqualTo(-1), "Committed version of read-only transaction should be -1 even the transaction was previously used to write something");
                }
            }
        }
コード例 #11
0
        public async Task Test_Use_Directory_Layer()
        {
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var foos = await db.Directory.CreateOrOpenAsync("Foos", this.Cancellation);

                var bars = await db.Directory.CreateOrOpenAsync("Bars", this.Cancellation);

                var foo123 = await db.Directory.CreateOrOpenAsync(new[] { "Foos", "123" }, this.Cancellation);

                var bar456 = await bars.CreateOrOpenAsync(db, new[] { "123" }, this.Cancellation);

                db.Debug_Dump(true);

                //// Collect memory
                //Trace.WriteLine("### GARBAGE COLLECT! ###");
                //db.Collect();
                //db.Debug_Dump();
            }
        }
コード例 #12
0
        public async Task MiniBench()
        {
            const int M       = 1 * 1000 * 1000;
            const int B       = 100;
            const int ENTROPY = 10 * 1000;

            const int  T         = M / B;
            const int  KEYSIZE   = 10;
            const int  VALUESIZE = 100;
            const bool RANDOM    = false;

            var rnd = new Random();

            //WARMUP
            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                await db.WriteAsync((tr) => tr.Set(db.Keys.Encode("hello"), Slice.FromString("world")), this.Cancellation);

                Slice.Random(rnd, KEYSIZE);
                Slice.Random(rnd, VALUESIZE);
            }

            Log("Inserting {0}-bytes {1} keys / {2}-bytes values, in {3:N0} transactions", KEYSIZE, RANDOM ? "random" : "ordered", VALUESIZE, T);

            bool   random = RANDOM;
            string fmt    = "D" + KEYSIZE;

            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                DumpMemory(collect: true);

                long total = 0;

                var payload = new byte[ENTROPY + VALUESIZE];
                rnd.NextBytes(payload);
                // help with compression by doubling every byte
                for (int i = 0; i < payload.Length; i += 2)
                {
                    payload[i + 1] = payload[i];
                }

                var sw = Stopwatch.StartNew();
                sw.Stop();

                sw.Restart();
                for (int i = 0; i < T; i++)
                {
                    using (var tr = db.BeginTransaction(this.Cancellation))
                    {
                        for (int j = 0; j < B; j++)
                        {
                            Slice key;
                            if (random)
                            {
                                do
                                {
                                    key = Slice.Random(rnd, KEYSIZE);
                                }while (key[0] == 255);
                            }
                            else
                            {
                                int x = i * B + j;
                                //x = x % 1000;
                                key = Slice.FromString(x.ToString(fmt));
                            }

                            tr.Set(key, Slice.Create(payload, rnd.Next(ENTROPY), VALUESIZE));
                            Interlocked.Increment(ref total);
                        }
                        await tr.CommitAsync().ConfigureAwait(false);
                    }
                    if (i % 1000 == 0)
                    {
                        Console.Write(".");                                   // + (i * B).ToString("D10"));
                    }
                }

                sw.Stop();
                Log("done");
                Log("* Inserted: {0:N0} keys", total);
                Log("* Elapsed : {0:N3} sec", sw.Elapsed.TotalSeconds);
                Log("* TPS: {0:N0} transactions/sec", T / sw.Elapsed.TotalSeconds);
                Log("* KPS: {0:N0} keys/sec", total / sw.Elapsed.TotalSeconds);
                Log("* BPS: {0:N0} bytes/sec", (total * (KEYSIZE + VALUESIZE)) / sw.Elapsed.TotalSeconds);

                DumpMemory(collect: true);

                db.Debug_Dump(false);

                DumpResult("WriteSeq" + B, total, total / B, sw.Elapsed);

                string path = @".\\minibench.pndb";
                Log("Saving {0} ...", path);
                sw.Restart();
                await db.SaveSnapshotAsync(path);

                sw.Stop();
                Log("* Saved {0:N0} bytes in {1:N3} sec", new System.IO.FileInfo(path).Length, sw.Elapsed.TotalSeconds);

                Log("Warming up reads...");
                var data = await db.GetValuesAsync(Enumerable.Range(0, 100).Select(i => Slice.FromString(i.ToString(fmt))), this.Cancellation);

                Log("Starting read tests...");

                #region sequential reads

                sw.Restart();
                for (int i = 0; i < total; i += 10)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.GetValuesAsync(Enumerable.Range(i, 10).Select(x => Slice.FromString(x.ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead10", total, total / 10, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 10)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.Snapshot.GetValuesAsync(Enumerable.Range(i, 10).Select(x => Slice.FromString(x.ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead10S", total, total / 10, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 10)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        int x = i;
                        int y = i + 10;
                        await tr.GetRangeAsync(
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(x.ToString(fmt))),
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(y.ToString(fmt)))
                            ).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead10R", total, total / 10, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 100)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.GetValuesAsync(Enumerable.Range(i, 100).Select(x => Slice.FromString(x.ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead100", total, total / 100, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 100)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.Snapshot.GetValuesAsync(Enumerable.Range(i, 100).Select(x => Slice.FromString(x.ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead100S", total, total / 100, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 100)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        int x = i;
                        int y = i + 100;
                        await tr.GetRangeAsync(
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(x.ToString(fmt))),
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(y.ToString(fmt)))
                            ).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead100R", total, total / 100, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 100)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        int x = i;
                        int y = i + 100;
                        await tr.Snapshot.GetRangeAsync(
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(x.ToString(fmt))),
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(y.ToString(fmt)))
                            ).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead100RS", total, total / 100, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 1000)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.GetValuesAsync(Enumerable.Range(i, 1000).Select(x => Slice.FromString(x.ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                DumpResult("SeqRead1k", total, total / 1000, sw.Elapsed);

                #endregion

                DumpMemory();

                #region random reads

                //sw.Restart();
                //for (int i = 0; i < total; i++)
                //{
                //	using (var tr = db.BeginReadOnlyTransaction())
                //	{
                //		int x = rnd.Next((int)total);
                //		await tr.GetAsync(Slice.FromString(x.ToString(fmt)));
                //	}
                //}
                //sw.Stop();
                //Log("RndRead1   : " + total.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (total / sw.Elapsed.TotalSeconds).ToString("N0") + " kps");

                sw.Restart();
                for (int i = 0; i < total; i += 10)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.GetValuesAsync(Enumerable.Range(i, 10).Select(x => Slice.FromString(rnd.Next((int)total).ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                //Log("RndRead10  : " + total.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (total / sw.Elapsed.TotalSeconds).ToString("N0") + " kps, " + (total / (10 * sw.Elapsed.TotalSeconds)).ToString("N0") + " tps");
                DumpResult("RndRead10", total, total / 10, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 10)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.Snapshot.GetValuesAsync(Enumerable.Range(i, 10).Select(x => Slice.FromString(rnd.Next((int)total).ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                //Log("RndRead10S : " + total.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (total / sw.Elapsed.TotalSeconds).ToString("N0") + " kps, " + (total / (10 * sw.Elapsed.TotalSeconds)).ToString("N0") + " tps");
                DumpResult("RndRead10S", total, total / 10, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 10)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        int x = rnd.Next((int)total - 10);
                        int y = x + 10;
                        await tr.GetRangeAsync(
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(x.ToString(fmt))),
                            FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(y.ToString(fmt)))
                            ).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                //Log("RndRead10R : " + total.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (total / sw.Elapsed.TotalSeconds).ToString("N0") + " kps, " + (total / (10 * sw.Elapsed.TotalSeconds)).ToString("N0") + " tps");
                DumpResult("RndRead10R", total, total / 10, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 100)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.GetValuesAsync(Enumerable.Range(i, 100).Select(x => Slice.FromString(rnd.Next((int)total).ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                //Log("RndRead100 : " + total.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (total / sw.Elapsed.TotalSeconds).ToString("N0") + " kps, " + (total / (100 * sw.Elapsed.TotalSeconds)).ToString("N0") + " tps");
                DumpResult("RndRead100", total, total / 100, sw.Elapsed);

                sw.Restart();
                for (int i = 0; i < total; i += 1000)
                {
                    using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        await tr.GetValuesAsync(Enumerable.Range(i, 1000).Select(x => Slice.FromString(rnd.Next((int)total).ToString(fmt)))).ConfigureAwait(false);
                    }
                }
                sw.Stop();
                //Log("RndRead1k  : " + total.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (total / sw.Elapsed.TotalSeconds).ToString("N0") + " kps, " + (total / (1000 * sw.Elapsed.TotalSeconds)).ToString("N0") + " tps");
                DumpResult("RndRead1k", total, total / 1000, sw.Elapsed);

                #endregion

                DumpMemory();

                #region Parallel Reads...

                int CPUS = Environment.ProcessorCount;

                long read  = 0;
                var  mre   = new ManualResetEvent(false);
                var  tasks = Enumerable
                             .Range(0, CPUS)
                             .Select(k => Task.Run(async() =>
                {
                    var rndz = new Random(k);
                    mre.WaitOne();

                    int keys = 0;
                    for (int j = 0; j < 20; j++)
                    {
                        for (int i = 0; i < total / CPUS; i += 100)
                        {
                            int pp = i;                                    // rndz.Next((int)total - 10);
                            using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                            {
                                var res = await tr.GetValuesAsync(Enumerable.Range(i, 100).Select(x => Slice.FromString((pp + x).ToString(fmt)))).ConfigureAwait(false);
                                keys   += res.Length;
                            }
                        }
                    }
                    Interlocked.Add(ref read, keys);
                    return(keys);
                })).ToArray();

                sw.Restart();
                mre.Set();
                await Task.WhenAll(tasks);

                sw.Stop();
                mre.Dispose();
                //Log("ParaSeqRead: " + read.ToString("N0") + " keys in " + sw.Elapsed.TotalSeconds.ToString("N3") + " sec => " + (read / sw.Elapsed.TotalSeconds).ToString("N0") + " kps");
                DumpResult("ParaSeqRead", read, read / 100, sw.Elapsed);

                read  = 0;
                mre   = new ManualResetEvent(false);
                tasks = Enumerable
                        .Range(0, CPUS)
                        .Select(k => Task.Run(async() =>
                {
                    var rndz = new Random(k);
                    mre.WaitOne();

                    int keys = 0;
                    for (int j = 0; j < 20; j++)
                    {
                        for (int i = 0; i < total / CPUS; i += 100)
                        {
                            int pp = i;                                    // rndz.Next((int)total - 100);
                            using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                            {
                                var res = await tr.GetRangeAsync(
                                    FdbKeySelector.FirstGreaterOrEqual(Slice.FromString(pp.ToString(fmt))),
                                    FdbKeySelector.FirstGreaterOrEqual(Slice.FromString((pp + 100).ToString(fmt)))
                                    ).ConfigureAwait(false);

                                keys += res.Count;
                            }
                        }
                    }
                    Interlocked.Add(ref read, keys);
                    return(keys);
                })).ToArray();

                sw.Restart();
                mre.Set();
                await Task.WhenAll(tasks);

                sw.Stop();
                mre.Dispose();
                DumpResult("ParaSeqRange", read, read / 100, sw.Elapsed);
                #endregion

                DumpMemory();
            }
        }
コード例 #13
0
        public async Task Test_GetKey_ReadConflicts()
        {
            Slice key;

            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    tr.Set(location.Encode(42), Slice.FromString("42"));
                    tr.Set(location.Encode(50), Slice.FromString("50"));
                    tr.Set(location.Encode(60), Slice.FromString("60"));
                    await tr.CommitAsync();
                }
                db.Debug_Dump();

                Func <FdbKeySelector, Slice, Task> check = async(selector, expected) =>
                {
                    using (var tr = db.BeginTransaction(this.Cancellation))
                    {
                        key = await tr.GetKeyAsync(selector);

                        await tr.CommitAsync();

                        Assert.That(key, Is.EqualTo(expected), selector.ToString() + " => " + FdbKey.Dump(expected));
                    }
                };

                await check(
                    FdbKeySelector.FirstGreaterOrEqual(location.Encode(50)),
                    location.Encode(50)
                    );
                await check(
                    FdbKeySelector.FirstGreaterThan(location.Encode(50)),
                    location.Encode(60)
                    );

                await check(
                    FdbKeySelector.FirstGreaterOrEqual(location.Encode(49)),
                    location.Encode(50)
                    );
                await check(
                    FdbKeySelector.FirstGreaterThan(location.Encode(49)),
                    location.Encode(50)
                    );

                await check(
                    FdbKeySelector.FirstGreaterOrEqual(location.Encode(49)) + 1,
                    location.Encode(60)
                    );
                await check(
                    FdbKeySelector.FirstGreaterThan(location.Encode(49)) + 1,
                    location.Encode(60)
                    );

                await check(
                    FdbKeySelector.LastLessOrEqual(location.Encode(49)),
                    location.Encode(42)
                    );
                await check(
                    FdbKeySelector.LastLessThan(location.Encode(49)),
                    location.Encode(42)
                    );
            }
        }
コード例 #14
0
        public async Task Test_Can_Save_And_Reload_Snapshot()
        {
            const string FILE_PATH = ".\\test.pndb";
            const int    N         = 1 * 1000 * 1000;

            if (File.Exists(FILE_PATH))
            {
                File.Delete(FILE_PATH);
            }

            // insert N sequential items and bulk load with "ordered = true" to skip the sorting of levels

            Console.WriteLine("Generating " + N.ToString("N0") + " keys...");
            var data = new KeyValuePair <Slice, Slice> [N];
            var rnd  = new Random();

            for (int i = 0; i < N; i++)
            {
                data[i] = new KeyValuePair <Slice, Slice>(
                    Slice.FromAscii(i.ToString("D16")),
                    Slice.Random(rnd, 50)
                    );
            }

            var sw = new Stopwatch();

            using (var db = MemoryDatabase.CreateNew())
            {
                Console.Write("Inserting ...");
                sw.Restart();
                await db.BulkLoadAsync(data, ordered : true);

                sw.Stop();
                Console.WriteLine(" done in " + sw.Elapsed.TotalSeconds.ToString("N1") + " secs");

                db.Debug_Dump();

                Console.Write("Saving...");
                sw.Restart();
                await db.SaveSnapshotAsync(FILE_PATH, null, this.Cancellation);

                sw.Stop();
                Console.WriteLine(" done in " + sw.Elapsed.TotalSeconds.ToString("N1") + " secs");
            }

            var fi = new FileInfo(FILE_PATH);

            Assert.That(fi.Exists, Is.True, "Snapshot file not found");
            Console.WriteLine("File size is " + fi.Length.ToString("N0") + " bytes (" + (fi.Length * 1.0d / N).ToString("N2") + " bytes/item, " + (fi.Length / (1048576.0 * sw.Elapsed.TotalSeconds)).ToString("N3") + " MB/sec)");

            Console.Write("Loading...");
            sw.Restart();
            using (var db = await MemoryDatabase.LoadFromAsync(FILE_PATH, this.Cancellation))
            {
                sw.Stop();
                Console.WriteLine(" done in " + sw.Elapsed.TotalSeconds.ToString("N1") + " secs (" + (fi.Length / (1048576.0 * sw.Elapsed.TotalSeconds)).ToString("N0") + " MB/sec)");
                db.Debug_Dump();

                Console.WriteLine("Checking data integrity...");
                sw.Restart();
                long n = 0;
                foreach (var batch in data.Buffered(50 * 1000))
                {
                    using (var tx = db.BeginReadOnlyTransaction(this.Cancellation))
                    {
                        var res = await tx
                                  .Snapshot
                                  .GetRange(
                            FdbKeySelector.FirstGreaterOrEqual(batch[0].Key),
                            FdbKeySelector.FirstGreaterThan(batch[batch.Count - 1].Key))
                                  .ToListAsync()
                                  .ConfigureAwait(false);

                        Assert.That(res.Count, Is.EqualTo(batch.Count), "Some keys are missing from {0} to {1} :(", batch[0], batch[batch.Count - 1]);

                        for (int i = 0; i < res.Count; i++)
                        {
                            // note: Is.EqualTo(...) is slow on Slices so we speed things a bit
                            if (res[i].Key != batch[i].Key)
                            {
                                Assert.That(res[i].Key, Is.EqualTo(batch[i].Key), "Key is different :(");
                            }
                            if (res[i].Value != batch[i].Value)
                            {
                                Assert.That(res[i].Value, Is.EqualTo(batch[i].Value), "Value is different for key {0} :(", batch[i].Key);
                            }
                        }
                    }
                    n += batch.Count;
                    Console.Write("\r" + n.ToString("N0"));
                }
                sw.Stop();
                Console.WriteLine(" done in " + sw.Elapsed.TotalSeconds.ToString("N1") + " secs");
            }

            Console.WriteLine("Content of database are identical ^_^");
        }
コード例 #15
0
        public async Task Test_GetRangeAsync()
        {
            Slice key;

            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    for (int i = 0; i <= 100; i++)
                    {
                        tr.Set(location.Encode(i), Slice.FromString("value of " + i));
                    }
                    await tr.CommitAsync();
                }

                db.Debug_Dump();

                // verify that key selectors work find
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterOrEqual(FdbKey.MaxValue));

                    if (key != FdbKey.MaxValue)
                    {
                        Assert.Inconclusive("Key selectors are buggy: fGE(max)");
                    }
                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessOrEqual(FdbKey.MaxValue));

                    if (key != FdbKey.MaxValue)
                    {
                        Assert.Inconclusive("Key selectors are buggy: lLE(max)");
                    }
                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessThan(FdbKey.MaxValue));

                    if (key != location.Encode(100))
                    {
                        Assert.Inconclusive("Key selectors are buggy: lLT(max)");
                    }
                }

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var chunk = await tr.GetRangeAsync(
                        FdbKeySelector.FirstGreaterOrEqual(location.Encode(0)),
                        FdbKeySelector.FirstGreaterOrEqual(location.Encode(50))
                        );

#if DEBUG
                    for (int i = 0; i < chunk.Count; i++)
                    {
                        Console.WriteLine(i.ToString() + " : " + chunk.Chunk[i].Key + " = " + chunk.Chunk[i].Value);
                    }
#endif

                    Assert.That(chunk.Count, Is.EqualTo(50), "chunk.Count");
                    Assert.That(chunk.HasMore, Is.False, "chunk.HasMore");
                    Assert.That(chunk.Reversed, Is.False, "chunk.Reversed");
                    Assert.That(chunk.Iteration, Is.EqualTo(1), "chunk.Iteration");

                    for (int i = 0; i < 50; i++)
                    {
                        Assert.That(chunk.Chunk[i].Key, Is.EqualTo(location.Encode(i)), "[{0}].Key", i);
                        Assert.That(chunk.Chunk[i].Value.ToString(), Is.EqualTo("value of " + i), "[{0}].Value", i);
                    }

                    await tr.CommitAsync();
                }

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var chunk = await tr.GetRangeAsync(
                        FdbKeySelector.FirstGreaterOrEqual(location.Encode(0)),
                        FdbKeySelector.FirstGreaterOrEqual(location.Encode(50)),
                        new FdbRangeOptions { Reverse = true }
                        );

#if DEBUG
                    for (int i = 0; i < chunk.Count; i++)
                    {
                        Console.WriteLine(i.ToString() + " : " + chunk.Chunk[i].Key + " = " + chunk.Chunk[i].Value);
                    }
#endif

                    Assert.That(chunk.Count, Is.EqualTo(50), "chunk.Count");
                    Assert.That(chunk.HasMore, Is.False, "chunk.HasMore");
                    Assert.That(chunk.Reversed, Is.True, "chunk.Reversed");
                    Assert.That(chunk.Iteration, Is.EqualTo(1), "chunk.Iteration");

                    for (int i = 0; i < 50; i++)
                    {
                        Assert.That(chunk.Chunk[i].Key, Is.EqualTo(location.Encode(49 - i)), "[{0}].Key", i);
                        Assert.That(chunk.Chunk[i].Value.ToString(), Is.EqualTo("value of " + (49 - i)), "[{0}].Value", i);
                    }

                    await tr.CommitAsync();
                }

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var chunk = await tr.GetRangeAsync(
                        FdbKeySelector.FirstGreaterOrEqual(location.Encode(0)),
                        FdbKeySelector.FirstGreaterOrEqual(FdbKey.MaxValue),
                        new FdbRangeOptions { Reverse = true, Limit = 1 }
                        );

#if DEBUG
                    for (int i = 0; i < chunk.Count; i++)
                    {
                        Console.WriteLine(i.ToString() + " : " + chunk.Chunk[i].Key + " = " + chunk.Chunk[i].Value);
                    }
#endif

                    Assert.That(chunk.Count, Is.EqualTo(1), "chunk.Count");
                    Assert.That(chunk.HasMore, Is.True, "chunk.HasMore");
                    Assert.That(chunk.Reversed, Is.True, "chunk.Reversed");
                    Assert.That(chunk.Iteration, Is.EqualTo(1), "chunk.Iteration");

                    await tr.CommitAsync();
                }
            }
        }
コード例 #16
0
        public async Task Test_Can_Resolve_Key_Selector_Outside_Boundaries()
        {
            // test various corner cases:

            // - k < first_key or k <= <00> resolves to:
            //   - '' always

            // - k > last_key or k >= <FF> resolve to:
            //	 - '<FF>' when access to system keys is off
            //   - '<FF>/backupRange' (usually) when access to system keys is ON

            // - k >= <FF><00> resolves to:
            //   - key_outside_legal_range when access to system keys is off
            //   - '<FF>/backupRange' (usually) when access to system keys is ON

            // - k >= <FF><FF> resolved to:
            //   - key_outside_legal_range when access to system keys is off
            //   - '<FF><FF>' when access to system keys is ON

            Slice key;

            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    tr.Set(Slice.FromString("A"), Slice.FromString("min"));
                    tr.Set(Slice.FromString("Z"), Slice.FromString("max"));
                    await tr.CommitAsync();
                }

                using (var tr = db.BeginReadOnlyTransaction(this.Cancellation))
                {
                    // before <00>
                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessThan(FdbKey.MinValue));

                    Assert.That(key, Is.EqualTo(Slice.Empty), "lLT(<00>) => ''");

                    // before the first key in the db
                    var minKey = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterOrEqual(FdbKey.MinValue));

                    Assert.That(minKey, Is.Not.Null);
                    Console.WriteLine("minKey = " + minKey);
                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessThan(minKey));

                    Assert.That(key, Is.EqualTo(Slice.Empty), "lLT(min_key) => ''");

                    // after the last key in the db

                    var maxKey = await tr.GetKeyAsync(FdbKeySelector.LastLessThan(FdbKey.MaxValue));

                    Assert.That(maxKey, Is.Not.Null);
                    Console.WriteLine("maxKey = " + maxKey);
                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(maxKey));

                    Assert.That(key, Is.EqualTo(FdbKey.MaxValue), "fGT(maxKey) => <FF>");

                    // after <FF>
                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(FdbKey.MaxValue));

                    Assert.That(key, Is.EqualTo(FdbKey.MaxValue), "fGT(<FF>) => <FF>");
                    Assert.That(async() => await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(Slice.FromAscii("\xFF\xFF"))), Throws.InstanceOf <FdbException>().With.Property("Code").EqualTo(FdbError.KeyOutsideLegalRange));
                    Assert.That(async() => await tr.GetKeyAsync(FdbKeySelector.LastLessThan(Slice.FromAscii("\xFF\x00"))), Throws.InstanceOf <FdbException>().With.Property("Code").EqualTo(FdbError.KeyOutsideLegalRange));

                    tr.WithReadAccessToSystemKeys();

                    var firstSystemKey = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(FdbKey.MaxValue));

                    // usually the first key in the system space is <FF>/backupDataFormat, but that may change in the future version.
                    Assert.That(firstSystemKey, Is.Not.Null);
                    Assert.That(firstSystemKey, Is.GreaterThan(FdbKey.MaxValue), "key should be between <FF> and <FF><FF>");
                    Assert.That(firstSystemKey, Is.LessThan(Slice.FromAscii("\xFF\xFF")), "key should be between <FF> and <FF><FF>");

                    // with access to system keys, the maximum possible key becomes <FF><FF>
                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterOrEqual(Slice.FromAscii("\xFF\xFF")));

                    Assert.That(key, Is.EqualTo(Slice.FromAscii("\xFF\xFF")), "fGE(<FF><FF>) => <FF><FF> (with access to system keys)");
                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(Slice.FromAscii("\xFF\xFF")));

                    Assert.That(key, Is.EqualTo(Slice.FromAscii("\xFF\xFF")), "fGT(<FF><FF>) => <FF><FF> (with access to system keys)");

                    key = await tr.GetKeyAsync(FdbKeySelector.LastLessThan(Slice.FromAscii("\xFF\x00")));

                    Assert.That(key, Is.EqualTo(maxKey), "lLT(<FF><00>) => max_key (with access to system keys)");
                    key = await tr.GetKeyAsync(FdbKeySelector.FirstGreaterThan(maxKey));

                    Assert.That(key, Is.EqualTo(firstSystemKey), "fGT(max_key) => first_system_key (with access to system keys)");
                }
            }
        }
コード例 #17
0
        public async Task Test_GetRange()
        {
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    for (int i = 0; i <= 100; i++)
                    {
                        tr.Set(location.Encode(i), Slice.FromString("value of " + i));
                    }
                    await tr.CommitAsync();
                }

                db.Debug_Dump();

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var results = await tr
                                  .GetRange(location.Encode(0), location.Encode(50))
                                  .ToListAsync();

                    Assert.That(results, Is.Not.Null);
#if DEBUG
                    for (int i = 0; i < results.Count; i++)
                    {
                        Console.WriteLine(i.ToString() + " : " + results[i].Key + " = " + results[i].Value);
                    }
#endif

                    Assert.That(results.Count, Is.EqualTo(50));
                    for (int i = 0; i < 50; i++)
                    {
                        Assert.That(results[i].Key, Is.EqualTo(location.Encode(i)), "[{0}].Key", i);
                        Assert.That(results[i].Value.ToString(), Is.EqualTo("value of " + i), "[{0}].Value", i);
                    }

                    await tr.CommitAsync();
                }

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var results = await tr
                                  .GetRange(location.Encode(0), location.Encode(50), new FdbRangeOptions { Reverse = true })
                                  .ToListAsync();

                    Assert.That(results, Is.Not.Null);
#if DEBUG
                    for (int i = 0; i < results.Count; i++)
                    {
                        Console.WriteLine(i.ToString() + " : " + results[i].Key + " = " + results[i].Value);
                    }
#endif

                    Assert.That(results.Count, Is.EqualTo(50));
                    for (int i = 0; i < 50; i++)
                    {
                        Assert.That(results[i].Key, Is.EqualTo(location.Encode(49 - i)), "[{0}].Key", i);
                        Assert.That(results[i].Value.ToString(), Is.EqualTo("value of " + (49 - i)), "[{0}].Value", i);
                    }

                    await tr.CommitAsync();
                }

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var result = await tr
                                 .GetRange(location.Encode(0), FdbKey.MaxValue, new FdbRangeOptions { Reverse = true })
                                 .FirstOrDefaultAsync();

#if DEBUG
                    Console.WriteLine(result.Key + " = " + result.Value);
#endif
                    Assert.That(result.Key, Is.EqualTo(location.Encode(100)));
                    Assert.That(result.Value.ToString(), Is.EqualTo("value of 100"));

                    await tr.CommitAsync();
                }
            }
        }
コード例 #18
0
        public async Task Test_Write_Then_Read()
        {
            using (var db = MemoryDatabase.CreateNew("FOO"))
            {
                var location = db.Keys;

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    tr.Set(Slice.FromString("hello"), Slice.FromString("World!"));
                    tr.AtomicAdd(Slice.FromString("counter"), Slice.FromFixed32(1));
                    tr.Set(Slice.FromString("foo"), Slice.FromString("bar"));
                    await tr.CommitAsync();
                }

                db.Debug_Dump();

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var result = await tr.GetAsync(Slice.FromString("hello"));

                    Assert.That(result, Is.Not.Null);
                    Assert.That(result.ToString(), Is.EqualTo("World!"));

                    result = await tr.GetAsync(Slice.FromString("counter"));

                    Assert.That(result, Is.Not.Null);
                    Assert.That(result.ToInt32(), Is.EqualTo(1));

                    result = await tr.GetAsync(Slice.FromString("foo"));

                    Assert.That(result.ToString(), Is.EqualTo("bar"));
                }

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    tr.Set(Slice.FromString("hello"), Slice.FromString("Le Monde!"));
                    tr.AtomicAdd(Slice.FromString("counter"), Slice.FromFixed32(1));
                    tr.Set(Slice.FromString("narf"), Slice.FromString("zort"));
                    await tr.CommitAsync();
                }

                db.Debug_Dump();

                using (var tr = db.BeginTransaction(this.Cancellation))
                {
                    var result = await tr.GetAsync(Slice.FromString("hello"));

                    Assert.That(result, Is.Not.Null);
                    Assert.That(result.ToString(), Is.EqualTo("Le Monde!"));

                    result = await tr.GetAsync(Slice.FromString("counter"));

                    Assert.That(result, Is.Not.Null);
                    Assert.That(result.ToInt32(), Is.EqualTo(2));

                    result = await tr.GetAsync(Slice.FromString("foo"));

                    Assert.That(result, Is.Not.Null);
                    Assert.That(result.ToString(), Is.EqualTo("bar"));

                    result = await tr.GetAsync(Slice.FromString("narf"));

                    Assert.That(result, Is.Not.Null);
                    Assert.That(result.ToString(), Is.EqualTo("zort"));
                }

                // Collect memory
                Trace.WriteLine("### GARBAGE COLLECT! ###");
                db.Collect();
                db.Debug_Dump();
            }
        }
コード例 #19
0
        public async Task Test_Conflicts()
        {
            // this SHOULD NOT conflict
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr1 = db.BeginTransaction(this.Cancellation))
                {
                    using (var tr2 = db.BeginTransaction(this.Cancellation))
                    {
                        tr2.Set(location.Encode("foo"), Slice.FromString("changed"));
                        await tr2.CommitAsync();
                    }

                    var x = await tr1.GetAsync(location.Encode("foo"));

                    tr1.Set(location.Encode("bar"), Slice.FromString("other"));

                    await tr1.CommitAsync();
                }
            }

            // this SHOULD conflict
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr1 = db.BeginTransaction(this.Cancellation))
                {
                    var x = await tr1.GetAsync(location.Encode("foo"));

                    using (var tr2 = db.BeginTransaction(this.Cancellation))
                    {
                        tr2.Set(location.Encode("foo"), Slice.FromString("changed"));
                        await tr2.CommitAsync();
                    }

                    tr1.Set(location.Encode("bar"), Slice.FromString("other"));

                    Assert.That(async() => await tr1.CommitAsync(), Throws.InstanceOf <FdbException>().With.Property("Code").EqualTo(FdbError.NotCommitted));
                }
            }

            // this SHOULD conflict
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr1 = db.BeginTransaction(this.Cancellation))
                {
                    await tr1.GetReadVersionAsync();

                    using (var tr2 = db.BeginTransaction(this.Cancellation))
                    {
                        tr2.Set(location.Encode("foo"), Slice.FromString("changed"));
                        await tr2.CommitAsync();
                    }

                    var x = await tr1.GetAsync(location.Encode("foo"));

                    tr1.Set(location.Encode("bar"), Slice.FromString("other"));

                    Assert.That(async() => await tr1.CommitAsync(), Throws.InstanceOf <FdbException>().With.Property("Code").EqualTo(FdbError.NotCommitted));
                }
            }

            // this SHOULD NOT conflict
            using (var db = MemoryDatabase.CreateNew("DB"))
            {
                var location = db.Keys;

                using (var tr1 = db.BeginTransaction(this.Cancellation))
                {
                    var x = await tr1.Snapshot.GetAsync(location.Encode("foo"));

                    using (var tr2 = db.BeginTransaction(this.Cancellation))
                    {
                        tr2.Set(location.Encode("foo"), Slice.FromString("changed"));
                        await tr2.CommitAsync();
                    }

                    tr1.Set(location.Encode("bar"), Slice.FromString("other"));

                    await tr1.CommitAsync();
                }
            }
        }