예제 #1
0
        public void ObjectInMemWriteRead2()
        {
            using var session = fht.NewSession(new MyFunctions());

            var key1 = new MyKey {
                key = 8999998
            };
            var input1 = new MyInput {
                value = 23
            };
            MyOutput output = new MyOutput();

            session.RMW(ref key1, ref input1, Empty.Default, 0);

            var key2 = new MyKey {
                key = 8999999
            };
            var input2 = new MyInput {
                value = 24
            };

            session.RMW(ref key2, ref input2, Empty.Default, 0);

            session.Read(ref key1, ref input1, ref output, Empty.Default, 0);

            Assert.IsTrue(output.value.value == input1.value);

            session.Read(ref key2, ref input2, ref output, Empty.Default, 0);
            Assert.IsTrue(output.value.value == input2.value);
        }
예제 #2
0
        public void ObjectInMemWriteRead2()
        {
            var key1 = new MyKey {
                key = 8999998
            };
            var input1 = new MyInput {
                value = 23
            };
            MyOutput output = new MyOutput();

            fht.RMW(ref key1, ref input1, Empty.Default, 0);

            var key2 = new MyKey {
                key = 8999999
            };
            var input2 = new MyInput {
                value = 24
            };

            fht.RMW(ref key2, ref input2, Empty.Default, 0);

            fht.Read(ref key1, ref input1, ref output, Empty.Default, 0);

            Assert.IsTrue(output.value.value == input1.value);

            fht.Read(ref key2, ref input2, ref output, Empty.Default, 0);
            Assert.IsTrue(output.value.value == input2.value);
        }
예제 #3
0
        public void ObjectInMemWriteRead2()
        {
            var key1 = new MyKey {
                key = 8999998
            };
            var input1 = new MyInput {
                value = 23
            };

            fht.RMW(key1, input1, null, 0);

            var key2 = new MyKey {
                key = 8999999
            };
            var input2 = new MyInput {
                value = 24
            };

            fht.RMW(key2, input2, null, 0);

            MyOutput output = new MyOutput();

            fht.Read(key1, null, ref output, null, 0);

            Assert.IsTrue(output.value.value == input1.value);

            fht.Read(key2, null, ref output, null, 0);
            Assert.IsTrue(output.value.value == input2.value);
        }
        public void LogCompactBasicCustomFctnTest([Values] CompactionType compactionType)
        {
            MyInput input = new();

            const int totalRecords = 2000;
            var       compactUntil = 0L;

            for (var i = 0; i < totalRecords; i++)
            {
                if (i == totalRecords / 2)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0, 0);
            }

            compactUntil = session.Compact(compactUntil, compactionType, default(EvenCompactionFunctions));
            fht.Log.Truncate();
            Assert.AreEqual(compactUntil, fht.Log.BeginAddress);

            // Read 2000 keys - all should be present
            for (var i = 0; i < totalRecords; i++)
            {
                var output = new MyOutput();
                var key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var ctx = (i < (totalRecords / 2) && (i % 2 != 0)) ? 1 : 0;

                var status = session.Read(ref key1, ref input, ref output, ctx, 0);
                if (status.IsPending)
                {
                    session.CompletePending(true);
                }
                else
                {
                    if (ctx == 0)
                    {
                        Assert.IsTrue(status.Found);
                        Assert.AreEqual(value.value, output.value.value);
                    }
                    else
                    {
                        Assert.IsFalse(status.Found);
                    }
                }
            }
        }
예제 #5
0
        public void DiskWriteScanBasicTest([Values] TestUtils.DeviceType deviceType)
        {
            log    = TestUtils.CreateTestDevice(deviceType, $"{path}DiskWriteScanBasicTest_{deviceType}.log");
            objlog = TestUtils.CreateTestDevice(deviceType, $"{path}DiskWriteScanBasicTest_{deviceType}.obj.log");
            fht    = new (128,
                          logSettings : new LogSettings {
                LogDevice = log, ObjectLogDevice = objlog, MutableFraction = 0.1, MemorySizeBits = 15, PageSizeBits = 9, SegmentSizeBits = 22
            },
                          checkpointSettings : new CheckpointSettings {
                CheckPointType = CheckpointType.FoldOver
            },
                          serializerSettings : new SerializerSettings <MyKey, MyValue> {
                keySerializer = () => new MyKeySerializer(), valueSerializer = () => new MyValueSerializer()
            }
                          );

            using var session = fht.For(new MyFunctions()).NewSession <MyFunctions>();
            using var s       = fht.Log.Subscribe(new LogObserver());

            var start = fht.Log.TailAddress;

            for (int i = 0; i < totalRecords; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var _value = new MyValue {
                    value = i
                };
                session.Upsert(ref _key, ref _value, Empty.Default, 0);
                if (i % 100 == 0)
                {
                    fht.Log.FlushAndEvict(true);
                }
            }
            fht.Log.FlushAndEvict(true);

            using (var iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.SinglePageBuffering))
            {
                int val;
                for (val = 0; iter.GetNext(out RecordInfo recordInfo, out MyKey key, out MyValue value); ++val)
                {
                    Assert.AreEqual(val, key.key, $"log scan 1: key");
                    Assert.AreEqual(val, value.value, $"log scan 1: value");
                }
                Assert.AreEqual(val, totalRecords, $"log scan 1: totalRecords");
            }

            using (var iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.DoublePageBuffering))
            {
                int val;
                for (val = 0; iter.GetNext(out RecordInfo recordInfo, out MyKey key, out MyValue value); ++val)
                {
                    Assert.AreEqual(val, key.key, $"log scan 2: key");
                    Assert.AreEqual(val, value.value, $"log scan 2: value");
                }
                Assert.AreEqual(val, totalRecords, $"log scan 2: totalRecords");
            }
        }
