/// <summary> /// Removes everything between begin and end then translates everything /// </summary> /// <param name="begin">begin key</param> /// <param name="end">end key</param> /// <param name="offset">offset to apply</param> /// <param name="applyOffset">func to apply offset to a key</param> public void Remove(TKey begin, TKey end, TKey offset, Func <TKey, TKey, TKey> applyOffset) { if (m_keyComparer.Compare(begin, end) >= 0) { throw new InvalidOperationException("End key must be greater than the Begin key."); } try { var entry = new Entry(begin, end, default(TValue)); var iterator = m_items.GetIterator(); var comparer = m_keyComparer; if (!iterator.Seek(entry, true)) { //on ne trouve pas l'item exacte, on prends le premier. iterator.SeekFirst(); } var cursor = iterator.Current; var c1 = comparer.Compare(begin, cursor.Begin); var c2 = comparer.Compare(end, cursor.End); List <Entry> toRemove = null; //begin < cursor.Begin if (c1 < 0) { var c3 = comparer.Compare(end, cursor.Begin); //end <= cursor.Begin // [++++++++++ // ------[ //ou // [++++++ // ------[ if (c3 <= 0) { TranslateAfter(null, offset, applyOffset); return; } //end < cursor.End // [+++++++++++[ //-----------[ if (c2 < 0) { cursor.Begin = applyOffset(end, offset); cursor.End = applyOffset(cursor.End, offset); TranslateAfter(cursor, offset, applyOffset); return; } //end == cursor.End // [+++++++++[ //---------------[ if (c2 == 0) { m_items.RemoveItem(cursor); TranslateAfter(cursor, offset, applyOffset); return; } //end > cursor.End // [+++++++++[ //-------------------... if (c2 > 0) { toRemove = new List <Entry>(); toRemove.Add(cursor); while (iterator.Next()) { cursor = iterator.Current; c2 = comparer.Compare(end, cursor.End); c3 = comparer.Compare(end, cursor.Begin); //end <= cursor.Begin // [+++++ // ----[ //ou // [+++++ // ------[ if (c3 <= 0) { //on set cursor pour que la translation soit faite correctement cursor = entry; break; } //end > cursor.Begin if (c3 > 0) { //end < cursor.End // [+++++++++++ // ----------[ if (c2 < 0) { cursor.Begin = begin; cursor.End = applyOffset(cursor.End, offset); break; } // end >= cursor.End // [+++++++++[ // ---------------[ //ou // [+++++++[ // ----------------... if (c2 >= 0) { toRemove.Add(cursor); if (c2 == 0) { break; } } } } m_items.RemoveItems(toRemove); TranslateAfter(cursor, offset, applyOffset); return; } } //begin == cursor.Begin else if (c1 == 0) { //end < cursor.End // [+++++++++[ // [-----[ if (c2 < 0) { cursor.Begin = begin; cursor.End = applyOffset(cursor.End, offset); TranslateAfter(cursor, offset, applyOffset); return; } //end == cursor.End // [++++++++[ // [--------[ else if (c2 == 0) { toRemove = new List <Entry>(); toRemove.Add(cursor); } // end > cursor.End // [+++++++[ // [-----------.... else { toRemove = new List <Entry>(); toRemove.Add(cursor); while (iterator.Next()) { cursor = iterator.Current; var c3 = comparer.Compare(end, cursor.Begin); c2 = comparer.Compare(end, cursor.End); //end < cursor.Begin // [++++++++[ //---------[ //ou // [+++++++[ //---------[ if (c3 <= 0) { break; } else { //end < cursor.End // [++++++++++++[ //-----[ if (c2 < 0) { cursor.Begin = begin; cursor.End = applyOffset(cursor.End, offset); break; } //end >= cursor.End // [+++++++++[ //---------------... //ou // [+++++++++[ //-----------[ if (c2 >= 0) { toRemove.Add(cursor); if (c2 == 0) { break; } } } } } m_items.RemoveItems(toRemove); TranslateAfter(cursor, offset, applyOffset); return; } //begin > cursor.Begin else { //end < cursor.End // [++++++++++++[ // [----[ // = [++[[++++[ if (c2 < 0) { var oldEnd = cursor.End; cursor.End = begin; TranslateAfter(cursor, offset, applyOffset); m_items.Insert(new Entry(begin, applyOffset(oldEnd, offset), cursor.Value)); return; } //end == cursor.End // [+++++++++++++[ // [-------[ if (c2 == 0) { cursor.End = begin; TranslateAfter(cursor, offset, applyOffset); return; } //end > cursor.End // [+++++++++++++[ // [------------- else { cursor.End = begin; while (iterator.Next()) { cursor = iterator.Current; var c3 = comparer.Compare(end, cursor.Begin); c2 = comparer.Compare(end, cursor.End); //end <= cursor.Begin // [++++++++++++[ // --[ //ou // [++++++++++++[ // -----[ if (c3 <= 0) { break; } else { //end < cursor.End // [+++++++++++++[ // ------------[ if (c2 < 0) { cursor.Begin = begin; cursor.End = applyOffset(cursor.End, offset); break; } //end >= cursor.End // [+++++++++++[ //--------------------... //ou // [+++++++++++[ //---------------[ else { if (toRemove == null) { toRemove = new List <Entry>(); } toRemove.Add(cursor); if (c2 == 0) { break; } } } } if (toRemove != null) { m_items.RemoveItems(toRemove); } TranslateAfter(cursor, offset, applyOffset); return; } } } finally { CheckInvariants(); } }