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();
            }
        }
Exemplo n.º 3
0
        /// <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);
                    }
                }
            }
        }