/// <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; }
/// <summary> /// Remove entries by keys. Mask * and ? supported. /// Return deleted keys. /// </summary> public virtual string[] Delete(params string[] keys) { throwIfHasOpenedStream(keys); var r = new List <string>(); foreach (var entry in entries.Find(keys).ToArray()) { r.Add(entry.Name); var pages = Stream.ReadPageSequence(Header, entry.FirstPage); pageAllocator.FreePages(pages); entries.Remove(entry); } if (Flags.HasFlag(PersistentContainerFlags.WriteDirImmediately)) { WriteHeaders(); } return(r.ToArray()); }