private int FindEmptyItem(int startIndex) { startIndex++; var emptyEntryIndex = default(int?); var maxCapacity = index.SizeInBlocks * index.BlockSize; if (maxCapacity > startIndex) { var buffer = new DirectoryItem[maxCapacity - startIndex]; blockStream.Read(startIndex, buffer); emptyEntryIndex = buffer .Where(x => x.Entry.Flags == DirectoryFlags.None || (x.Entry.Flags & DirectoryFlags.Deleted) != 0) .Select((x, entryIndex) => (int?)entryIndex) .FirstOrDefault(); } if (emptyEntryIndex == null) { index.SetSizeInBlocks(index.SizeInBlocks + 1); return(startIndex); } return(startIndex + emptyEntryIndex.Value); }
private void AddEntry(DirectoryItem directoryEntryItem) { blockStream.Write(firstEmptyItemOffset, new[] { directoryEntryItem }); firstEmptyItemOffset = FindEmptyItem(firstEmptyItemOffset); itemsCount++; Flush(); }
private void UpdateHeader() { var directoryHeaderItem = new DirectoryItem { Header = new DirectoryHeader { FirstEmptyItemOffset = firstEmptyItemOffset, NameBlockIndex = nameBlockIndex, ItemsCount = itemsCount, LastNameOffset = lastNameOffset, ParentDirectoryBlockIndex = parentDirectoryBlockId } }; blockStream.Write(0, new[] { directoryHeaderItem }); }
public IUnsafeDirectory Read(int blockId) { if (blockId < 0) { throw new ArgumentOutOfRangeException(nameof(blockId)); } var indexBlockProvider = indexBlockProviderFactory.Create(blockId, directoryCache); var index = directoryIndexFactory.Create(indexBlockProvider, directoryCache); var indexStream = directoryBlockStreamFactory.Create(index); var buffer = new DirectoryItem[1]; indexStream.Read(0, buffer); var header = buffer[0].Header; return(directoryFactory.Create(index, directoryCache, header)); }
private void AddEntry(int blockId, string name, DirectoryFlags flags) { indexLock.EnterWriteLock(); try { var directoryEntryItem = new DirectoryItem { Entry = new DirectoryEntryStruct { BlockIndex = blockId, Created = DateTime.Now.Ticks, Updated = DateTime.Now.Ticks, Size = 0, Flags = flags, NameOffset = StoreName(name) } }; AddEntry(directoryEntryItem); } finally { indexLock.ExitWriteLock(); } }
public void UpdateEntry(int blockId, IDirectoryEntryInfoOverrides overrides) { if (overrides == null) { throw new ArgumentNullException(nameof(overrides)); } if (blockId < 0) { throw new ArgumentOutOfRangeException(nameof(blockId)); } indexLock.EnterWriteLock(); try { var buffer = new DirectoryItem[itemsCount]; blockStream.Read(1, buffer); for (var i = 0; i < buffer.Length; i++) { var entry = buffer[i]; if (entry.Entry.BlockIndex == blockId && (entry.Entry.Flags & DirectoryFlags.Deleted) == 0) { ApplyOverrides(ref entry.Entry, overrides); blockStream.Write(i + 1, new[] { entry }); return; } } } finally { indexLock.ExitWriteLock(); } throw new Exception("Entry not found"); }
public IDirectoryEntryInfo[] GetDirectoryEntries() { indexLock.EnterReadLock(); try { var result = new List <IDirectoryEntryInfo>(itemsCount); if (itemsCount > 0) { var buffer = new DirectoryItem[itemsCount]; blockStream.Read(1, buffer); var names = new short[lastNameOffset]; nameIndexBlockStream.Read(0, names); foreach (var item in buffer.Where(x => (x.Entry.Flags & DirectoryFlags.Deleted) == 0)) { var entry = item.Entry; var nameLength = names[entry.NameOffset]; var nameBuffer = new char[nameLength]; for (var i = 0; i < nameLength; i++) { nameBuffer[i] = (char)names[entry.NameOffset + 1 + i]; } result.Add(new DirectoryEntryInfo(entry, new string(nameBuffer))); } } return(result.ToArray()); } finally { indexLock.ExitReadLock(); } }