Esempio n. 1
0
        public Result Initialize(SubStorage tableStorage)
        {
            // Read and verify the bucket tree header.
            // note: skip init
            var header = new BucketTree.Header();

            Result rc = tableStorage.Read(0, SpanHelpers.AsByteSpan(ref header));

            if (rc.IsFailure())
            {
                return(rc);
            }

            rc = header.Verify();
            if (rc.IsFailure())
            {
                return(rc);
            }

            // Determine extents.
            long nodeStorageSize    = QueryNodeStorageSize(header.EntryCount);
            long entryStorageSize   = QueryEntryStorageSize(header.EntryCount);
            long nodeStorageOffset  = QueryHeaderStorageSize();
            long entryStorageOffset = nodeStorageOffset + nodeStorageSize;

            // Initialize.
            var nodeStorage  = new SubStorage(tableStorage, nodeStorageOffset, nodeStorageSize);
            var entryStorage = new SubStorage(tableStorage, entryStorageOffset, entryStorageSize);

            return(Initialize(nodeStorage, entryStorage, header.EntryCount));
        }
Esempio n. 2
0
        public Result Initialize(SubStorage nodeStorage, SubStorage entryStorage, int nodeSize, int entrySize,
                                 int entryCount)
        {
            Assert.AssertTrue(entrySize >= sizeof(long));
            Assert.AssertTrue(nodeSize >= entrySize + Unsafe.SizeOf <NodeHeader>());
            Assert.AssertTrue(NodeSizeMin <= nodeSize && nodeSize <= NodeSizeMax);
            Assert.AssertTrue(Utilities.IsPowerOfTwo(nodeSize));
            Assert.AssertTrue(!IsInitialized());

            // Ensure valid entry count.
            if (entryCount <= 0)
            {
                return(ResultFs.InvalidArgument.Log());
            }

            // Allocate node.
            if (!_nodeL1.Allocate(nodeSize))
            {
                return(ResultFs.BufferAllocationFailed.Log());
            }

            bool needFree = true;

            try
            {
                // Read node.
                Result rc = nodeStorage.Read(0, _nodeL1.GetBuffer());
                if (rc.IsFailure())
                {
                    return(rc);
                }

                // Verify node.
                rc = _nodeL1.GetHeader().Verify(0, nodeSize, sizeof(long));
                if (rc.IsFailure())
                {
                    return(rc);
                }

                // Validate offsets.
                int offsetCount            = GetOffsetCount(nodeSize);
                int entrySetCount          = GetEntrySetCount(nodeSize, entrySize, entryCount);
                BucketTreeNode <long> node = _nodeL1.GetNode <long>();

                long startOffset;
                if (offsetCount < entrySetCount && node.GetCount() < offsetCount)
                {
                    startOffset = node.GetL2BeginOffset();
                }
                else
                {
                    startOffset = node.GetBeginOffset();
                }

                long endOffset = node.GetEndOffset();

                if (startOffset < 0 || startOffset > node.GetBeginOffset() || startOffset >= endOffset)
                {
                    return(ResultFs.InvalidBucketTreeEntryOffset.Log());
                }

                NodeStorage   = nodeStorage;
                EntryStorage  = entryStorage;
                NodeSize      = nodeSize;
                EntrySize     = entrySize;
                OffsetCount   = offsetCount;
                EntrySetCount = entrySetCount;
                StartOffset   = startOffset;
                EndOffset     = endOffset;

                needFree = false;

                return(Result.Success);
            }
            finally
            {
                if (needFree)
                {
                    _nodeL1.Free();
                }
            }
        }