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); }
public void MixedTest1() { using var session = fht.NewSession(); int key = 8999998; var input1 = new MyInput { value = 23 }; MyOutput output = new MyOutput(); session.RMW(ref key, ref input1, Empty.Default, 0); int key2 = 8999999; var input2 = new MyInput { value = 24 }; session.RMW(ref key2, ref input2, Empty.Default, 0); session.Read(ref key, 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); }
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 MixedTest1() { using var session = fht.For(new MixedFunctions()).NewSession <MixedFunctions>(); int key = 8999998; var input1 = new MyInput { value = 23 }; MyOutput output = new MyOutput(); session.RMW(ref key, ref input1, Empty.Default, 0); int key2 = 8999999; var input2 = new MyInput { value = 24 }; session.RMW(ref key2, ref input2, Empty.Default, 0); session.Read(ref key, ref input1, ref output, Empty.Default, 0); Assert.AreEqual(input1.value, output.value.value); session.Read(ref key2, ref input2, ref output, Empty.Default, 0); Assert.AreEqual(input2.value, output.value.value); }
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); }
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); } } } }
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) { MyInput input = new MyInput(); 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, true); Assert.AreEqual(compactUntil, fht.Log.BeginAddress); // Read all 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.CompletePendingWithOutputs(out var completedOutputs, wait: true); Assert.IsTrue(completedOutputs.Next()); Assert.AreEqual(Status.OK, completedOutputs.Current.Status); output = completedOutputs.Current.Output; Assert.IsFalse(completedOutputs.Next()); completedOutputs.Dispose(); } Assert.AreEqual(Status.OK, status); Assert.AreEqual(value.value, output.value.value); } }
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); } } }
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); } } }
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); }
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); }
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); } }
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); }
public void ObjectDiskWriteRead() { for (int i = 0; i < 2000; i++) { fht.Upsert(new MyKey { key = i }, new MyValue { value = i }, default(MyContext), 0); } MyOutput g1 = new MyOutput(); var status = fht.Read(new MyKey { key = 23 }, new MyInput(), ref g1, new MyContext(), 0); if (status == Status.PENDING) { fht.CompletePending(true); } else { Assert.IsTrue(status == Status.OK); } Assert.IsTrue(g1.value.value == 23); status = fht.Read(new MyKey { key = 99999 }, new MyInput(), ref g1, new MyContext(), 0); if (status == Status.PENDING) { fht.CompletePending(true); } else { Assert.IsTrue(status == Status.NOTFOUND); } }
public void MixedTest2() { using var session = fht.For(new MixedFunctions()).NewSession <MixedFunctions>(); for (int i = 0; i < 2000; i++) { var value = new MyValue { value = i }; session.Upsert(ref i, ref value, Empty.Default, 0); } var key2 = 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.AreEqual(Status.OK, status); } Assert.AreEqual(23, g1.value.value); key2 = 99999; status = session.Read(ref key2, ref input, ref g1, Empty.Default, 0); if (status == Status.PENDING) { session.CompletePending(true); } else { Assert.AreEqual(Status.NOTFOUND, status); } }
public void MixedTest2() { using var session = fht.NewSession(); for (int i = 0; i < 2000; i++) { var value = new MyValue { value = i }; session.Upsert(ref i, ref value, Empty.Default, 0); } var key2 = 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 = 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); } }
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); } }
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); } } }
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); } } }
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); } } } }
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); }
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); }
public void GenericDiskDeleteTest2() { 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.IsTrue(status == Status.NOTFOUND); status = session.Upsert(ref key100, ref value100, 0, 0); Assert.IsTrue(status == Status.OK); status = session.Read(ref key100, ref input, ref output, 0, 0); Assert.IsTrue(status == Status.OK); Assert.IsTrue(output.value.value == value100.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.IsTrue(status == Status.NOTFOUND); status = session.Read(ref key200, ref input, ref output, 0, 0); Assert.IsTrue(status == Status.OK); Assert.IsTrue(output.value.value == input.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 == Status.PENDING); 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 == Status.PENDING); session.CompletePending(true); status = session.Read(ref key200, ref input, ref output, 0, 0); Assert.IsTrue(status == Status.OK); Assert.IsTrue(output.value.value == input.value); }
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); } } }
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); } } } }
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); } } } }
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); } } }
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); } }
public void GenericDiskDeleteTest1() { 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) == Status.PENDING) { session.CompletePending(true); } else { Assert.IsTrue(output.value.value == 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 == Status.PENDING) { session.CompletePending(true); } else { Assert.IsTrue(status == Status.NOTFOUND); } } 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.IsTrue(totalRecords == val); }