Esempio n. 1
0
        /// <summary>
        /// Writes the supplied stream to the binary stream.
        /// </summary>
        /// <param name="stream"></param>
        /// <param name="blockSize"></param>
        /// <param name="treeNodeType"></param>
        /// <param name="treeStream"></param>
        public static void Create(BinaryStreamPointerBase stream, int blockSize, EncodingDefinition treeNodeType, TreeStream <TKey, TValue> treeStream)
        {
            if (stream is null)
            {
                throw new ArgumentNullException("stream");
            }
            if (treeStream is null)
            {
                throw new ArgumentNullException("stream");
            }
            if (treeNodeType is null)
            {
                throw new ArgumentNullException("treeNodeType");
            }
            if (!(treeStream.IsAlwaysSequential && treeStream.NeverContainsDuplicates))
            {
                throw new ArgumentException("Stream must gaurentee sequential reads and that it never will contain a duplicate", "treeStream");
            }

            SortedTreeHeader header = new SortedTreeHeader();

            header.TreeNodeType         = treeNodeType;
            header.BlockSize            = blockSize;
            header.RootNodeLevel        = 0;
            header.RootNodeIndexAddress = 1;
            header.LastAllocatedBlock   = 1;

            Func <uint> getNextNewNodeIndex = () =>
            {
                header.LastAllocatedBlock++;
                return(header.LastAllocatedBlock);
            };

            SparseIndexWriter <TKey> indexer = new SparseIndexWriter <TKey>();

            NodeWriter <TKey, TValue> .Create(treeNodeType, stream, header.BlockSize, header.RootNodeLevel, header.RootNodeIndexAddress, getNextNewNodeIndex, indexer, treeStream);

            while (indexer.Count > 0)
            {
                indexer.SwitchToReading();
                header.RootNodeLevel++;
                header.RootNodeIndexAddress = getNextNewNodeIndex();

                SparseIndexWriter <TKey> indexer2 = new SparseIndexWriter <TKey>();
                NodeWriter <TKey, SnapUInt32> .Create(EncodingDefinition.FixedSizeCombinedEncoding, stream, header.BlockSize, header.RootNodeLevel, header.RootNodeIndexAddress, getNextNewNodeIndex, indexer2, indexer);

                indexer.Dispose();
                indexer = indexer2;
            }

            indexer.Dispose();

            header.IsDirty = true;
            header.SaveHeader(stream);
        }
Esempio n. 2
0
        /// <summary>
        /// Closes the current node and prepares a new node with the supplied key.
        /// </summary>
        /// <param name="sparseIndex"></param>
        /// <param name="newNodeIndex">the index for the next node.</param>
        /// <param name="writePointer">the pointer to the start of the block</param>
        /// <param name="key">the key to use.</param>
        /// <param name="header"></param>
        private static void NewNodeThenInsert(NodeHeader <TKey> header, SparseIndexWriter <TKey> sparseIndex, uint newNodeIndex, byte *writePointer, TKey key)
        {
            TKey dividingKey = new TKey(); //m_tempKey;

            key.CopyTo(dividingKey);

            uint currentNode = header.NodeIndex;

            //Finish this header.
            header.RightSiblingNodeIndex = newNodeIndex;
            key.CopyTo(header.UpperKey);
            header.Save(writePointer);

            //Prepare the next header
            header.NodeIndex             = newNodeIndex;
            header.RecordCount           = 0;
            header.ValidBytes            = (ushort)header.HeaderSize;
            header.LeftSiblingNodeIndex  = currentNode;
            header.RightSiblingNodeIndex = uint.MaxValue;
            key.CopyTo(header.LowerKey);
            header.UpperKey.SetMax();

            sparseIndex.Add(currentNode, dividingKey, newNodeIndex);
        }
Esempio n. 3
0
        public static void Create(EncodingDefinition encodingMethod, BinaryStreamPointerBase stream, int blockSize, byte level, uint startingNodeIndex, Func <uint> getNextNewNodeIndex, SparseIndexWriter <TKey> sparseIndex, TreeStream <TKey, TValue> treeStream)
        {
            NodeHeader <TKey> header = new NodeHeader <TKey>(level, blockSize);
            PairEncodingBase <TKey, TValue> encoding = Library.Encodings.GetEncodingMethod <TKey, TValue>(encodingMethod);

            SparseIndexWriter <TKey> sparseIndex1 = sparseIndex;
            Func <uint> getNextNewNodeIndex1      = getNextNewNodeIndex;
            int         maximumStorageSize        = encoding.MaxCompressionSize;

            byte[] buffer1 = new byte[maximumStorageSize];
            if ((header.BlockSize - header.HeaderSize) / maximumStorageSize < 4)
            {
                throw new Exception("Tree must have at least 4 records per node. Increase the block size or decrease the size of the records.");
            }

            //InsideNodeBoundary = m_BoundsFalse;
            header.NodeIndex             = startingNodeIndex;
            header.RecordCount           = 0;
            header.ValidBytes            = (ushort)header.HeaderSize;
            header.LeftSiblingNodeIndex  = uint.MaxValue;
            header.RightSiblingNodeIndex = uint.MaxValue;
            header.LowerKey.SetMin();
            header.UpperKey.SetMax();

            byte *writePointer = stream.GetWritePointer(blockSize * header.NodeIndex, blockSize);

            fixed(byte *buffer = buffer1)
            {
                TKey   key1   = new TKey();
                TKey   key2   = new TKey();
                TValue value1 = new TValue();
                TValue value2 = new TValue();

                key1.Clear();
                key2.Clear();
                value1.Clear();
                value2.Clear();

Read1:
                //Read part 1.
                if (treeStream.Read(key1, value1))
                {
                    if (header.RemainingBytes < maximumStorageSize)
                    {
                        if (header.RemainingBytes < encoding.Encode(buffer, key2, value2, key1, value1))
                        {
                            NewNodeThenInsert(header, sparseIndex1, getNextNewNodeIndex1(), writePointer, key1);
                            key2.Clear();
                            value2.Clear();
                            writePointer = stream.GetWritePointer(blockSize * header.NodeIndex, blockSize);
                        }
                    }

                    byte *stream1 = writePointer + header.ValidBytes;
                    header.ValidBytes += (ushort)encoding.Encode(stream1, key2, value2, key1, value1);
                    header.RecordCount++;

                    //Read part 2.
                    if (treeStream.Read(key2, value2))
                    {
                        if (header.RemainingBytes < maximumStorageSize)
                        {
                            if (header.RemainingBytes < encoding.Encode(buffer, key1, value1, key2, value2))
                            {
                                NewNodeThenInsert(header, sparseIndex1, getNextNewNodeIndex1(), writePointer, key2);
                                key1.Clear();
                                value1.Clear();
                                writePointer = stream.GetWritePointer(blockSize * header.NodeIndex, blockSize);
                            }
                        }
                        byte *stream2 = writePointer + header.ValidBytes;
                        header.ValidBytes += (ushort)encoding.Encode(stream2, key1, value1, key2, value2);
                        header.RecordCount++;

                        goto Read1;
                    }
                }
            }

            header.Save(writePointer);
        }