예제 #1
0
        protected void Block_Usage_Finished(Block_Usage usage_Block)
        {
            var block = usage_Block.Block;

            var base_Address = block.Base_Address();


            _base_Address_Index.Remove(base_Address);
            block.Reserve_Size(usage_Block.Used_Length);

            Fix_Block_Position_In_Groups(block, base_Address, block.Base_Address(), block.Length + usage_Block.Used_Length, block.Length);

            if (block.IsEmpty())
            {
                _end_Address_Index.Remove(block.End_Address());
            }
            else
            {
                _base_Address_Index[block.Base_Address()] = block;
            }
        }
예제 #2
0
        public Node <T> Commit(Stream indexStream)
        {
            var pending_Nodes_ = new List <Node <T> >();

            Find_All_Pending_Nodes_From(pending_Nodes_, Uncommitted_Root);

            int neededBytes = Block_Size * pending_Nodes_.Count;

            var blocks = Look_For_Available_Blocks(neededBytes);

            Blocks_Count += blocks.Count;
            Nodes_Count  += pending_Nodes_.Count;
            Commit_Count++;

            foreach (var block in blocks)
            {
                if (Blocks_Count_By_Lenght.ContainsKey(block.Length))
                {
                    Blocks_Count_By_Lenght[block.Length]++;
                }
                else
                {
                    Blocks_Count_By_Lenght[block.Length] = 1;
                }
            }

            var block_At_End_Of_File = new Block_Usage(new Block(_index_Pointer, int.MaxValue));

            blocks.Add(block_At_End_Of_File);
            blocks = blocks.OrderBy(b => b.Base_Address()).ToList();

            var addressesQueue = new Queue <long>();

            foreach (var block in blocks)
            {
                for (int i = 0; i < block.Length && pending_Nodes_.Count > addressesQueue.Count; i += Block_Size)
                {
                    addressesQueue.Enqueue(block.Base_Address() + i);
                }
            }

            Update_Addresses_From(Uncommitted_Root, addressesQueue);

            var nodes = new Queue <Node <T> >(pending_Nodes_.OrderBy(d => d.Address));

            foreach (var block in blocks)
            {
                if (nodes.Count == 0)
                {
                    break;
                }

                var toUpdate = new List <Node <T> >();
                for (int j = 0; j < block.Length && nodes.Count > 0; j += Block_Size)
                {
                    toUpdate.Add(nodes.Dequeue());
                    block.Use(Block_Size);
                }

                int buffer_Size = toUpdate.Count * Block_Size;
                var buffer      = new byte[buffer_Size];
                for (int i = 0; i < toUpdate.Count; i++)
                {
                    Node_Factory.To_Bytes_In_Buffer(toUpdate[i], buffer, i * Block_Size);
                }

                indexStream.Seek(block.Base_Address(), SeekOrigin.Begin);
                indexStream.Write(buffer, 0, buffer.Length);
            }

            foreach (var block in blocks)
            {
                if (block == block_At_End_Of_File)
                {
                    _index_Pointer = block.Base_Address() + block.Used_Length;
                }
                else
                {
                    Block_Usage_Finished(block);
                }
            }

            foreach (var node in pending_Nodes_)
            {
                node.Is_Volatile = false;
            }

            Nodes.Clear();
            Nodes.AddRange(Pending_Nodes);
            Pending_Nodes.Clear();
            indexStream.Flush();

            Add_Block_Address_To_Available_Space();
            Freed_Empty_Slots.Clear();

            var newRoot = Node_Factory.Create_New_One_Like_This(Uncommitted_Root);

            for (int i = 0; i < newRoot.Key_Num + 1; i++)
            {
                newRoot.Children[i] = null;
            }
            return(newRoot);
        }