示例#1
0
        public void TestInvert()
        {
            OrdinalList lista = new OrdinalList(new int[] {0, 2, 4, 6, 8, 10, 12});
            OrdinalList listb = new OrdinalList(new int[] {1, 3, 5, 7, 9, 11, 13});

            OrdinalList invta = lista.Invert(13);
            string invtatext = "", listbtext = "";
            foreach (int i in invta)
                invtatext += "," + i;
            foreach (int i in listb)
                listbtext += "," + i;
            Assert.AreEqual(listbtext, invtatext);

            lista = new OrdinalList(new int[] { 0 });
            listb = new OrdinalList(new int[] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13 });
            invta = lista.Invert(13);
            invtatext = "";
            listbtext = "";
            foreach (int i in invta)
                invtatext += "," + i;
            foreach (int i in listb)
                listbtext += "," + i;
            Assert.AreEqual(listbtext, invtatext);

            lista = new OrdinalList(new int[] { 0, 1, 2, 4, 5, 6, 7, 8, 9, 10, 11, 13 });
            listb = new OrdinalList(new int[] { 3 });
            invta = lista.Invert(4);
            invtatext = "";
            listbtext = "";
            foreach (int i in invta)
                invtatext += "," + i;
            foreach (int i in listb)
                listbtext += "," + i;
            Assert.AreEqual(listbtext, invtatext);
        }
示例#2
0
        /// <summary>
        /// For file-level transactions, performs a two-stage commit of all changed handles.
        /// After the first stage has completed, the stageCommit() delegate is invoked.
        /// </summary>
        /// <remarks>
        ///
        /// </remarks>
        public void Commit <T>(Action <T> stageCommit, T value)
        {
            if (_options.CommitOnWrite)
            {
                Flush(true);
                return;
            }

            lock (_sync)
            {
                if (_stream == null)
                {
                    throw new ObjectDisposedException(GetType().FullName);
                }

                //Phase 1 - commit block 0 for each section
                foreach (var section in _sections)
                {
                    section.Commit(_fput, false);
                }
                Flush(true);

                try { if (stageCommit != null)
                      {
                          stageCommit(value);
                      }
                }
                finally
                {
                    //Phase 2 - commit block max for each section and set clean
                    foreach (var section in _sections)
                    {
                        section.Commit(_fput, true);
                    }
                    Flush(true);

                    foreach (int ifree in _reservedBlocks)
                    {
                        _firstFreeBlock = Math.Min(_firstFreeBlock, ifree);
                        break;
                    }
                    _reservedBlocks = _freeBlocks.Invert((_sections.Length * BlocksPerSection) - 1);
                }
            }
        }
示例#3
0
        private bool LoadSections(Stream stream, LoadFrom from)
        {
            long fsize    = stream.Length;
            long hsize    = fsize / SectionSize;
            var  sections = new FileSection[hsize];

            for (int i = 0; i < sections.Length; i++)
            {
                if (from == LoadFrom.Either && FileSection.TryLoadSection(stream, false, i, BlockSize, out sections[i]))
                {
                    continue;
                }

                if (!FileSection.TryLoadSection(stream, from != LoadFrom.FirstBlock, i, BlockSize, out sections[i]))
                {
                    return(false);
                }
            }

            int lastIndex = (int)(hsize * BlocksPerSection) - 1;

            OrdinalList freeHandles = new OrdinalList();

            freeHandles.Ceiling = lastIndex;

            OrdinalList usedBlocks = new OrdinalList();

            usedBlocks.Ceiling = lastIndex;

            foreach (var section in sections)
            {
                section.GetFree(freeHandles, usedBlocks, _fget);
            }

            _sections    = sections;
            _freeHandles = freeHandles;
            _freeBlocks  = usedBlocks.Invert(lastIndex);
            if (!_options.CommitOnWrite)
            {
                _reservedBlocks = usedBlocks;
            }
            _firstFreeBlock = _prevFreeBlock = _prevFreeHandle = 0;
            return(true);
        }
        public void ConcurrencyTest()
        {
            using (TempFile temp = new TempFile())
                using (ManualResetEvent stop = new ManualResetEvent(false))
                    using (TempFile copy = new TempFile())
                        using (TransactedCompoundFile test = new TransactedCompoundFile(
                                   new TransactedCompoundFile.Options(temp.TempPath)
                        {
                            BlockSize = 512, CreateNew = true
                        }))
                            using (WorkQueue workers = new WorkQueue(5))
                            {
                                bool failed = false;
                                workers.OnError += (o, e) => failed = true;
                                for (int i = 0; i < 5; i++)
                                {
                                    workers.Enqueue(() => ExersizeFile(stop, test));
                                }

                                do
                                {
                                    System.Threading.Thread.Sleep(1000);
                                    test.Commit();
                                    File.Copy(temp.TempPath, copy.TempPath, true);
                                    Assert.AreEqual(0, copy.Length % 512);
                                    int hcount = (int)(copy.Length / 512);

                                    using (TransactedCompoundFile verify = new TransactedCompoundFile(
                                               new TransactedCompoundFile.Options(copy.TempPath)
                                    {
                                        BlockSize = 512, CreateNew = false
                                    }))
                                    {
                                        OrdinalList free = new OrdinalList();
                                        free.Ceiling = hcount;
                                        for (int i = 0; i < hcount; i++)
                                        {
                                            uint h = verify.Create();
                                            free.Add((int)h);
                                            if (h >= hcount)
                                            {
                                                break;
                                            }
                                        }

                                        int         verifiedCount = 0;
                                        OrdinalList used          = free.Invert(hcount);
                                        foreach (uint h in used)
                                        {
                                            // skip reserved offsets.
                                            if (h % (512 / 4) == 0 || (h + 1) % (512 / 4) == 0)
                                            {
                                                continue;
                                            }

                                            IOStream.ReadAllBytes(verify.Read(h));
                                            verifiedCount++;
                                        }
                                        System.Diagnostics.Trace.WriteLine("Verified handle count: " + verifiedCount);
                                    }
                                } while (!failed && System.Diagnostics.Debugger.IsAttached);

                                stop.Set();
                                workers.Complete(false, 1000);
                                Assert.IsFalse(failed);
                            }
        }