public Node Clone_Chain_To_Root(Node node, long prev_Address) { if (node.Parent == null) return node; var parent = node.Parent; for (int i = 0; i < parent.Key_Num +1; i++) if (parent.Pointers[i] == prev_Address) parent.Pointers[i] = node.Address; prev_Address = parent.Address; Write_Node(parent); Free_Address(prev_Address); return Clone_Chain_To_Root(parent, prev_Address); }
protected Node Read_Node(Node parent, long address) { Index_Stream.Seek(address, SeekOrigin.Begin); var buffer = new byte[Node.Size_In_Bytes(Size)]; Index_Stream.Read(buffer, 0, buffer.Length); if (_readMemory_Count.ContainsKey(address)) _readMemory_Count[address] += 1; else _readMemory_Count[address] = 1; var node = Node.From_Bytes(buffer, Size); node.Parent = parent; node.Address = address; return node; }
protected Node Split(Node node) { var newNode = Node.Create_New(Size, node.IsLeaf); var mid_Key = node.Keys[Size / 2]; newNode.Key_Num = Size - Size / 2 - 1; for (int i = 0; i < newNode.Key_Num; i++) { newNode.Keys[i] = node.Keys[i + (Size / 2 + 1)]; newNode.Pointers[i] = node.Pointers[i + (Size / 2 + 1)]; } newNode.Pointers[newNode.Key_Num] = node.Pointers[Size]; node.Key_Num = Size / 2; if (node.IsLeaf) { node.Key_Num++; newNode.Pointers[0] = node.Pointers[0]; Write_Node(newNode); node.Pointers[0] = newNode.Address; mid_Key = node.Keys[Size / 2 + 1]; } else Write_Node(newNode); //Update_Node(node); long previous_Address = node.Address; Write_Node(node); Free_Address(previous_Address); if (node.Parent == null) // if i'm splitting the root, i need a new up level { var root = Node.Create_New(Size, false); root.Keys[0] = mid_Key; root.Pointers[0] = node.Address; root.Pointers[1] = newNode.Address; root.Key_Num = 1; node.Parent = root; Write_Node(root); node.Parent = newNode.Parent = Root; return root; } else { newNode.Parent = node.Parent; for (int i = 0; i < node.Parent.Key_Num + 1; i++) if (node.Parent.Pointers[i] == previous_Address) node.Parent.Pointers[i] = node.Address; return Insert_in_node(node.Parent, mid_Key, newNode.Address); } }
protected Node Insert_in_node(Node node, int key, long address) { int x = 0; while (x < node.Key_Num && node.Keys[x] < key) x++; for (int i = node.Key_Num; i > x; i--) node.Keys[i] = node.Keys[i - 1]; for (int i = node.Key_Num + 1; i > x + 1; i--) node.Pointers[i] = node.Pointers[i - 1]; node.Keys[x] = key; node.Pointers[x + 1] = address; node.Key_Num++; if (node.Key_Num == Size) return Split(node); else { long previous_Address = node.Address; Write_Node(node); Free_Address(previous_Address); //Update_Node(node); node = Clone_Chain_To_Root(node, previous_Address); } return node; }
protected void Delete_Key_In_Node(Node node, int key) { int x = 0; while (key != node.Keys[x]) x++; for (int i = x; i < node.Key_Num - 1; i++) node.Keys[i] = node.Keys[i + 1]; for (int i = x + 1; i < node.Key_Num; i++) node.Pointers[i] = node.Pointers[i + 1]; node.Key_Num--; }
protected void Write_Node(Node node) { if (Empty_Slots.Any()) { var address = Empty_Slots.Dequeue(); Reserved_Empty_Slots.Add(address); Write_Node(node, address); } else { var address = Index_Pointer(); Write_Node(node, address); _index_Pointer += Node.Size_In_Bytes(Size); } }
protected void Write_Node(Node node, long address) { node.Address = address; Index_Stream.Seek(address, SeekOrigin.Begin); var bytes = node.To_Bytes(); Index_Stream.Write(bytes, 0, bytes.Length); if (_writeMemory_Count.ContainsKey(address)) _writeMemory_Count[address] += 1; else _writeMemory_Count[address] = 1; }