Example #1
0
        /// <summary>
        /// Adds all of the items in the stream to this tree. Skips any dulpicate entries.
        /// </summary>
        /// <param name="stream">the stream to add.</param>
        public void TryAddRange(TreeStream <TKey, TValue> stream)
        {
            //TKey key = new TKey();
            //TValue value = new TValue();
            //while (stream.Read(key, value))
            //{
            //    TryAdd(key, value);
            //}
            //return;

            InsertStreamHelper <TKey, TValue> helper = new InsertStreamHelper <TKey, TValue>(stream);

            LeafStorage.TryInsertSequentialStream(helper);
            while (helper.IsValid)
            {
                if (helper.IsKVP1)
                {
                    LeafStorage.TryInsert(helper.Key1, helper.Value1);
                }
                else
                {
                    LeafStorage.TryInsert(helper.Key2, helper.Value2);
                }
                helper.NextDoNotCheckSequential();
            }
            if (IsDirty && AutoFlush)
            {
                m_header.SaveHeader(Stream);
            }
        }
        public virtual void TryInsertSequentialStream(InsertStreamHelper <TKey, TValue> stream)
        {
            //First check to see if the sequentail insertion is valid.
            bool   isFull;
            TKey   key   = new TKey();
            TValue value = new TValue();

            //Exit if stream is not valid or not sequentail.
            if (!stream.IsValid || !stream.IsStillSequential)
            {
                return;
            }

            NavigateToNode(stream.Key);

            //Exit if the node holding this key is not the far right node.
            if (!IsRightSiblingIndexNull)
            {
                return;
            }

            //Verify that this next key to be inserted is greater than the last record in this node
            if (RecordCount > 0)
            {
                Read(RecordCount - 1, key, value);
                if (key.IsGreaterThanOrEqualTo(stream.Key))
                {
                    return;
                }
            }

TryAgain:

            AppendSequentialStream(stream, out isFull);

            if (!stream.IsValid || !stream.IsStillSequential || !IsRightSiblingIndexNull)
            {
                return;
            }

            if (isFull)
            {
                NewNodeThenInsert(stream.Key, stream.Value);
                stream.Next();
                goto TryAgain;
            }
        }
        protected override void AppendSequentialStream(InsertStreamHelper <TKey, TValue> stream, out bool isFull)
        {
            //isFull = false;
            //return;

            //ToDo: Figure out why this code does not work.

            if (RecordCount >= m_maxRecordsPerNode)
            {
                isFull = true;
                return;
            }

            int recordsAdded         = 0;
            int additionalValidBytes = 0;

            byte *writePointer = GetWritePointerAfterHeader();
            int   offset       = RecordCount * KeyValueSize;

TryAgain:
            if (!stream.IsValid || !stream.IsStillSequential)
            {
                isFull = false;
                IncrementRecordCounts(recordsAdded, additionalValidBytes);
                return;
            }

            if (stream.IsKVP1)
            {
                //Key1,Value1 are the current record
                if (RemainingBytes - additionalValidBytes < KeyValueSize)
                {
                    isFull = true;
                    IncrementRecordCounts(recordsAdded, additionalValidBytes);
                    return;
                }

                stream.Key1.Write(writePointer + offset);
                stream.Value1.Write(writePointer + offset + KeySize);
                additionalValidBytes += KeyValueSize;
                recordsAdded++;
                offset += KeyValueSize;

                //Inlined stream.Next()
                stream.IsValid           = stream.Stream.Read(stream.Key2, stream.Value2);
                stream.IsStillSequential = stream.Key1.IsLessThan(stream.Key2);
                stream.IsKVP1            = false;
                //End Inlined
                goto TryAgain;
            }
            else
            {
                //Key2,Value2 are the current record
                if (RemainingBytes - additionalValidBytes < KeyValueSize)
                {
                    isFull = true;
                    IncrementRecordCounts(recordsAdded, additionalValidBytes);
                    return;
                }

                stream.Key2.Write(writePointer + offset);
                stream.Value2.Write(writePointer + offset + KeySize);
                additionalValidBytes += KeyValueSize;
                recordsAdded++;
                offset += KeyValueSize;

                //Inlined stream.Next()
                stream.IsValid           = stream.Stream.Read(stream.Key1, stream.Value1);
                stream.IsStillSequential = stream.Key2.IsLessThan(stream.Key1);
                stream.IsKVP1            = true;
                //End Inlined

                goto TryAgain;
            }
        }
        /// <summary>
        /// Requests that the current stream is inserted into the tree. Sequential insertion can only occur while the stream
        /// is in order and is entirely past the end of the tree.
        /// </summary>
        /// <param name="stream">the stream data to insert</param>
        /// <param name="isFull">if returning from this function while the node is not yet full, this means the stream
        /// can no longer be inserted sequentially and we must break out to the root and insert one at a time.</param>
        protected override void AppendSequentialStream(InsertStreamHelper <TKey, TValue> stream, out bool isFull)
        {
            int   recordsAdded         = 0;
            int   additionalValidBytes = 0;
            byte *writePointer         = GetWritePointer();

            fixed(byte *buffer = m_buffer1)
            {
                SeekTo(RecordCount);

                if (RecordCount > 0)
                {
                    m_currentKey.CopyTo(stream.PrevKey);
                    m_currentValue.CopyTo(stream.PrevValue);
                }
                else
                {
                    stream.PrevKey.Clear();
                    stream.PrevValue.Clear();
                }

TryAgain:

                if (!stream.IsValid || !stream.IsStillSequential)
                {
                    isFull = false;
                    IncrementRecordCounts(recordsAdded, additionalValidBytes);
                    ClearNodeCache();
                    return;
                }

                int length;

                if (stream.IsKVP1)
                {
                    //Key1,Value1 are the current record
                    if (RemainingBytes - additionalValidBytes < m_maximumStorageSize)
                    {
                        length = EncodeRecord(buffer, stream.Key2, stream.Value2, stream.Key1, stream.Value1);
                        if (RemainingBytes - additionalValidBytes < length)
                        {
                            isFull = true;
                            IncrementRecordCounts(recordsAdded, additionalValidBytes);
                            ClearNodeCache();
                            return;
                        }
                    }

                    length = EncodeRecord(writePointer + m_nextOffset, stream.Key2, stream.Value2, stream.Key1, stream.Value1);
                    additionalValidBytes += length;
                    recordsAdded++;
                    m_currentOffset = m_nextOffset;
                    m_nextOffset    = m_currentOffset + length;

                    //Inlined stream.Next()
                    stream.IsValid           = stream.Stream.Read(stream.Key2, stream.Value2);
                    stream.IsStillSequential = stream.Key1.IsLessThan(stream.Key2);
                    stream.IsKVP1            = false;
                    //End Inlined
                    goto TryAgain;
                }
                else
                {
                    //Key2,Value2 are the current record
                    if (RemainingBytes - additionalValidBytes < m_maximumStorageSize)
                    {
                        length = EncodeRecord(buffer, stream.Key1, stream.Value1, stream.Key2, stream.Value2);
                        if (RemainingBytes - additionalValidBytes < length)
                        {
                            isFull = true;
                            IncrementRecordCounts(recordsAdded, additionalValidBytes);
                            ClearNodeCache();
                            return;
                        }
                    }

                    length = EncodeRecord(writePointer + m_nextOffset, stream.Key1, stream.Value1, stream.Key2, stream.Value2);
                    additionalValidBytes += length;
                    recordsAdded++;
                    m_currentOffset = m_nextOffset;
                    m_nextOffset    = m_currentOffset + length;

                    //Inlined stream.Next()
                    stream.IsValid           = stream.Stream.Read(stream.Key1, stream.Value1);
                    stream.IsStillSequential = stream.Key2.IsLessThan(stream.Key1);
                    stream.IsKVP1            = true;
                    //End Inlined

                    goto TryAgain;
                }
            }
        }