public Usage Count_Empty_Slots() { int invalid = 0; int valid = 0; int blockSize = _node_Factory.Size_In_Bytes(3); long position = Index_Stream.Position; Index_Stream.Seek(8, SeekOrigin.Begin); var buffer = new byte[blockSize]; while (Index_Stream.Read(buffer, 0, buffer.Length) > 0) { var node = _node_Factory.From_Bytes(buffer, 3); if (node.IsValid) { valid++; } else { invalid++; } } int used = valid * blockSize; int wasted = invalid * blockSize; Index_Stream.Seek(position, SeekOrigin.Begin); return(new Usage { Invalid = invalid, Valid = valid }); }
protected Node <T> Read_Node(long address) { var buffer = new byte[_block_Size]; Index_Stream.Seek(address, SeekOrigin.Begin); Index_Stream.Read(buffer, 0, buffer.Length); return(_node_Factory.From_Bytes(buffer, Order)); }
public void Commit() { if (!_pending_Changes.Has_Pending_Changes()) { return; } foreach (var address in _pending_Changes.Get_Freed_Empty_Slots()) { _cache.Invalidate(address); } var newRoot = _pending_Changes.Commit(Index_Stream, Data_Stream); writes++; Metadata_Stream.Seek(0, SeekOrigin.Begin); var buffer = new byte[512]; _metadata.DataStream_Length = _pending_Changes.Get_Current_Data_Pointer(); _metadata.IndexStream_Length = _pending_Changes.Get_Index_Pointer(); _metadata.Root_Address = newRoot.Address; _metadata.Clustered_Data_Length = Cluster_Data_Length; _metadata.Alignment = Alignment; _metadata.Number_Of_Keys += key_added; _metadata.Number_Of_Leaves += leaves_added; _metadata.Number_Of_Nodes += nodes_added; _metadata.Height = 0; _metadata.To_Bytes_In_Buffer(buffer, 0); Metadata_Stream.Write(buffer, 0, buffer.Length); Metadata_Stream.Flush(); Root = newRoot; _pending_Changes.Clean_Root(); key_added = leaves_added = nodes_added = 0; // TODO persist empty pages on metadata ? //Cached_Nodes.Clear(); //foreach (var node in Pending_Changes.Last_Cached_Nodes()) // Cached_Nodes[node.Address] = node; _index_Pointer = _pending_Changes.Get_Index_Pointer(); Index_Stream.Flush(); }
public void Mark_As_Invalid(Stream index, long block_Address) { Index_Stream.Seek(block_Address, SeekOrigin.Begin); Index_Stream.Write(BitConverter.GetBytes(-1), 0, 4); }
public void Dispose() { Index_Stream.Dispose(); Metadata_Stream.Dispose(); Data_Stream.Dispose(); }
public void Flush() { Index_Stream.Flush(); }