Ejemplo n.º 1
0
        public void CreateNewBlock(Guid id, ulong blockCount)
        {
            if (blockCount > UInt32.MaxValue)
            {
                throw new Exception("VirtualBlocks larger than 2^32-1 are not yet supported!");
            }
            using(_configurationLock.EnterWriteLock())
            {
                if (_blocks.ContainsKey(id))
                {
                    throw new Exception("Block already exists!");
                }
                if (blockCount > uint.MaxValue)
                {
                    throw new NotImplementedException("More than 2^32-1 blocks not yet supported at create-time!");
                }

                MetaGroupHeader xGroupHeader = null;
                foreach (var xMetaGroup in _metaHeaders)
                {
                    if (xMetaGroup.Parts.Length < _metaGroupItemsPerVirtualBlock)
                    {
                        xGroupHeader = xMetaGroup;
                        break;
                    }
                }
                if (xGroupHeader == null)
                {
                    throw new Exception("No GroupHeader found with a free slot!");
                }

                var xNextPostValues = (from item in _metaHeaders
                                       where item.Parts.Length > 0
                                       select (from subItem in item.Parts
                                               select subItem.FirstDataBlockNumber + subItem.BlockCount).Max()).ToArray();
                ulong xNextPos;
                if (xNextPostValues.Any())
                {
                    xNextPos = xNextPostValues.Max();
                }
                else
                {
                    xNextPos = (from item in _metaHeaders
                                select item.BlockId + 1).Max();
                }

                if ((((xNextPos + blockCount) * _virtualBlockSize) / _blockStore.BlockSize) > _blockStore.BlockCount)
                {
                    throw new Exception("No free space found!");
                }

                var xNewPartsList = new List<VirtualBlockPart>(xGroupHeader.Parts);

                var xNewPart = new VirtualBlockPart
                               {
                                   BlockCount = (uint)blockCount,
                                   FirstDataBlockNumber = xNextPos,
                                   PartIndex = 0,
                                   TotalPartCount = 1
                               };
                var xVBlock = new VirtualBlockConfig
                              {
                                  Identifier = id,
                                  Parts = new List<VirtualBlockPart>
                                          {
                                              xNewPart
                                          },
                                  TotalLength = blockCount
                              };
                xNewPart.VirtualBlock = xVBlock;
                xNewPartsList.Add(xNewPart);
                xGroupHeader.Parts = xNewPartsList.ToArray();
                _blocks.Add(id, xVBlock);
            }
            using(_openBlocksLock.EnterWriteLock())
            {
                _openBlocks.Add(id, new List<VBlockContentStore>());
            }
        }
Ejemplo n.º 2
0
        private void LoadConfiguration()
        {
            using(_configurationLock.EnterWriteLock())
            {
                var xBuff = new byte[_virtualBlockSize];
                var xBuffSeg = new ArraySegment<byte>(xBuff);
                var xNextMetaGroupBlock = 0UL;
                do
                {
                    RetrieveVirtualBlock(xNextMetaGroupBlock, xBuffSeg);
                    var xMetaGroupHeader = new MetaGroupHeader
                                           {
                                               BlockId = xNextMetaGroupBlock
                                           };
                    var xStartOffset = 0;
                    if (xNextMetaGroupBlock == 0)
                    {
                        xStartOffset = 8;
                    }

                    xNextMetaGroupBlock = ByteConverter.ReadUInt64(xBuff, xStartOffset);
                    xStartOffset = 32;
                    var xParts = new List<VirtualBlockPart>((int)_metaGroupItemsPerVirtualBlock);
                    for (uint i = 0; i < _metaGroupItemsPerVirtualBlock; i++)
                    {
                        var xVBlockId = ByteConverter.ReadGuid(xBuff, xStartOffset);
                        if (xVBlockId != Guid.Empty)
                        {
                            var xVBlockPart = new VirtualBlockPart
                                              {
                                                  TotalPartCount = ByteConverter.ReadUInt16(xBuff, xStartOffset + 16),
                                                  PartIndex = ByteConverter.ReadUInt16(xBuff, xStartOffset + 18),
                                                  FirstDataBlockNumber = ByteConverter.ReadUInt64(xBuff, xStartOffset + 20),
                                                  BlockCount = ByteConverter.ReadUInt32(xBuff, xStartOffset + 28)
                                              };
                            VirtualBlockConfig xBlockConfig;
                            if(!_blocks.TryGetValue(xVBlockId, out xBlockConfig))
                            {
                                xBlockConfig = new VirtualBlockConfig();
                                xBlockConfig.Identifier = xVBlockId;
                                xBlockConfig.Parts=new List<VirtualBlockPart>(4);
                                _blocks.Add(xVBlockId, xBlockConfig);
                            }
                            xBlockConfig.Parts.Add(xVBlockPart);
                        }
                        xStartOffset += 32;
                    }
                    xMetaGroupHeader.Parts = xParts.ToArray();
                    _metaHeaders.Add(xMetaGroupHeader);
                } while (xNextMetaGroupBlock != 0);

                if (_blocks.Count > 0)
                {
                    using (_openBlocksLock.EnterWriteLock())
                    {
                        foreach (var xItem in _blocks)
                        {
                            xItem.Value.TotalLength = (from item in xItem.Value.Parts
                                                       select (ulong)item.BlockCount).Sum();
                            _openBlocks.Add(xItem.Key, new List<VBlockContentStore>());
                        }
                    }
                }
            }
        }