예제 #6
0
        public void GenericLogCompactionCustomFunctionsTest1()
        {
            MyInput input = new MyInput();

            const int totalRecords = 2000;
            var       compactUntil = 0L;

            for (var i = 0; i < totalRecords; i++)
            {
                if (i == totalRecords / 2)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0, 0);
            }

            compactUntil = session.Compact(compactUntil, true, default(EvenCompactionFunctions));
            Assert.IsTrue(fht.Log.BeginAddress == compactUntil);

            // Read 2000 keys - all should be present
            for (var i = 0; i < totalRecords; i++)
            {
                var output = new MyOutput();
                var key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var ctx = (i < (totalRecords / 2) && (i % 2 != 0)) ? 1 : 0;

                var status = session.Read(ref key1, ref input, ref output, ctx, 0);
                if (status == Status.PENDING)
                {
                    session.CompletePending(true);
                }
                else
                {
                    if (ctx == 0)
                    {
                        Assert.IsTrue(status == Status.OK);
                        Assert.IsTrue(output.value.value == value.value);
                    }
                    else
                    {
                        Assert.IsTrue(status == Status.NOTFOUND);
                    }
                }
            }
        }
        public void LogCompactBasicTest([Values] TestUtils.DeviceType deviceType, [Values] CompactionType compactionType)
        {
            MyInput input = new();

            const int totalRecords = 500;
            long      compactUntil = 0;

            for (int i = 0; i < totalRecords; i++)
            {
                if (i == 250)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0, 0);
            }

            compactUntil = session.Compact(compactUntil, compactionType);
            fht.Log.Truncate();
            Assert.AreEqual(compactUntil, fht.Log.BeginAddress);

            // Read all keys - all should be present
            for (int i = 0; i < totalRecords; i++)
            {
                MyOutput output = new();

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = session.Read(ref key1, ref input, ref output, 0, 0);
                if (status.IsPending)
                {
                    session.CompletePendingWithOutputs(out var completedOutputs, wait: true);
                    Assert.IsTrue(completedOutputs.Next());
                    Assert.IsTrue(completedOutputs.Current.Status.Found);
                    output = completedOutputs.Current.Output;
                    Assert.IsFalse(completedOutputs.Next());
                    completedOutputs.Dispose();
                }
                Assert.IsTrue(status.Found);
                Assert.AreEqual(value.value, output.value.value);
            }
        }
예제 #8
0
        public void GenericLogCompactionTest1()
        {
            MyInput input = new MyInput();

            const int totalRecords = 2000;
            var       start        = fht.Log.TailAddress;
            long      compactUntil = 0;

            for (int i = 0; i < totalRecords; i++)
            {
                if (i == 1000)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                fht.Upsert(ref key1, ref value, 0, 0);
            }

            fht.Log.Compact(compactUntil);
            Assert.IsTrue(fht.Log.BeginAddress == compactUntil);

            // Read 2000 keys - all should be present
            for (int i = 0; i < totalRecords; i++)
            {
                MyOutput output = new MyOutput();

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, 0, 0);
                if (status == Status.PENDING)
                {
                    fht.CompletePending(true);
                }
                else
                {
                    Assert.IsTrue(status == Status.OK);
                    Assert.IsTrue(output.value.value == value.value);
                }
            }
        }
예제 #9
0
        public void LogCompactNotShiftBeginAddrTest()
        {
            MyInput input = new MyInput();

            const int totalRecords = 2000;
            long      compactUntil = 0;

            for (int i = 0; i < totalRecords; i++)
            {
                if (i == 1000)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0, 0);
            }

            // Do not shift begin to until address ... verify that is the case and verify all the keys
            compactUntil = session.Compact(compactUntil, false);
            Assert.IsFalse(fht.Log.BeginAddress == compactUntil);

            // Read 2000 keys - all should be present
            for (int i = 0; i < totalRecords; i++)
            {
                MyOutput output = new MyOutput();

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = session.Read(ref key1, ref input, ref output, 0, 0);
                if (status == Status.PENDING)
                {
                    session.CompletePending(true);
                }
                else
                {
                    Assert.IsTrue(status == Status.OK);
                    Assert.IsTrue(output.value.value == value.value);
                }
            }
        }
