示例#1
0
        private void MultiAddOnNewValue(Transaction tx, Slice key, Slice value, ushort?version, int maxNodeSize)
        {
            var requiredPageSize = Constants.PageHeaderSize + SizeOf.LeafEntry(-1, value, 0) + Constants.NodeOffsetSize;

            if (requiredPageSize > maxNodeSize)
            {
                // no choice, very big value, we might as well just put it in its own tree from the get go...
                // otherwise, we would have to put this in overflow page, and that won't save us any space anyway

                var tree = Create(tx, TreeFlags.MultiValue);
                tree.DirectAdd(value, 0);
                tx.AddMultiValueTree(this, key, tree);

                DirectAdd(key, sizeof(TreeRootHeader), NodeFlags.MultiValuePageRef);
                return;
            }

            var actualPageSize = (ushort)Math.Min(Utils.NearestPowerOfTwo(requiredPageSize), maxNodeSize);

            var ptr = DirectAdd(key, actualPageSize);

            var nestedPage = new Page(ptr, "multi tree", actualPageSize)
            {
                PageNumber = -1L,                // hint that this is an inner page
                Lower      = (ushort)Constants.PageHeaderSize,
                Upper      = actualPageSize,
                Flags      = PageFlags.Leaf,
            };

            CheckConcurrency(key, value, version, 0, TreeActionType.Add);

            nestedPage.AddDataNode(0, value, 0, 0);
        }
示例#2
0
        private void MultiAddOnNewValue(Transaction tx, Slice key, Slice value, ushort?version, int maxNodeSize)
        {
            MemorySlice valueToInsert;

            if (KeysPrefixing)
            {
                valueToInsert = new PrefixedSlice(value); // first item is never prefixed
            }
            else
            {
                valueToInsert = value;
            }

            var requiredPageSize = Constants.PageHeaderSize +      // header of a nested page
                                   Constants.NodeOffsetSize +      // one node in a nested page
                                   SizeOf.LeafEntry(-1, value, 0); // node header and its value

            if (requiredPageSize + Constants.NodeHeaderSize > maxNodeSize)
            {
                // no choice, very big value, we might as well just put it in its own tree from the get go...
                // otherwise, we would have to put this in overflow page, and that won't save us any space anyway

                var tree = Create(tx, KeysPrefixing, TreeFlags.MultiValue);
                tree.DirectAdd(value, 0);
                tx.AddMultiValueTree(this, key, tree);

                DirectAdd(key, sizeof(TreeRootHeader), NodeFlags.MultiValuePageRef);
                return;
            }

            var actualPageSize = (ushort)Math.Min(Utils.NearestPowerOfTwo(requiredPageSize), maxNodeSize - Constants.NodeHeaderSize);

            var ptr = DirectAdd(key, actualPageSize);

            var nestedPage = new Page(ptr, "multi tree", actualPageSize)
            {
                PageNumber = -1L,// hint that this is an inner page
                Lower      = (ushort)Constants.PageHeaderSize,
                Upper      = KeysPrefixing ? (ushort)(actualPageSize - Constants.PrefixInfoSectionSize) : actualPageSize,
                Flags      = KeysPrefixing ? PageFlags.Leaf | PageFlags.KeysPrefixed : PageFlags.Leaf,
            };

            nestedPage.ClearPrefixInfo();

            CheckConcurrency(key, value, version, 0, TreeActionType.Add);

            nestedPage.AddDataNode(0, valueToInsert, 0, 0);
        }