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); }
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); }