예제 #10
0
        public void GenericDiskWriteScan()
        {
            using var session = fht.NewSession();

            var s = fht.Log.Subscribe(new LogObserver());

            var start = fht.Log.TailAddress;

            for (int i = 0; i < totalRecords; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var _value = new MyValue {
                    value = i
                };
                session.Upsert(ref _key, ref _value, Empty.Default, 0);
                if (i % 100 == 0)
                {
                    fht.Log.FlushAndEvict(true);
                }
            }
            fht.Log.FlushAndEvict(true);
            using (var iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.SinglePageBuffering))
            {
                int val = 0;
                while (iter.GetNext(out RecordInfo recordInfo, out MyKey key, out MyValue value))
                {
                    Assert.IsTrue(key.key == val);
                    Assert.IsTrue(value.value == val);
                    val++;
                }
                Assert.IsTrue(totalRecords == val);
            }

            using (var iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.DoublePageBuffering))
            {
                int val = 0;
                while (iter.GetNext(out RecordInfo recordInfo, out MyKey key, out MyValue value))
                {
                    Assert.IsTrue(key.key == val);
                    Assert.IsTrue(value.value == val);
                    val++;
                }
                Assert.IsTrue(totalRecords == val);
            }

            s.Dispose();
        }
예제 #11
0
        public void ObjectInMemWriteRead()
        {
            var key1 = new MyKey {
                key = 9999999
            };
            var value = new MyValue {
                value = 23
            };

            MyOutput output = new MyOutput();

            fht.Upsert(key1, value, null, 0);
            fht.Read(key1, null, ref output, null, 0);

            Assert.IsTrue(output.value.value == value.value);
        }
예제 #12
0
        public void ObjectInMemWriteRead()
        {
            var key1 = new MyKey {
                key = 9999999
            };
            var value = new MyValue {
                value = 23
            };

            MyInput  input  = null;
            MyOutput output = new MyOutput();

            fht.Upsert(ref key1, ref value, Empty.Default, 0);
            fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
            Assert.IsTrue(output.value.value == value.value);
        }
예제 #13
0
        public void ObjectDiskWriteRead()
        {
            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                fht.Upsert(ref key, ref value, Empty.Default, 0);
                // fht.ShiftReadOnlyAddress(fht.LogTailAddress);
            }

            var key2 = new MyKey {
                key = 23
            };
            var      input  = new MyInput();
            MyOutput g1     = new MyOutput();
            var      status = fht.Read(ref key2, ref input, ref g1, Empty.Default, 0);

            if (status == Status.PENDING)
            {
                fht.CompletePending(true);
            }
            else
            {
                Assert.IsTrue(status == Status.OK);
            }

            Assert.IsTrue(g1.value.value == 23);

            key2 = new MyKey {
                key = 99999
            };
            status = fht.Read(ref key2, ref input, ref g1, Empty.Default, 0);

            if (status == Status.PENDING)
            {
                fht.CompletePending(true);
            }
            else
            {
                Assert.IsTrue(status == Status.NOTFOUND);
            }
        }
예제 #14
0
        public void GenericLogCompactionCustomFunctionsTest2()
        {
            // Update: irrelevant as session compaction no longer uses Copy/CopyInPlace
            // This test checks if CopyInPlace returning false triggers call to Copy

            using var session = fht.For(new MyFunctionsDelete()).NewSession <MyFunctionsDelete>();

            var key = new MyKey {
                key = 100
            };
            var value = new MyValue {
                value = 20
            };

            session.Upsert(ref key, ref value, 0, 0);

            fht.Log.Flush(true);

            value = new MyValue {
                value = 21
            };
            session.Upsert(ref key, ref value, 0, 0);

            fht.Log.Flush(true);

            var compactionFunctions = new Test2CompactionFunctions();

            session.Compact(fht.Log.TailAddress, true, compactionFunctions);

            Assert.IsFalse(compactionFunctions.CopyCalled);

            var input  = default(MyInput);
            var output = default(MyOutput);
            var status = session.Read(ref key, ref input, ref output, 0, 0);

            if (status == Status.PENDING)
            {
                session.CompletePending(true);
            }
            else
            {
                Assert.IsTrue(status == Status.OK);
                Assert.IsTrue(output.value.value == value.value);
            }
        }
