Beispiel #1
0
 protected void InsertRange(int index, AListBase <T> source, bool move)
 {
     if (source._root.IsLeaf || source._maxLeafSize != _maxLeafSize)
     {
         InsertRange(index, (IListSource <T>)source);
         if (move)
         {
             source.Clear();
         }
     }
     else
     {
         AListBase <T> rightSection = null;
         int           rightSize;
         if ((rightSize = Count - index) != 0)
         {
             rightSection = RemoveSection(index, rightSize);
         }
         Combine(source, move, true);
         if (rightSection != null)
         {
             Combine(rightSection, true, true);
         }
     }
 }
Beispiel #2
0
 public ObserverMgr(AListBase <K, T> list, AListNode <K, T> root, IAListTreeObserver <K, T> existingObserver)
 {
     _list = list;
     _root = root;
     if (existingObserver != null)
     {
         _observers.Add(existingObserver);
     }
 }
Beispiel #3
0
 void IAListTreeObserver <K, T> .RootChanged(AListBase <K, T> list, AListNode <K, T> newRoot, bool clear)
 {
     _roots[list] = newRoot;
     if (clear)
     {
         _hasCachedSummary = false;
         _cachedSummary    = default(TSummary);
         _summaries.Clear();
     }
 }
Beispiel #4
0
 void IAListTreeObserver <K, T> .Detach(AListBase <K, T> list, AListNode <K, T> root)
 {
     if (_roots.TryGetValue(list, null) is AListInnerBase <K, T> )
     {
         // Avoid a memory leak
         _parents.Clear();
         _summaries.Clear();
     }
     _roots.Remove(list);
 }
Beispiel #5
0
 public void RootChanged(AListBase <K, T> list, AListNode <K, T> newRoot, bool clear)
 {
     Debug.Assert(_list == list);
     _root = newRoot;
     try {
         for (int i = 0; i < _observers.Count; i++)
         {
             _observers[i].RootChanged(list, newRoot, clear);
         }
     } catch (Exception e) { IllegalException(e); }
 }
Beispiel #6
0
 public AListBase(AListBase <T> items, bool keepListChangingHandlers) : base(items, keepListChangingHandlers)
 {
 }
Beispiel #7
0
 public static AListStatisticTracker <T> StatisticTracker <T>(this AListBase <int, T> list, Func <T, double> selector)
 => new AListStatisticTracker <T>(selector, list);
Beispiel #8
0
 public static AListStatisticTracker <K, T, TStatistic> StatisticTracker <K, T, TStatistic>(this AListBase <K, T> list,
                                                                                            Func <T, TStatistic> selector, Func <TStatistic, TStatistic, TStatistic> aggregator, TStatistic emptyResult)
 => new AListStatisticTracker <K, T, TStatistic>(selector, aggregator, emptyResult, list);
Beispiel #9
0
 public static AListSumTracker <K, T> SumTracker <K, T>(this AListBase <K, T> list, Func <T, double> selector) => new AListSumTracker <K, T>(selector, list);
Beispiel #10
0
 bool?IAListTreeObserver <K, T> .Attach(AListBase <K, T> list) => null;
Beispiel #11
0
 protected override void Clone(out AListBase <T> clone)
 {
     clone = Clone();
 }
Beispiel #12
0
 public void Detach(AListBase <K, T> list, AListNode <K, T> root)
 {
     throw new NotImplementedException();                 // should not be called
 }
Beispiel #13
0
 public bool?Attach(AListBase <K, T> list)
 {
     throw new InvalidOperationException();                 // should not be called
 }
Beispiel #14
0
 public AListStatisticTracker(Func <T, TSummary> selector, Func <TSummary, TSummary, TSummary> aggregator, TSummary emptyResult, AListBase <K, T> list = null)
 {
     _selector    = selector;
     _emptyResult = emptyResult;
     _aggregator  = array => {
         if (array.Length == 0)
         {
             return(_emptyResult);
         }
         var total = array[0];
         for (int i = 1; i < array.Length; i++)
         {
             total = aggregator(total, array[i]);
         }
         return(total);
     };
     list?.AddObserver(this);
 }
Beispiel #15
0
 public AListStatisticTracker(Func <T, TSummary> selector, Func <TSummary[], TSummary> aggregator, TSummary emptyResult, AListBase <K, T> list = null)
 {
     _selector    = selector;
     _aggregator  = aggregator;
     _emptyResult = emptyResult;
     list?.AddObserver(this);
 }
Beispiel #16
0
 protected abstract void Clone(out AListBase <T> clone);
Beispiel #17
0
        protected virtual void Combine(AListBase <T> other, bool move, bool append)
        {
            int heightDifference = _treeHeight - other._treeHeight;
            int insertAt         = append ? Count : 0;

            if (!(other._root is AListInner <T>))
            {
                goto insertRange;
            }
            else if (heightDifference < 0)
            {
                // The other tree is taller (bigger). We can only append/prepend a smaller
                // tree; therefore, swap the trees and then append/prepend the smaller one.
                // With the tree contents swapped, the notifications to ListChanging
                // must be fudged. If we have a tree _observer, the situation is too
                // complex and unusual to handle, so we fall back on InsertRange().
                if (_observer != null || (other._observer != null && move))
                {
                    goto insertRange;
                }

                AListBase <T> other2 = other;
                if (!move)
                {
                    other.Clone(out other2);
                }

                // Fire ListChanging on both lists, and block further notifications
                var       temp  = _listChanging;
                var       tempO = other._listChanging;
                Exception e     = null;
                if (temp != null)
                {
                    CallListChanging(new ListChangeInfo <T>(NotifyCollectionChangedAction.Add, insertAt, other.Count, other));
                }
                if (tempO != null)
                {
                    try {
                        other.CallListChanging(new ListChangeInfo <T>(NotifyCollectionChangedAction.Remove, 0, -other.Count, null));
                    } catch (Exception e_) {
                        // Ugh. We already notified the first list about the insert,
                        // so it is too late to abort. Finish the operation and
                        // throw the exception afterward.
                        e = e_;
                    }
                }

                try {
                    _listChanging       = null;
                    other._listChanging = null;
                    other2.Combine(this, move, !append);
                } finally {
                    _listChanging       = temp;
                    other._listChanging = tempO;
                }
                base.SwapHelper(other2, false);

                if (e != null)
                {
                    throw e;
                }
            }
            else
            {                   // other tree is the same height or less tall
                BeginInsertRange(insertAt, other, other.Count);
                int amtInserted = 0;
                try {
                    AListNode <int, T> splitLeft, splitRight;
                    splitLeft   = ((AListInner <T>)_root).Combine((AListInner <T>)other._root, heightDifference, out splitRight, _observer, move, append);
                    amtInserted = other.Count;
                    if (move)
                    {
                        other.ClearInternal(true);
                    }
                    AutoSplit(splitLeft, splitRight);
                }
                finally
                {
                    DoneInsertRange(amtInserted);
                }
            }
            return;

insertRange:
            InsertRange(insertAt, (IListSource <T>)other);
            if (move)
            {
                other.ClearInternal(true);
            }
        }
Beispiel #18
0
 public static AListSumTracker <K, double> SumTracker <K>(this AListBase <K, double> list) => SumTracker(list, n => n);
Beispiel #19
0
 protected SparseAList(AListBase <int, T> original, AListNode <int, T> section) : base(original, section)
 {
 }
Beispiel #20
0
 public void Attach(AListBase <K, T> list, Action <bool> populate)
 {
     throw new InvalidOperationException();                 // should not be called
 }