public void TestClear() { Dictionary <long, byte[]> data = new Dictionary <long, byte[]>(); using (TempFile file = new TempFile()) using (FragmentedFile ff = FragmentedFile.CreateNew(file.TempPath, 512, 100, 2, FragmentedFile.OptionsDefault)) { //Create: for (int i = 0; i < 256; i++) { data.Add(ff.Create(), null); } //Enumerate: int count = 0; foreach (KeyValuePair <long, Stream> fragment in ff.ForeachBlock(true, true, null)) { count++; } Assert.AreEqual(256, count); ff.Clear(); //Empty? foreach (KeyValuePair <long, Stream> fragment in ff.ForeachBlock(true, true, null)) { Assert.Fail(); } } }
void TestCrud(FragmentedFile ff, int blockCount, int blockSize) { Dictionary <long, byte[]> data = new Dictionary <long, byte[]>(); //Create: for (int i = 0; i < blockCount; i++) { data.Add(ff.Create(), null); } //Write: foreach (long id in new List <long>(data.Keys)) { using (Stream io = ff.Open(id, FileAccess.Write)) io.Write(data[id] = MakeBytes(blockSize), 0, blockSize); } //Read: foreach (KeyValuePair <long, byte[]> kv in data) { using (Stream io = ff.Open(kv.Key, FileAccess.Read)) Assert.AreEqual(kv.Value, IOStream.ReadAllBytes(io)); } //Enumerate: Dictionary <long, byte[]> copy = new Dictionary <long, byte[]>(data); foreach (KeyValuePair <long, Stream> fragment in ff.ForeachBlock(true, true, null)) { Assert.AreEqual(copy[fragment.Key], IOStream.ReadAllBytes(fragment.Value)); Assert.IsTrue(copy.Remove(fragment.Key)); } //Update: foreach (long id in new List <long>(data.Keys)) { Assert.AreEqual(data[id], IOStream.ReadAllBytes(ff.Open(id, FileAccess.Read))); using (Stream io = ff.Open(id, FileAccess.Write)) io.Write(data[id] = MakeBytes(blockSize * 2), 0, blockSize * 2); Assert.AreEqual(data[id], IOStream.ReadAllBytes(ff.Open(id, FileAccess.Read))); using (Stream io = ff.Open(id, FileAccess.Write)) io.Write(data[id] = MakeBytes(blockSize / 2), 0, blockSize / 2); Assert.AreEqual(data[id], IOStream.ReadAllBytes(ff.Open(id, FileAccess.Read))); } //Delete: foreach (long id in new List <long>(data.Keys)) { ff.Delete(id); } //Empty? foreach (KeyValuePair <long, Stream> fragment in ff.ForeachBlock(true, true, null)) { Assert.Fail(); } }
/// <summary> /// Performs a low-level scan of the storage file to yield all Key/Value pairs it was able to read from the file. /// </summary> /// <param name="options"> The options normally used to create the <see cref="BPlusTree{TKey, TValue}"/> instance </param> /// <param name="sharing"> <see cref="FileShare"/> options used to open the file </param> /// <returns> Yields the Key/Value pairs found in the file </returns> public static IEnumerable <KeyValuePair <TKey, TValue> > RecoveryScan(Options options, FileShare sharing) { options = options.Clone(); options.CreateFile = CreatePolicy.Never; string filename = options.FileName; if (String.IsNullOrEmpty(filename)) { throw new InvalidConfigurationValueException("FileName", "The FileName property was not specified."); } if (!File.Exists(filename)) { throw new InvalidConfigurationValueException("FileName", "The FileName specified does not exist."); } if (options.StorageType != StorageType.Disk) { throw new InvalidConfigurationValueException("StorageType", "The storage type is not set to 'Disk'."); } using (FragmentedFile file = new FragmentedFile(filename, options.FileBlockSize, 1, 1, FileAccess.Read, sharing, FileOptions.None)) { NodeSerializer nodeReader = new NodeSerializer(options, new NodeHandleSerializer(new Storage.BTreeFileStore.HandleSerializer())); foreach (KeyValuePair <long, Stream> block in file.ForeachBlock(true, false, IngoreDataInvalid)) { List <KeyValuePair <TKey, TValue> > found = new List <KeyValuePair <TKey, TValue> >(); try { foreach (KeyValuePair <TKey, TValue> entry in nodeReader.RecoverLeaf(block.Value)) { found.Add(entry); } } catch { /* Serialization error: Ignore and continue */ } foreach (KeyValuePair <TKey, TValue> entry in found) { yield return(entry); } } } }