Example #1
0
        private void MoveLeafNode(Page parentPage, Page from, Page to)
        {
            Debug.Assert(from.IsBranch == false);
            var originalFromKeyStart = GetActualKey(from, from.LastSearchPositionOrLastEntry);

            var fromNode = from.GetNode(from.LastSearchPosition);
			byte* val = @from.Base + @from.KeysOffsets[@from.LastSearchPosition] + Constants.NodeHeaderSize + originalFromKeyStart.Size;

			var nodeVersion = fromNode->Version; // every time new node is allocated the version is increased, but in this case we do not want to increase it
			if (nodeVersion > 0)
				nodeVersion -= 1;

	        var prefixedOriginalFromKey = to.PrepareKeyToInsert(originalFromKeyStart, to.LastSearchPosition);

	        byte* dataPos;
	        var fromDataSize = fromNode->DataSize;
	        switch (fromNode->Flags)
	        {
				case NodeFlags.PageRef:
					to.EnsureHasSpaceFor(_tx, prefixedOriginalFromKey, -1);
					dataPos = to.AddPageRefNode(to.LastSearchPosition, prefixedOriginalFromKey, fromNode->PageNumber);
					break;
				case NodeFlags.Data:
					to.EnsureHasSpaceFor(_tx, prefixedOriginalFromKey, fromDataSize);
					dataPos = to.AddDataNode(to.LastSearchPosition, prefixedOriginalFromKey, fromDataSize, nodeVersion);
					break;
				case NodeFlags.MultiValuePageRef:
					to.EnsureHasSpaceFor(_tx, prefixedOriginalFromKey, fromDataSize);
					dataPos = to.AddMultiValueNode(to.LastSearchPosition, prefixedOriginalFromKey, fromDataSize, nodeVersion);
					break;
				default:
			        throw new NotSupportedException("Invalid node type to move: " + fromNode->Flags);
	        }
			
			if(dataPos != null && fromDataSize > 0)
                Memory.Copy(dataPos, val, fromDataSize);
            
            from.RemoveNode(from.LastSearchPositionOrLastEntry);

            var pos = parentPage.LastSearchPositionOrLastEntry;
            parentPage.RemoveNode(pos);

            var newSeparatorKey = GetActualKey(to, 0); // get the next smallest key it has now
            var pageNumber = to.PageNumber;
            if (parentPage.GetNode(0)->PageNumber == to.PageNumber)
            {
                pageNumber = from.PageNumber;
                newSeparatorKey = GetActualKey(from, 0);
            }

			AddSeparatorToParentPage(parentPage, pageNumber, newSeparatorKey, pos);
        }
Example #2
0
 private byte* AddNodeToPage(Page page, int index)
 {
     switch (_nodeType)
     {
         case NodeFlags.PageRef:
             return page.AddPageRefNode(index, _newKey, _pageNumber);
         case NodeFlags.Data:
             return page.AddDataNode(index, _newKey, _len, _nodeVersion);
         case NodeFlags.MultiValuePageRef:
             return page.AddMultiValueNode(index, _newKey, _len, _nodeVersion);
         default:
             throw new NotSupportedException("Unknown node type");
     }
 }
Example #3
0
        private byte* AddNodeToPage(Page page, int index, MemorySlice alreadyPreparedNewKey = null)
        {
	        var newKeyToInsert = alreadyPreparedNewKey ?? page.PrepareKeyToInsert(_newKey, index);

            switch (_nodeType)
            {
                case NodeFlags.PageRef:
					return page.AddPageRefNode(index, newKeyToInsert, _pageNumber);
                case NodeFlags.Data:
					return page.AddDataNode(index, newKeyToInsert, _len, _nodeVersion);
                case NodeFlags.MultiValuePageRef:
					return page.AddMultiValueNode(index, newKeyToInsert, _len, _nodeVersion);
                default:
                    throw new NotSupportedException("Unknown node type");
            }
        }
Example #4
0
        private void MoveLeafNode(Page parentPage, Page from, Page to)
        {
            Debug.Assert(from.IsBranch == false);
            var originalFromKeyStart = GetActualKey(from, from.LastSearchPositionOrLastEntry);

            var   fromNode = from.GetNode(from.LastSearchPosition);
            byte *val      = @from.Base + @from.KeysOffsets[@from.LastSearchPosition] + Constants.NodeHeaderSize + originalFromKeyStart.Size;

            var nodeVersion = fromNode->Version; // every time new node is allocated the version is increased, but in this case we do not want to increase it

            if (nodeVersion > 0)
            {
                nodeVersion -= 1;
            }

            var prefixedOriginalFromKey = to.PrepareKeyToInsert(originalFromKeyStart, to.LastSearchPosition);

            byte *dataPos;
            var   fromDataSize = fromNode->DataSize;

            switch (fromNode->Flags)
            {
            case NodeFlags.PageRef:
                to.EnsureHasSpaceFor(_tx, prefixedOriginalFromKey, -1);
                dataPos = to.AddPageRefNode(to.LastSearchPosition, prefixedOriginalFromKey, fromNode->PageNumber);
                break;

            case NodeFlags.Data:
                to.EnsureHasSpaceFor(_tx, prefixedOriginalFromKey, fromDataSize);
                dataPos = to.AddDataNode(to.LastSearchPosition, prefixedOriginalFromKey, fromDataSize, nodeVersion);
                break;

            case NodeFlags.MultiValuePageRef:
                to.EnsureHasSpaceFor(_tx, prefixedOriginalFromKey, fromDataSize);
                dataPos = to.AddMultiValueNode(to.LastSearchPosition, prefixedOriginalFromKey, fromDataSize, nodeVersion);
                break;

            default:
                throw new NotSupportedException("Invalid node type to move: " + fromNode->Flags);
            }

            if (dataPos != null && fromDataSize > 0)
            {
                Memory.Copy(dataPos, val, fromDataSize);
            }

            from.RemoveNode(from.LastSearchPositionOrLastEntry);

            var pos = parentPage.LastSearchPositionOrLastEntry;

            parentPage.RemoveNode(pos);

            var newSeparatorKey = GetActualKey(to, 0); // get the next smallest key it has now
            var pageNumber      = to.PageNumber;

            if (parentPage.GetNode(0)->PageNumber == to.PageNumber)
            {
                pageNumber      = from.PageNumber;
                newSeparatorKey = GetActualKey(from, 0);
            }

            AddSeparatorToParentPage(to, parentPage, pageNumber, newSeparatorKey, pos);
        }