예제 #15
0
        public void ObjectInMemWriteRead()
        {
            using var session = fht.NewSession(new MyFunctions());

            var key1 = new MyKey {
                key = 9999999
            };
            var value = new MyValue {
                value = 23
            };

            MyInput  input  = null;
            MyOutput output = new MyOutput();

            session.Upsert(ref key1, ref value, Empty.Default, 0);
            session.Read(ref key1, ref input, ref output, Empty.Default, 0);
            Assert.IsTrue(output.value.value == value.value);
        }
예제 #16
0
        public void GenericDiskWriteScan()
        {
            const int totalRecords = 2000;
            var       start        = fht.Log.TailAddress;

            for (int i = 0; i < totalRecords; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var _value = new MyValue {
                    value = i
                };
                fht.Upsert(ref _key, ref _value, Empty.Default, 0);
                if (i % 100 == 0)
                {
                    fht.Log.FlushAndEvict(true);
                }
            }
            fht.Log.FlushAndEvict(true);
            var iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.SinglePageBuffering);

            int val = 0;

            while (iter.GetNext(out MyKey key, out MyValue value))
            {
                Assert.IsTrue(key.key == val);
                Assert.IsTrue(value.value == val);
                val++;
            }
            Assert.IsTrue(totalRecords == val);

            iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.DoublePageBuffering);

            val = 0;
            while (iter.GetNext(out MyKey key, out MyValue value))
            {
                Assert.IsTrue(key.key == val);
                Assert.IsTrue(value.value == val);
                val++;
            }
            Assert.IsTrue(totalRecords == val);
        }
        public void LogCompactCopyInPlaceCustomFctnTest([Values] CompactionType compactionType)
        {
            // Update: irrelevant as session compaction no longer uses Copy/CopyInPlace
            // This test checks if CopyInPlace returning false triggers call to Copy

            using var session = fht.For(new MyFunctionsDelete()).NewSession <MyFunctionsDelete>();

            var key = new MyKey {
                key = 100
            };
            var value = new MyValue {
                value = 20
            };

            session.Upsert(ref key, ref value, 0, 0);

            fht.Log.Flush(true);

            value = new MyValue {
                value = 21
            };
            session.Upsert(ref key, ref value, 0, 0);

            fht.Log.Flush(true);

            var compactionFunctions = new Test2CompactionFunctions();
            var compactUntil        = session.Compact(fht.Log.TailAddress, compactionType, compactionFunctions);

            fht.Log.Truncate();

            var input  = default(MyInput);
            var output = default(MyOutput);
            var status = session.Read(ref key, ref input, ref output, 0, 0);

            if (status.IsPending)
            {
                session.CompletePendingWithOutputs(out var outputs, wait: true);
                (status, output) = GetSinglePendingResult(outputs);
            }
            Assert.IsTrue(status.Found);
            Assert.AreEqual(value.value, output.value.value);
        }
예제 #18
0
        public void LogCompactTestNewEntries()
        {
            MyInput input = new MyInput();

            const int totalRecords = 2000;
            long      compactUntil = 0;

            for (int i = 0; i < totalRecords; i++)
            {
                if (i == 1000)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0, 0);
            }

            // Put fresh entries for 1000 records
            for (int i = 0; i < 1000; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0, 0);
            }

            fht.Log.Flush(true);

            var tail = fht.Log.TailAddress;

            compactUntil = session.Compact(compactUntil, true);
            Assert.IsTrue(fht.Log.BeginAddress == compactUntil);
            Assert.IsTrue(fht.Log.TailAddress == tail);

            // Read 2000 keys - all should be present
            for (int i = 0; i < totalRecords; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = session.Read(ref key1, ref input, ref output, 0, 0);
                if (status == Status.PENDING)
                {
                    session.CompletePending(true);
                }
                else
                {
                    Assert.IsTrue(status == Status.OK);
                    Assert.IsTrue(output.value.value == value.value);
                }
            }
        }
예제 #19
0
        public void ObjectDiskWriteReadCache2()
        {
            MyInput input = default(MyInput);

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                fht.Upsert(ref key, ref value, Empty.Default, 0);
            }
            fht.CompletePending(true);

            // Dispose the hybrid log from memory entirely
            fht.Log.DisposeFromMemory();

            // Read 2000 keys - all should be served from disk, populating and evicting the read cache FIFO
            for (int i = 0; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.PENDING);
                fht.CompletePending(true);
            }

            // Read last 100 keys - all should be served from cache
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.OK);
                Assert.IsTrue(output.value.value == value.value);
            }

            // Evict the read cache entirely
            fht.ReadCache.FlushAndEvict(true);

            // Read 100 keys - all should be served from disk, populating cache
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.PENDING);
                fht.CompletePending(true);
            }

            // Read 100 keys - all should be served from cache
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.OK);
                Assert.IsTrue(output.value.value == value.value);
            }
        }
