/// <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; } } }