public void TestOptions()
        {
            using (TempFile temp = new TempFile())
            {
                TransactedCompoundFile.Options o = new TransactedCompoundFile.Options(temp.TempPath);
                Assert.AreEqual(temp.TempPath, o.FilePath);
                Assert.AreEqual(4096, o.BlockSize);
                Assert.AreEqual(8192, o.BlockSize = 8192);
                Assert.AreEqual(false, o.CreateNew);
                Assert.AreEqual(true, o.CreateNew = true);
                Assert.AreEqual(false, o.ReadOnly);
                Assert.AreEqual(true, o.ReadOnly = true);
                Assert.AreEqual(false, o.CommitOnDispose);
                Assert.AreEqual(true, o.CommitOnDispose = true);
                Assert.AreEqual(false, o.CommitOnWrite);
                Assert.AreEqual(true, o.CommitOnWrite = true);
                Assert.AreEqual(FileOptions.None, o.FileOptions);
                Assert.AreEqual(FileOptions.WriteThrough, o.FileOptions = FileOptions.WriteThrough);
                Assert.AreEqual(TransactedCompoundFile.LoadingRule.Default, o.LoadingRule);
                Assert.AreEqual(TransactedCompoundFile.LoadingRule.Primary, o.LoadingRule = TransactedCompoundFile.LoadingRule.Primary);

                TransactedCompoundFile.Options copy = (TransactedCompoundFile.Options)((ICloneable)o).Clone();
                Assert.AreEqual(FileOptions.WriteThrough, copy.FileOptions);
            }
        }
        public void VerifyCommitAsTransaction()
        {
            using (TempFile temp1 = new TempFile())
                using (TempFile temp2 = new TempFile())
                {
                    var options = new TransactedCompoundFile.Options(temp1.TempPath)
                    {
                        BlockSize = 512
                    };

                    const int count   = 4;
                    byte[]    sample1 = new byte[options.MaxWriteSize / 3];
                    byte[]    sample2 = (byte[])sample1.Clone();
                    new Random().NextBytes(sample1);
                    new Random().NextBytes(sample2);

                    using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                    {
                        for (uint h = 1u; h < count; h++)
                        {
                            Assert.AreEqual(h, file.Create());
                        }
                        for (uint h = 1u; h < count; h++)
                        {
                            file.Write(h, sample1, 0, sample1.Length);
                        }
                        file.Commit();//persist.
                        for (uint h = 1u; h < count; h++)
                        {
                            file.Write(h, sample2, 0, sample2.Length);
                        }

                        file.Commit(x => temp1.CopyTo(temp2.TempPath, true), 0);
                    }

                    options = new TransactedCompoundFile.Options(temp2.TempPath)
                    {
                        BlockSize = 512, CommitOnDispose = false
                    };

                    //Verify primary has sample2 data
                    options.LoadingRule = TransactedCompoundFile.LoadingRule.Primary;
                    using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                    {
                        for (uint h = 1u; h < count; h++)
                        {
                            CompareBytes(sample2, 0, sample2.Length, IOStream.ReadAllBytes(file.Read(h)));
                        }
                    }
                    //Verify secondary has sample1 data
                    options.LoadingRule = TransactedCompoundFile.LoadingRule.Secondary;
                    using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                    {
                        for (uint h = 1u; h < count; h++)
                        {
                            CompareBytes(sample1, 0, sample1.Length, IOStream.ReadAllBytes(file.Read(h)));
                        }
                    }
                }
        }
        public void VerifyLoadRulesWithCorruptSecondary()
        {
            using (TempFile temp = new TempFile())
            {
                var options = new TransactedCompoundFile.Options(temp.TempPath)
                {
                    BlockSize = 512
                };

                const int count  = 4;
                byte[]    sample = new byte[options.MaxWriteSize / 3];
                new Random().NextBytes(sample);

                using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                {
                    for (uint h = 1u; h < count; h++)
                    {
                        Assert.AreEqual(h, file.Create());
                    }
                    for (uint h = 1u; h < count; h++)
                    {
                        file.Write(h, sample, 0, sample.Length);
                    }
                    file.Commit();
                }

                //Corrupts the secondary storage:
                using (Stream f = temp.Open())
                {
                    f.Seek(-100, SeekOrigin.End);
                    f.Write(sample, 0, 100);
                }
                try
                {
                    options.LoadingRule = TransactedCompoundFile.LoadingRule.Secondary;
                    new TransactedCompoundFile(options).Dispose();
                    Assert.Fail("Should not load");
                }
                catch (InvalidDataException)
                {
                }

                options.LoadingRule = TransactedCompoundFile.LoadingRule.Primary;
                using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                {
                    for (uint h = 1u; h < count; h++)
                    {
                        CompareBytes(sample, 0, sample.Length, IOStream.ReadAllBytes(file.Read(h)));
                    }
                    //Commit fixes corruption
                    file.Commit();
                }

                options.LoadingRule = TransactedCompoundFile.LoadingRule.Secondary;
                new TransactedCompoundFile(options).Dispose();
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Opens an existing BPlusTree file at the path specified, for a new file use CreateNew()
        /// </summary>
        public BTreeFileStoreV2(TransactedCompoundFile.Options options)
        {
            _options = options;
            _file    = new TransactedCompoundFile(options);
            _rootId  = new FileId(TransactedCompoundFile.FirstIdentity);

            if (options.CreateNew)
            {
                CreateRoot(_file);
            }
        }
 public void TestExceedWriteMax()
 {
     using (TempFile temp = new TempFile())
     {
         var options = new TransactedCompoundFile.Options(temp.TempPath)
         {
             BlockSize = 512
         };
         byte[] sample = new byte[options.MaxWriteSize + 1];
         new Random().NextBytes(sample);
         using (TransactedCompoundFile file = new TransactedCompoundFile(options))
         {
             file.Write(file.Create(), sample, 0, sample.Length);
         }
     }
 }
        public void TestLargeWrite()
        {
            using (TempFile temp = new TempFile())
            {
                var options = new TransactedCompoundFile.Options(temp.TempPath)
                {
                    BlockSize = 512
                };
                byte[] sample = new byte[options.MaxWriteSize];
                new Random().NextBytes(sample);
                List <uint> handles = new List <uint>();
                using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                {
                    for (int i = 0; i < 2; i++)
                    {
                        var hid = file.Create();
                        handles.Add(hid);
                        file.Write(hid, sample, i, sample.Length - i);
                        CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i])));
                    }
                    file.Commit();
                }
                long size = temp.Info.Length;
                using (TransactedCompoundFile file = new TransactedCompoundFile(options))
                {
                    for (int i = 0; i < 2; i++)
                    {
                        CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i])));
                        file.Delete(handles[i]);
                    }
                    file.Commit();
                    Assert.AreEqual(size, temp.Info.Length);
                    for (int i = 0; i < 252; i++)
                    {
                        var hid = file.Create();
                        handles.Add(hid);
                        file.Write(hid, sample, i, 300);
                    }
                    file.Commit();
                    Assert.AreEqual(size, temp.Info.Length);

                    file.Create();
                    Assert.AreNotEqual(size, temp.Info.Length);
                }
            }
        }
        void TestWriteWithOptions(TransactedCompoundFile.Options options)
        {
            byte[] sample = new byte[1024];
            new Random().NextBytes(sample);
            List <uint> handles = new List <uint>();

            using (TransactedCompoundFile file = new TransactedCompoundFile(options))
            {
                for (int i = 0; i < 1000; i++)
                {
                    var hid = file.Create();
                    handles.Add(hid);
                    file.Write(hid, sample, i, sample.Length - i);
                    CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(hid)));
                    if (i == 500)
                    {
                        file.Commit();
                    }
                }
            }
            options.CreateNew = false;
            using (TransactedCompoundFile file = new TransactedCompoundFile(options))
            {
                for (int i = 0; i < 1000; i++)
                {
                    if (i <= 500 || options.CommitOnWrite || options.CommitOnDispose)
                    {
                        CompareBytes(sample, i, sample.Length - i, IOStream.ReadAllBytes(file.Read(handles[i])));
                    }
                    else
                    {
                        try
                        {
                            IOStream.ReadAllBytes(file.Read(handles[i]));
                            Assert.Fail();
                        }
                        catch (ArgumentOutOfRangeException) { }
                    }
                }
            }
        }
            /// <summary> Used to create the correct storage type </summary>
            internal override INodeStorage CreateStorage()
            {
                if (StorageType == StorageType.Custom)
                {
                    return(Check.NotNull(StorageSystem));
                }
                if (StorageType == StorageType.Memory)
                {
                    return(new BTreeMemoryStore());
                }

                InvalidConfigurationValueException.Assert(StorageType == StorageType.Disk, "StorageType", "Unknown value defined.");
                bool exists = File.Exists(FileName);

                if (exists && new FileInfo(FileName).Length == 0)
                {
                    exists = false;
                    File.Delete(FileName);
                }
                bool createNew = CreateFile == CreatePolicy.Always ||
                                 (exists == false && CreateFile == CreatePolicy.IfNeeded);

                if (!exists && !createNew)
                {
                    throw new InvalidConfigurationValueException("CreateFile", "The file does not exist and CreateFile is Never");
                }

                TransactedCompoundFile.Options foptions =
                    new TransactedCompoundFile.Options(FileName)
                {
                    BlockSize   = FileBlockSize,
                    FileOptions = FileOptions.None,
                    ReadOnly    = ReadOnly,
                    CreateNew   = createNew
                };

                switch (StoragePerformance)
                {
                case StoragePerformance.Fastest:
                {
                    SetStorageCache(true);
                    break;
                }

                case StoragePerformance.CommitToCache:
                {
                    foptions.FileOptions   = FileOptions.None;
                    foptions.CommitOnWrite = true;
                    break;
                }

                case StoragePerformance.CommitToDisk:
                {
                    foptions.FileOptions   = FileOptions.WriteThrough;
                    foptions.CommitOnWrite = true;
                    break;
                }

                case StoragePerformance.LogFileInCache:
                case StoragePerformance.LogFileNoCache:
                {
                    SetStorageCache(true);
                    if (LogFile == null)
                    {
                        _logFileName = _logFileName ?? Path.ChangeExtension(FileName, ".tlog");
                        SetLogFile(new TransactionLog <TKey, TValue>(
                                       new TransactionLogOptions <TKey, TValue>(_logFileName, KeySerializer, ValueSerializer)
                            {
                                FileOptions = StoragePerformance == StoragePerformance.LogFileNoCache
                                            ? FileOptions.WriteThrough : FileOptions.None,
                            }
                                       ));
                    }
                    break;
                }

                default:
                    throw new InvalidConfigurationValueException("DurabilityProtection", "The configuration option is not valid.");
                }

                return(new BTreeFileStoreV2(foptions));
            }