예제 #20
0
        public void GenericLogCompactionTest3()
        {
            MyInput input = new MyInput();

            const int totalRecords = 2000;
            var       start        = fht.Log.TailAddress;
            long      compactUntil = 0;

            for (int i = 0; i < totalRecords; i++)
            {
                if (i == totalRecords / 2)
                {
                    compactUntil = fht.Log.TailAddress;
                }

                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                fht.Upsert(ref key1, ref value, 0, 0);

                if (i % 8 == 0)
                {
                    int j = i / 4;
                    key1 = new MyKey {
                        key = j
                    };
                    fht.Delete(ref key1, 0, 0);
                }
            }

            var tail = fht.Log.TailAddress;

            fht.Log.Compact(compactUntil);
            Assert.IsTrue(fht.Log.BeginAddress == compactUntil);

            // Read 2000 keys - all should be present
            for (int i = 0; i < totalRecords; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                int ctx = ((i < 500) && (i % 2 == 0)) ? 1 : 0;

                var status = fht.Read(ref key1, ref input, ref output, ctx, 0);
                if (status == Status.PENDING)
                {
                    fht.CompletePending(true);
                }
                else
                {
                    if (ctx == 0)
                    {
                        Assert.IsTrue(status == Status.OK);
                        Assert.IsTrue(output.value.value == value.value);
                    }
                    else
                    {
                        Assert.IsTrue(status == Status.NOTFOUND);
                    }
                }
            }
        }
예제 #21
0
        public void IterationBasicTest()
        {
            using var session = fht.For(new MyFunctionsDelete()).NewSession <MyFunctionsDelete>();

            const int totalRecords = 2000;
            var       start        = fht.Log.TailAddress;

            for (int i = 0; i < totalRecords; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0);
            }

            int count = 0;
            var iter  = session.Iterate();

            while (iter.GetNext(out var recordInfo))
            {
                count++;
                Assert.AreEqual(iter.GetKey().key, iter.GetValue().value);
            }
            iter.Dispose();

            Assert.AreEqual(totalRecords, count);

            for (int i = 0; i < totalRecords; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = 2 * i
                };
                session.Upsert(ref key1, ref value, 0);
            }

            count = 0;
            iter  = session.Iterate();
            while (iter.GetNext(out var recordInfo))
            {
                count++;
                Assert.AreEqual(iter.GetKey().key * 2, iter.GetValue().value);
            }
            iter.Dispose();

            Assert.AreEqual(totalRecords, count);

            for (int i = totalRecords / 2; i < totalRecords; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0);
            }

            count = 0;
            iter  = session.Iterate();
            while (iter.GetNext(out var recordInfo))
            {
                count++;
            }
            iter.Dispose();

            Assert.AreEqual(totalRecords, count);

            for (int i = 0; i < totalRecords; i += 2)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key1, ref value, 0);
            }

            count = 0;
            iter  = session.Iterate();
            while (iter.GetNext(out var recordInfo))
            {
                count++;
            }
            iter.Dispose();

            Assert.AreEqual(totalRecords, count);

            for (int i = 0; i < totalRecords; i += 2)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Delete(ref key1, 0);
            }

            count = 0;
            iter  = session.Iterate();
            while (iter.GetNext(out var recordInfo))
            {
                count++;
            }
            iter.Dispose();

            Assert.AreEqual(totalRecords / 2, count);

            for (int i = 0; i < totalRecords; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = 3 * i
                };
                session.Upsert(ref key1, ref value, 0);
            }

            count = 0;
            iter  = session.Iterate();
            while (iter.GetNext(out var recordInfo))
            {
                count++;
                Assert.AreEqual(iter.GetKey().key * 3, iter.GetValue().value);
            }
            iter.Dispose();

            Assert.AreEqual(totalRecords, count);
        }
예제 #22
0
        public async Task AsyncObjectDiskWriteRead()
        {
            using var session = fht.NewSession(new MyFunctions());

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key, ref value);
            }

            var key1 = new MyKey {
                key = 1989
            };
            var input      = new MyInput();
            var readResult = await session.ReadAsync(ref key1, ref input, Empty.Default);

            var result = readResult.Complete();

            Assert.IsTrue(result.Item1 == Status.OK);
            Assert.IsTrue(result.Item2.value.value == 1989);

            var key2 = new MyKey {
                key = 23
            };

            readResult = await session.ReadAsync(ref key2, ref input, Empty.Default);

            result = readResult.Complete();

            Assert.IsTrue(result.Item1 == Status.OK);
            Assert.IsTrue(result.Item2.value.value == 23);

            var key3 = new MyKey {
                key = 9999
            };

            readResult = await session.ReadAsync(ref key3, ref input, Empty.Default);

            result = readResult.Complete();

            Assert.IsTrue(result.Item1 == Status.NOTFOUND);

            // Update last 100 using RMW in memory
            for (int i = 1900; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                var r = await session.RMWAsync(ref key, ref input, Empty.Default);

                while (r.status == Status.PENDING)
                {
                    r = await r.CompleteAsync(); // test async version of RMW completion
                }
            }

            // Update first 100 using RMW from storage
            for (int i = 0; i < 100; i++)
            {
                var key = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                (await session.RMWAsync(ref key, ref input, Empty.Default)).Complete();
            }

            for (int i = 0; i < 2000; i++)
            {
                var output = new MyOutput();
                var key    = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                readResult = await session.ReadAsync(ref key, ref input, Empty.Default);

                result = readResult.Complete();
                Assert.IsTrue(result.Item1 == Status.OK);
                if (i < 100 || i >= 1900)
                {
                    Assert.IsTrue(result.Item2.value.value == value.value + 1);
                }
                else
                {
                    Assert.IsTrue(result.Item2.value.value == value.value);
                }
            }
        }
