protected override long GetWritePositionLocked(OperationHint hint, int length)
        {
            var contentHint = hint as OptimizedOperation ?? throw new ArgumentException(nameof(hint));
            var retv        = -1L;

            lock (_blocksLockObject)
            {
                if (!TryGetAvailableBlock(length, out var block))
                {
                    retv = CurrentPosition;
                }
                else
                {
                    contentHint.IsExistingBlockUsed = true;
                    retv = block.Position;

                    if (block.Length <= length)
                    {
                        return(retv);
                    }

                    var generatedBlock = new DriveBlock
                    {
                        Length   = block.Length - length,
                        Position = block.Position + length
                    };

                    AddAvailableBlock(generatedBlock);
                    contentHint.GeneratedAvailableBlock = generatedBlock;
                }
            }

            return(retv);
        }
Exemple #2
0
        public IEnumerable <DriveBlock> AllocateSpace(int dataLength)
        {
            lock (_allocateLock)
            {
                var dataLeft = dataLength;
                while (dataLeft > 0)
                {
                    if (!TryGetAvailableBlock(dataLength, out var block))
                    {
                        CurrentPosition = InitialPosition + Length;
                        block           = new DriveBlock
                        {
                            Length   = dataLength,
                            Position = CurrentPosition
                        };

                        CurrentPosition += block.Length;
                        Length          += block.Length;
                    }

                    yield return(block);

                    dataLeft -= block.Length;
                }
            }
        }
        public void RemoveAvailableBlock(DriveBlock block)
        {
            lock (_blocksLockObject)
            {
                var queue = _availableBlocks[block.Length];
                var list  = queue.ToList();
                list.Remove(block);
                if (!list.Any())
                {
                    _availableBlocks.Remove(block.Length);
                    return;
                }

                _availableBlocks[block.Length] = new Queue <DriveBlock>(list);
            }
        }
Exemple #4
0
        protected override bool HandleAddedAvailableBlock(DriveBlock block)
        {
            //min entry length = 42
            if (block.Length < 42)
            {
                return(false);
            }

            var blockLengthBytes = BitConverter.GetBytes(block.Length);

            var bytesList = new List <byte>(blockLengthBytes)
            {
                (byte)ServiceMarks.Proceed
            };

            var operation = new FileTableOperation(drive => drive.Write(block.Position, bytesList.ToArray()), block.Position);

            Synchronizer.EnqueueOperation(operation);
            return(true);
        }
        public void AddAvailableBlock(DriveBlock block)
        {
            if (block == null)
            {
                throw new ArgumentNullException(nameof(block));
            }

            if (!HandleAddedAvailableBlock(block))
            {
                return;
            }

            lock (_blocksLockObject)
            {
                if (!_availableBlocks.ContainsKey(block.Length))
                {
                    _availableBlocks[block.Length] = new Queue <DriveBlock>();
                }

                _availableBlocks[block.Length].Enqueue(block);
            }
        }
        protected virtual bool TryGetAvailableBlock(int length, out DriveBlock block)
        {
            lock (_blocksLockObject)
            {
                block = null;
                if (!_availableBlocks.TryGetValue(length, out var queue) ||
                    _availableBlocks.Keys.All(x => x < length))
                {
                    return(false);
                }

                if (queue == null)
                {
                    var key = _availableBlocks.Keys.FirstOrDefault(x => x > length);
                    queue = _availableBlocks[key];
                }

                block = queue.Dequeue();

                if (block.Length > length)
                {
                    var generatedBlock = new DriveBlock
                    {
                        Length   = block.Length - length,
                        Position = block.Position + length
                    };

                    AddAvailableBlock(generatedBlock);
                }

                if (!queue.Any())
                {
                    _availableBlocks.Remove(length);
                }

                return(true);
            }
        }
 protected virtual bool HandleAddedAvailableBlock(DriveBlock block)
 {
     return(true);
 }
Exemple #8
0
 protected override bool TryGetAvailableBlock(int length, out DriveBlock block)
 {
     return(base.TryGetAvailableBlock(length, out block) && block.Length >= 42);
 }
Exemple #9
0
 public DriveBlock(DriveBlock block)
 {
     Position = block.Position;
     Length   = block.Length;
 }