/// <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; }
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; } }