예제 #23
0
 public bool Equals(MyKey otherKey)
 {
     return(key == otherKey.key);
 }
예제 #24
0
        public async Task ReadAsyncObjectDiskWriteRead()
        {
            using var session = fht.NewSession(new MyFunctions());

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var r = await session.UpsertAsync(ref key, ref value);

                while (r.Status.IsPending)
                {
                    r = await r.CompleteAsync(); // test async version of Upsert completion
                }
            }

            var key1 = new MyKey {
                key = 1989
            };
            var input      = new MyInput();
            var readResult = await session.ReadAsync(ref key1, ref input, Empty.Default);

            var result = readResult.Complete();

            Assert.IsTrue(result.status.Found);
            Assert.AreEqual(1989, result.output.value.value);

            var key2 = new MyKey {
                key = 23
            };

            readResult = await session.ReadAsync(ref key2, ref input, Empty.Default);

            result = readResult.Complete();

            Assert.IsTrue(result.status.Found);
            Assert.AreEqual(23, result.output.value.value);

            var key3 = new MyKey {
                key = 9999
            };

            readResult = await session.ReadAsync(ref key3, ref input, Empty.Default);

            result = readResult.Complete();

            Assert.IsFalse(result.status.Found);

            // Update last 100 using RMW in memory
            for (int i = 1900; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                var r = await session.RMWAsync(ref key, ref input, Empty.Default);

                while (r.Status.IsPending)
                {
                    r = await r.CompleteAsync(); // test async version of RMW completion
                }
            }

            // Update first 100 using RMW from storage
            for (int i = 0; i < 100; i++)
            {
                var key = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                (await session.RMWAsync(ref key, ref input, Empty.Default)).Complete();
            }

            for (int i = 0; i < 2000; i++)
            {
                var output = new MyOutput();
                var key    = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                readResult = await session.ReadAsync(ref key, ref input, Empty.Default);

                result = readResult.Complete();
                Assert.IsTrue(result.status.Found);
                if (i < 100 || i >= 1900)
                {
                    Assert.AreEqual(value.value + 1, result.output.value.value);
                }
                else
                {
                    Assert.AreEqual(value.value, result.output.value.value);
                }
            }
        }
예제 #25
0
        public void ObjectDiskWriteRead()
        {
            using var session = fht.NewSession(new MyFunctions());

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key, ref value, Empty.Default, 0);
                // fht.ShiftReadOnlyAddress(fht.LogTailAddress);
            }

            MyKey    key2   = new() { key = 23 };
            MyInput  input  = new();
            MyOutput g1     = new();
            var      status = session.Read(ref key2, ref input, ref g1, Empty.Default, 0);

            if (status.IsPending)
            {
                session.CompletePendingWithOutputs(out var outputs, wait: true);
                (status, g1) = GetSinglePendingResult(outputs);
            }

            Assert.IsTrue(status.Found);
            Assert.AreEqual(23, g1.value.value);

            key2 = new MyKey {
                key = 99999
            };
            status = session.Read(ref key2, ref input, ref g1, Empty.Default, 0);

            if (status.IsPending)
            {
                session.CompletePending(true);
            }
            else
            {
                Assert.IsFalse(status.Found);
            }

            // Update first 100 using RMW from storage
            for (int i = 0; i < 100; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                status = session.RMW(ref key1, ref input, Empty.Default, 0);
                if (status.IsPending)
                {
                    session.CompletePending(true);
                }
            }

            for (int i = 0; i < 2000; i++)
            {
                var output = new MyOutput();
                var key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                if (session.Read(ref key1, ref input, ref output, Empty.Default, 0).IsPending)
                {
                    session.CompletePending(true);
                }
                else
                {
                    if (i < 100)
                    {
                        Assert.AreEqual(value.value + 1, output.value.value);
                        Assert.AreEqual(value.value + 1, output.value.value);
                    }
                    else
                    {
                        Assert.AreEqual(value.value, output.value.value);
                        Assert.AreEqual(value.value, output.value.value);
                    }
                }
            }
        }
