public void SetSizeInBlocks(int count) { if (count < 0) { throw new ArgumentOutOfRangeException(nameof(count)); } var currentBlockCount = provider.UsedEntryCount; if (count == currentBlockCount) { return; } if (count > currentBlockCount) { provider.SetSizeInBlocks(count / provider.BlockSize + (count % provider.BlockSize == 0 ? 0 : 1)); var allocateBlockCount = count - currentBlockCount; var blocks = accessParameters.AllocationManager.Allocate(allocateBlockCount); indexBlockStream.Write(currentBlockCount, blocks); } else { var releaseBlockCount = currentBlockCount - count; var blocks = new int[releaseBlockCount]; indexBlockStream.Read(currentBlockCount - releaseBlockCount, blocks); accessParameters.AllocationManager.Release(blocks); blocks = new int[releaseBlockCount]; indexBlockStream.Write(currentBlockCount - releaseBlockCount, blocks); provider.SetSizeInBlocks(count / provider.BlockSize + count % provider.BlockSize == 0 ? 0 : 1); } }
public int[] Allocate(int blockCount) { if (blockCount <= 0) { throw new ArgumentOutOfRangeException(nameof(blockCount)); } var allocatedFromIndexBlocks = new int[0]; lock (lockObject) { var allocatedFromIndexBlockCount = Math.Min(ReleasedBlockCount, blockCount); if (allocatedFromIndexBlockCount > 0) { allocatedFromIndexBlocks = new int[allocatedFromIndexBlockCount]; var position = ReleasedBlockCount - allocatedFromIndexBlockCount; blockStream.Read(position, allocatedFromIndexBlocks); blockStream.Write(position, new int[allocatedFromIndexBlockCount]); ReleasedBlockCount -= allocatedFromIndexBlockCount; } var leftBlocks = blockCount - allocatedFromIndexBlockCount; if (leftBlocks > 0) { var blocks = storage.Extend(leftBlocks); return(allocatedFromIndexBlocks.Concat(blocks).ToArray()); } } EraseBlocks(allocatedFromIndexBlocks); return(allocatedFromIndexBlocks); }
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(); } }
public void Read(int position, byte[] buffer) { if (buffer == null) { throw new ArgumentNullException(nameof(buffer)); } if (position < 0 || position + buffer.Length > Size) { throw new ArgumentOutOfRangeException(nameof(position)); } lockObject.EnterReadLock(); try { blockStream.Read(position, buffer); } finally { lockObject.ExitReadLock(); } }