public void Mark(TKey begin, TKey end) { if (m_comparer.Compare(begin, end) >= 0) { throw new InvalidOperationException("End key must be greater than the Begin key."); } var entry = new Entry(begin, end); Entry cursor; switch (m_items.Count) { case 0: { // the list empty // no checks required m_items.Insert(entry); m_bounds.ReplaceWith(entry); break; } case 1: { // there is only one value cursor = m_items[0]; if (!Resolve(cursor, entry)) { // no conflict m_items.Insert(entry); m_bounds.Update( Min(entry.Begin, cursor.Begin), Max(entry.End, cursor.End) ); } else { // merged with the previous range m_bounds.ReplaceWith(cursor); } break; } default: { // check with the bounds first if (m_comparer.Compare(begin, m_bounds.End) > 0) { // completely to the right m_items.Insert(entry); m_bounds.Update(m_bounds.Begin, end); break; } if (m_comparer.Compare(end, m_bounds.Begin) < 0) { // completely to the left m_items.Insert(entry); m_bounds.Update(begin, m_bounds.End); break; } if (m_comparer.Compare(begin, m_bounds.Begin) <= 0 && m_comparer.Compare(end, m_bounds.End) >= 0) { // overlaps with all the ranges // note :if we are here, there was at least 2 items, so just clear everything m_items.Clear(); m_items.Insert(entry); m_bounds.ReplaceWith(entry); break; } // overlaps with existing ranges, we may need to resolve conflicts int offset, level; bool inserted = false; // once inserted, will it conflict with the previous entry ? if ((level = m_items.FindPrevious(entry, true, out offset, out cursor)) >= 0) { if (Resolve(cursor, entry)) { entry = cursor; inserted = true; } } // also check for potential conflicts with the next entries while (true) { level = m_items.FindNext(entry, false, out offset, out cursor); if (level < 0) { break; } if (inserted) { // we already have inserted the key so conflicts will remove the next segment if (Resolve(entry, cursor)) { // next segment has been removed //Console.WriteLine(" > folded with previous: " + entry); m_items.RemoveAt(level, offset); } else { break; } } else { // we havent inserted the key yet, so in case of conflict, we will use the next segment's slot if (Resolve(cursor, entry)) { //Console.WriteLine(" > merged in place: " + cursor); inserted = true; } else { break; } } } if (!inserted) { // no conflict, we have to insert the new range m_items.Insert(entry); } m_bounds.Update( Min(m_bounds.Begin, entry.Begin), Max(m_bounds.End, entry.End) ); break; } } //TODO: check constraints ! }
public int FindNext(T value, bool orEqual, IComparer <T> comparer, out int offset, out T result) { return(ColaStore.FindNext <T>(m_levels, m_count, value, orEqual, comparer ?? m_comparer, out offset, out result)); }