예제 #26
0
        public void DiskDeleteBasicTest1()
        {
            const int totalRecords = 2000;
            var       start        = fht.Log.TailAddress;

            for (int i = 0; i < totalRecords; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var _value = new MyValue {
                    value = i
                };
                session.Upsert(ref _key, ref _value, 0, 0);
            }

            for (int i = 0; i < totalRecords; i++)
            {
                var input  = new MyInput();
                var output = new MyOutput();
                var key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                if (session.Read(ref key1, ref input, ref output, 0, 0).IsPending)
                {
                    session.CompletePending(true);
                }
                else
                {
                    Assert.AreEqual(value.value, output.value.value);
                }
            }

            for (int i = 0; i < totalRecords; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                session.Delete(ref key1, 0, 0);
            }

            for (int i = 0; i < totalRecords; i++)
            {
                var input  = new MyInput();
                var output = new MyOutput();
                var key1   = new MyKey {
                    key = i
                };

                var status = session.Read(ref key1, ref input, ref output, 1, 0);

                if (status.IsPending)
                {
                    session.CompletePendingWithOutputs(out var outputs, wait: true);
                    (status, _) = GetSinglePendingResult(outputs);
                }
                Assert.IsFalse(status.Found);
            }


            using var iter = fht.Log.Scan(start, fht.Log.TailAddress, ScanBufferingMode.SinglePageBuffering);
            int val = 0;

            while (iter.GetNext(out RecordInfo recordInfo, out MyKey key, out MyValue value))
            {
                if (recordInfo.Tombstone)
                {
                    val++;
                }
            }
            Assert.AreEqual(val, totalRecords);
        }
예제 #27
0
        public void DiskDeleteBasicTest2()
        {
            const int totalRecords = 2000;

            for (int i = 0; i < totalRecords; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var _value = new MyValue {
                    value = i
                };
                session.Upsert(ref _key, ref _value, 0, 0);
            }

            var key100 = new MyKey {
                key = 100
            };
            var value100 = new MyValue {
                value = 100
            };
            var key200 = new MyKey {
                key = 200
            };

            session.Delete(ref key100, 0, 0);

            var input = new MyInput {
                value = 1000
            };
            var output = new MyOutput();
            var status = session.Read(ref key100, ref input, ref output, 1, 0);

            Assert.IsFalse(status.Found, status.ToString());

            status = session.Upsert(ref key100, ref value100, 0, 0);
            Assert.IsTrue(!status.Found, status.ToString());

            status = session.Read(ref key100, ref input, ref output, 0, 0);
            Assert.IsTrue(status.Found, status.ToString());
            Assert.AreEqual(value100.value, output.value.value);

            session.Delete(ref key100, 0, 0);
            session.Delete(ref key200, 0, 0);

            // This RMW should create new initial value, since item is deleted
            status = session.RMW(ref key200, ref input, 1, 0);
            Assert.IsFalse(status.Found);

            status = session.Read(ref key200, ref input, ref output, 0, 0);
            Assert.IsTrue(status.Found, status.ToString());
            Assert.AreEqual(input.value, output.value.value);

            // Delete key 200 again
            session.Delete(ref key200, 0, 0);

            // Eliminate all records from memory
            for (int i = 201; i < 2000; i++)
            {
                var _key = new MyKey {
                    key = i
                };
                var _value = new MyValue {
                    value = i
                };
                session.Upsert(ref _key, ref _value, 0, 0);
            }
            status = session.Read(ref key100, ref input, ref output, 1, 0);
            Assert.IsTrue(status.IsPending);
            session.CompletePending(true);

            // This RMW should create new initial value, since item is deleted
            status = session.RMW(ref key200, ref input, 1, 0);
            Assert.IsTrue(status.IsPending);
            session.CompletePending(true);

            status = session.Read(ref key200, ref input, ref output, 0, 0);
            Assert.IsTrue(status.Found, status.ToString());
            Assert.AreEqual(input.value, output.value.value);
        }
