示例#1
0
        /// <summary>
        /// Write entries directory to pages. If pages not enough for new directory - additional pages will allocated.
        /// Also write header and pageAllocator state
        /// </summary>
        public void Write(Stream stm, PagedContainerHeader header, PageAllocator pageAllocator)
        {
            var targetPages = pages;

            var buff = entries.WriteEntries(header.DataHandler);

            var requiredPages = header.GetRequiredPages(buff.Length);

            if (requiredPages > targetPages.Length) // need to allocate additional pages?
            {
                targetPages = targetPages.Concat(pageAllocator.AllocatePages(requiredPages - targetPages.Length)).ToArray();
            }
            else if (requiredPages < targetPages.Length) // can free unused pages?
            {
                var mustBeFreePages = targetPages.Skip(requiredPages).ToArray();
                targetPages = targetPages.Take(requiredPages).ToArray();

                pageAllocator.FreePages(mustBeFreePages);
            }

            stm.WriteIntoPages(header, buff, 0, targetPages);

            header.DirectoryFirstPage = targetPages[0];
            header.Write(stm);

            pageAllocator.Write(stm);

            pages = targetPages;
        }
示例#2
0
        protected PagedContainerAbstract(Stream stm, PersistentContainerSettings?settings = null)
        {
            Stream = stm;
            settings ??= new PersistentContainerSettings();
            try
            {
                if (stm.Length == 0) // new file
                {
                    Header = new PagedContainerHeader(settings);
                    Header.Write(stm);

                    pageAllocator = new PageAllocator(Header);
                    pageAllocator.Write(stm);
                }
                else
                {
                    Header        = new PagedContainerHeader(stm, settings.encryptorDecryptor);
                    pageAllocator = new PageAllocator(Header, stm);
                }

                entries = Header.DirectoryFirstPage == 0
                    ? new PagedContainerEntryCollection()
                    : new PagedContainerEntryCollection(Header, stm.ReadWithPageSequence(Header, Header.DirectoryFirstPage));
            }
            catch
            {
                Dispose();
                throw;
            }
        }