/// <summary> /// Seeks the streams only in the forward direction. /// This means that if the current position in any stream is invalid or past this point, /// the stream will not seek backwards. /// </summary> /// <param name="key">the key to seek to</param> private void SeekAllArchiveStreamsForward(TKey key) { foreach (BufferedArchiveStream <TKey, TValue> table in m_sortedArchiveStreams.Items) { if (table.CacheIsValid && table.CacheKey.IsLessThan(key)) { table.SeekToKeyAndUpdateCacheValue(key); } } //Resorts the entire list. m_sortedArchiveStreams.Sort(); //Remove any duplicates RemoveDuplicatesIfExists(); if (m_sortedArchiveStreams.Items.Length > 0) { m_firstTable = m_sortedArchiveStreams[0]; m_firstTableScanner = m_firstTable.Scanner; } else { m_firstTable = null; m_firstTableScanner = null; } SetReadWhileUpperBoundsValue(); }
/// <summary> /// Does a seek operation on the current stream when there is a seek filter on the reader. /// </summary> /// <returns> /// True if the provided key is still valid within the next best fitting frame. /// </returns> private bool AdvanceSeekableFilter(bool isValid, TKey key) { TryAgain: if (m_keySeekFilter != null && m_keySeekFilter.NextWindow()) { //If the current point is a valid point. //Check to see if the seek operation can be avoided. //or if the next available point does not exist in this window. if (isValid) { //If the current point is within this window if (key.IsGreaterThanOrEqualTo(m_keySeekFilter.StartOfFrame) && key.IsLessThanOrEqualTo(m_keySeekFilter.EndOfFrame)) { return(true); } //If the current point is after this window, seek to the next window. if (key.IsGreaterThan(m_keySeekFilter.EndOfFrame)) { goto TryAgain; } } //If the current point is not valid, or is before m_startKey //Advance the scanner to the next window. SeekAllArchiveStreamsForward(m_keySeekFilter.StartOfFrame); return(false); } Dispose(); m_firstTableScanner = null; m_firstTable = null; return(false); }
/// <summary> /// Compares two Archive Streams together for proper sorting. /// </summary> /// <param name="item1"></param> /// <param name="item2"></param> /// <returns></returns> int CompareStreams(BufferedArchiveStream <TKey, TValue> item1, BufferedArchiveStream <TKey, TValue> item2) { if (!item1.CacheIsValid && !item2.CacheIsValid) { return(0); } if (!item1.CacheIsValid) { return(1); } if (!item2.CacheIsValid) { return(-1); } return(item1.CacheKey.CompareTo(item2.CacheKey));// item1.CurrentKey.CompareTo(item2.CurrentKey); }
bool IsLessThan(BufferedArchiveStream <TKey, TValue> item1, BufferedArchiveStream <TKey, TValue> item2) { if (!item1.CacheIsValid && !item2.CacheIsValid) { return(false); } if (!item1.CacheIsValid) { return(false); } if (!item2.CacheIsValid) { return(true); } return(item1.CacheKey.IsLessThan(item2.CacheKey));// item1.CurrentKey.CompareTo(item2.CurrentKey); }
//------------------------------------------------------------- /// <summary> /// Will verify that the stream is in the proper order and remove any duplicates that were found. /// May be called after every single read, but better to be called /// when a ReadWhile function returns false. /// </summary> void VerifyArchiveStreamSortingOrder() { if (EOS) { return; } m_sortedArchiveStreams[0].UpdateCachedValue(); if (m_sortedArchiveStreams.Items.Length > 1) { //If list is no longer in order int compare = CompareStreams(m_sortedArchiveStreams[0], m_sortedArchiveStreams[1]); if (compare == 0 && m_sortedArchiveStreams[0].CacheIsValid) { //If a duplicate entry is found, advance the position of the duplicate entry RemoveDuplicatesFromList(); SetReadWhileUpperBoundsValue(); } if (compare > 0) { m_sortedArchiveStreams.SortAssumingIncreased(0); m_firstTable = m_sortedArchiveStreams[0]; m_firstTableScanner = m_firstTable.Scanner; SetReadWhileUpperBoundsValue(); } if (compare == 0 && !m_sortedArchiveStreams[0].CacheIsValid) { Dispose(); m_firstTable = null; m_firstTableScanner = null; } } else { if (!m_sortedArchiveStreams[0].CacheIsValid) { Dispose(); m_firstTable = null; m_firstTableScanner = null; } } }
/// <summary> /// Does an unconditional seek operation to the provided key. /// </summary> /// <param name="key"></param> void SeekToKey(TKey key) { foreach (var table in m_sortedArchiveStreams.Items) { table.SeekToKeyAndUpdateCacheValue(key); } m_sortedArchiveStreams.Sort(); //Remove any duplicates RemoveDuplicatesIfExists(); if (m_sortedArchiveStreams.Items.Length > 0) { m_firstTable = m_sortedArchiveStreams[0]; m_firstTableScanner = m_firstTable.Scanner; } else { m_firstTable = null; m_firstTableScanner = null; } SetReadWhileUpperBoundsValue(); }