예제 #28
0
        public async Task AsyncObjectDiskWriteRead()
        {
            using var session = fht.NewSession();

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                await session.UpsertAsync(ref key, ref value, Empty.Default);
            }

            var key1 = new MyKey {
                key = 1989
            };
            var input  = new MyInput();
            var result = await session.ReadAsync(ref key1, ref input, Empty.Default);

            Assert.IsTrue(result.Item1 == Status.OK);
            Assert.IsTrue(result.Item2.value.value == 1989);

            var key2 = new MyKey {
                key = 23
            };

            result = await session.ReadAsync(ref key2, ref input, Empty.Default);

            Assert.IsTrue(result.Item1 == Status.OK);
            Assert.IsTrue(result.Item2.value.value == 23);

            var key3 = new MyKey {
                key = 9999
            };

            result = await session.ReadAsync(ref key3, ref input, Empty.Default);

            Assert.IsTrue(result.Item1 == Status.NOTFOUND);

            // Update last 100 using RMW in memory
            for (int i = 1900; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                await session.RMWAsync(ref key, ref input, Empty.Default);
            }

            // Update first 100 using RMW from storage
            for (int i = 0; i < 100; i++)
            {
                var key = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                await session.RMWAsync(ref key, ref input, Empty.Default);
            }

            for (int i = 0; i < 2000; i++)
            {
                var output = new MyOutput();
                var key    = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                result = await session.ReadAsync(ref key, ref input, Empty.Default);

                Assert.IsTrue(result.Item1 == Status.OK);
                if (i < 100 || i >= 1900)
                {
                    Assert.IsTrue(result.Item2.value.value == value.value + 1);
                }
                else
                {
                    Assert.IsTrue(result.Item2.value.value == value.value);
                }
            }
        }
예제 #29
0
        public void ObjectDiskWriteRead()
        {
            using var session = fht.NewSession();

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                session.Upsert(ref key, ref value, Empty.Default, 0);
                // fht.ShiftReadOnlyAddress(fht.LogTailAddress);
            }

            var key2 = new MyKey {
                key = 23
            };
            var      input  = new MyInput();
            MyOutput g1     = new MyOutput();
            var      status = session.Read(ref key2, ref input, ref g1, Empty.Default, 0);

            if (status == Status.PENDING)
            {
                session.CompletePending(true);
            }
            else
            {
                Assert.IsTrue(status == Status.OK);
            }

            Assert.IsTrue(g1.value.value == 23);

            key2 = new MyKey {
                key = 99999
            };
            status = session.Read(ref key2, ref input, ref g1, Empty.Default, 0);

            if (status == Status.PENDING)
            {
                session.CompletePending(true);
            }
            else
            {
                Assert.IsTrue(status == Status.NOTFOUND);
            }

            // Update first 100 using RMW from storage
            for (int i = 0; i < 100; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                status = session.RMW(ref key1, ref input, Empty.Default, 0);
                if (status == Status.PENDING)
                {
                    session.CompletePending(true);
                }
            }

            for (int i = 0; i < 2000; i++)
            {
                var output = new MyOutput();
                var key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                if (session.Read(ref key1, ref input, ref output, Empty.Default, 0) == Status.PENDING)
                {
                    session.CompletePending(true);
                }
                else
                {
                    if (i < 100)
                    {
                        Assert.IsTrue(output.value.value == value.value + 1);
                        Assert.IsTrue(output.value.value == value.value + 1);
                    }
                    else
                    {
                        Assert.IsTrue(output.value.value == value.value);
                        Assert.IsTrue(output.value.value == value.value);
                    }
                }
            }
        }
예제 #30
0
        public void ObjectDiskWriteReadCache()
        {
            MyInput input = default(MyInput);

            for (int i = 0; i < 2000; i++)
            {
                var key = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };
                fht.Upsert(ref key, ref value, Empty.Default, 0);
            }
            fht.CompletePending(true);

            // Evict all records from main memory of hybrid log
            fht.Log.FlushAndEvict(true);

            // Read 2000 keys - all should be served from disk, populating and evicting the read cache FIFO
            for (int i = 0; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.PENDING);
                fht.CompletePending(true);
            }

            // Read last 100 keys - all should be served from cache
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.OK);
                Assert.IsTrue(output.value.value == value.value);
            }

            // Evict the read cache entirely
            fht.ReadCache.FlushAndEvict(true);

            // Read 100 keys - all should be served from disk, populating cache
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.PENDING);
                fht.CompletePending(true);
            }

            // Read 100 keys - all should be served from cache
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.OK);
                Assert.IsTrue(output.value.value == value.value);
            }


            // Upsert to overwrite the read cache
            for (int i = 1900; i < 1950; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i + 1
                };
                fht.Upsert(ref key1, ref value, Empty.Default, 0);
            }

            // RMW to overwrite the read cache
            for (int i = 1950; i < 2000; i++)
            {
                var key1 = new MyKey {
                    key = i
                };
                input = new MyInput {
                    value = 1
                };
                var status = fht.RMW(ref key1, ref input, Empty.Default, 0);
                if (status == Status.PENDING)
                {
                    fht.CompletePending(true);
                }
            }

            // Read the 100 keys
            for (int i = 1900; i < 2000; i++)
            {
                MyOutput output = new MyOutput();
                var      key1   = new MyKey {
                    key = i
                };
                var value = new MyValue {
                    value = i + 1
                };

                var status = fht.Read(ref key1, ref input, ref output, Empty.Default, 0);
                Assert.IsTrue(status == Status.OK);
                Assert.IsTrue(output.value.value == value.value);
            }
        }