public void TestReadOnly() { using (TempFile file = new TempFile()) { var opt = new BPlusTree<int, int>.Options(PrimitiveSerializer.Int32, PrimitiveSerializer.Int32) { CreateFile = CreatePolicy.Always, FileName = file.TempPath, }; using (BPlusTree<int, int> tree = new BPlusTree<int, int>(opt)) { tree.Add(1, 2); tree.Add(3, 4); tree.Add(5, 6); } opt.CreateFile = CreatePolicy.Never; opt.ReadOnly = true; using (BPlusTree<int, int> tree = new BPlusTree<int, int>(opt)) { Assert.AreEqual(tree[1], 2); Assert.AreEqual(tree[3], 4); Assert.AreEqual(tree[5], 6); try { tree[1] = 0; Assert.Fail(); } catch (InvalidOperationException) { } try { tree.Remove(1); Assert.Fail(); } catch (InvalidOperationException) { } } } }
public void TestReadOnlyCopy() { using (var tempFile = new TempFile()) { var options = new BPlusTree<int, string>.OptionsV2(new PrimitiveSerializer(), new PrimitiveSerializer()) { CreateFile = CreatePolicy.Always, FileName = tempFile.TempPath, }.CalcBTreeOrder(4, 10); var readcopy = options.Clone(); readcopy.CreateFile = CreatePolicy.Never; readcopy.ReadOnly = true; using (var tree = new BPlusTree<int, string>(options)) { using (var copy = new BPlusTree<int, string>(readcopy)) { copy.EnableCount(); Assert.AreEqual(0, copy.Count); } //insert some data... tree.AddRange(MakeValues(0, 100)); using (var copy = new BPlusTree<int, string>(readcopy)) { copy.EnableCount(); Assert.AreEqual(0, copy.Count); } tree.Commit(); //insert some data... for (int i = 0; i < 100; i++) tree.Remove(i); tree.AddRange(MakeValues(1000, 1000)); using (var copy = new BPlusTree<int, string>(readcopy)) { copy.EnableCount(); Assert.AreEqual(100, copy.Count); Assert.AreEqual(0, copy.First().Key); Assert.AreEqual(99, copy.Last().Key); } tree.Commit(); } } }
public void TestConcurrency() { mreStop.Reset(); using(TempFile temp = new TempFile()) { BPlusTree<Guid, TestInfo>.OptionsV2 options = new BPlusTree<Guid, TestInfo>.OptionsV2( PrimitiveSerializer.Guid, new TestInfoSerializer()); options.CalcBTreeOrder(16, 24); options.CreateFile = CreatePolicy.Always; options.FileName = temp.TempPath; using (BPlusTree<Guid, TestInfo> tree = new BPlusTree<Guid, TestInfo>(options)) { tree.EnableCount(); var actions = new List<IAsyncResult>(); var tests = new Action<BPlusTree<Guid, TestInfo>>[] { DeleteStuff, UpdateStuff, AddStuff, AddRanges, BulkyInserts, FetchStuff, FetchStuff, FetchStuff, FetchStuff, FetchStuff }; foreach (var t in tests) actions.Add(t.BeginInvoke(tree, null, null)); const int waitIterations = 8; // wait for n seconds int timesWaited = 0; do { Trace.TraceInformation("Dictionary.Count = {0}", tree.Count); Thread.Sleep(1000); timesWaited++; } while (timesWaited<waitIterations && Debugger.IsAttached); mreStop.Set(); for (int i = 0; i < actions.Count; i++) { tests[i].EndInvoke(actions[i]); } Trace.TraceInformation("Dictionary.Count = {0}", tree.Count); } } }
public void TestMergeRandomInFile() { BPlusTreeOptions<int, string> options = Options; using (TempFile temp = new TempFile()) { temp.Delete(); options.CreateFile = CreatePolicy.Always; options.FileName = temp.TempPath; options.CalcBTreeOrder(4, 4); Stopwatch sw = Stopwatch.StartNew(); Dictionary<int, string> expected = TestMergeRandom(options, 2, 300); Trace.TraceInformation("Creating {0} nodes in {1}.", expected.Count, sw.Elapsed); sw = Stopwatch.StartNew(); options = Options; options.CreateFile = CreatePolicy.Never; options.FileName = temp.TempPath; options.CalcBTreeOrder(4, 4); using (BPlusTree<int, string> tree = new BPlusTree<int, string>(options)) { VerifyDictionary(expected, tree); } Trace.TraceInformation("Verified {0} nodes in {1}.", expected.Count, sw.Elapsed); } }
public void TestMergeSequenceInFile() { BPlusTreeOptions<int, string> options = Options; using (TempFile temp = new TempFile()) { options = Options; temp.Delete(); //options.CreateFile = CreatePolicy.Always; //options.FileName = temp.TempPath; options.MaximumValueNodes = 14; options.MinimumValueNodes = 7; options.MaximumChildNodes = 6; options.MinimumChildNodes = 2; // Just to make sure we don't break some fencepost condition in the future for (int i = 0; i <= (options.MaximumValueNodes * options.MaximumChildNodes) + 1; i++) TestMergeSequenceInFile(options.Clone(), i); TestMergeSequenceInFile(options.Clone(), options.MaximumValueNodes * options.MaximumChildNodes * options.MaximumChildNodes); TestMergeSequenceInFile(options.Clone(), options.MaximumValueNodes * options.MaximumChildNodes * options.MaximumChildNodes + 1); } }
public void TestSyncFromLogging() { using (var tempFile = new TempFile()) using (var logfile = new TempFile()) using (var tempCopy = new TempFile()) { var options = new BPlusTree<int, string>.OptionsV2(new PrimitiveSerializer(), new PrimitiveSerializer()) { CreateFile = CreatePolicy.Always, FileName = tempFile.TempPath, TransactionLogFileName = logfile.TempPath, }.CalcBTreeOrder(4, 10); var readcopy = options.Clone(); readcopy.FileName = tempCopy.TempPath; readcopy.StoragePerformance = StoragePerformance.Fastest; using (var tree = new BPlusTree<int, string>(options)) using (var copy = new BPlusTree<int, string>(readcopy)) using (var tlog = new TransactionLog<int, string>( new TransactionLogOptions<int, string>(logfile.TempPath, PrimitiveSerializer.Int32, PrimitiveSerializer.String) { ReadOnly = true })) { tree.Add(0, "0"); tree.Commit(); long logpos = 0; copy.EnableCount(); //start by copying the data from tree's file into the copy instance: copy.BulkInsert( BPlusTree<int, string>.EnumerateFile(options), new BulkInsertOptions { InputIsSorted = true, CommitOnCompletion = false, ReplaceContents = true } ); Assert.AreEqual(1, copy.Count); Assert.AreEqual("0", copy[0]); tlog.ReplayLog(copy, ref logpos); Assert.AreEqual(1, copy.Count); //insert some data... tree.AddRange(MakeValues(1, 99)); tlog.ReplayLog(copy, ref logpos); Assert.AreEqual(100, copy.Count); //insert some data... for (int i = 0; i < 100; i++) tree.Remove(i); tlog.ReplayLog(copy, ref logpos); Assert.AreEqual(0, copy.Count); tree.AddRange(MakeValues(1000, 1000)); tlog.ReplayLog(copy, ref logpos); Assert.AreEqual(1000, copy.Count); } } }