示例#1
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 ^_^");
        }