コード例 #1
0
        /// <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();
            }
        }