Beispiel #1
0
        public void TestAddRange()
        {
            var list = _newList();

            list.AddRange(Iterable.Range(1, 3));
            list.AddRange(Enumerable.Range(5, 3));
            ExpectList(list, 1, 2, 3, 5, 6, 7);
            list.AddRange(Iterable.Range(10, 2));
            list.AddRange(Enumerable.Range(20, 2));
            ExpectList(list, 1, 2, 3, 5, 6, 7, 10, 11, 20, 21);
            list.AddRange(Iterable.Single(30));
            list.AddRange(Enumerable.Range(40, 1));
            ExpectList(list, 1, 2, 3, 5, 6, 7, 10, 11, 20, 21, 30, 40);
            list.AddRange(Iterable.Repeat(0, 0));
            list.AddRange(Enumerable.Repeat(0, 0));
            ExpectList(list, 1, 2, 3, 5, 6, 7, 10, 11, 20, 21, 30, 40);

            list.AddRange(Iterable.Single(-99));
            if (Enumerable.First(list) == -99)
            {
                // It's a sorted list.
                list.AddRange(Iterable.Single(4));
                ExpectList(list, -99, 1, 2, 3, 4, 5, 6, 7, 10, 11, 20, 21, 30, 40);
                list.AddRange(Enumerable.Range(-2, 3));
                ExpectList(list, -99, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 20, 21, 30, 40);
                list.AddRange(Enumerable.Range(12, 8));
                ExpectList(list, -99, -2, -1, 0, 1, 2, 3, 4, 5, 6, 7, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 30, 40);
            }
            else
            {
                ExpectList(list, 1, 2, 3, 5, 6, 7, 10, 11, 20, 21, 30, 40, -99);
            }
        }
Beispiel #2
0
        public void TestSort()
        {
            for (int size = 0; size <= 2000; size = size * 2 + _r.Next(4))
            {
                ListT      list      = _newList();
                List <int> list2     = new List <int>(size);
                int        threshold = _r.Next(255);
                for (int i = 0; i < size; i++)
                {
                    int n = _r.Next(size + 1);
                    if (_r.Next(256) < threshold)
                    {
                        // Front-inserts are needed to test DList<T>.Sort() thoroughly
                        list.InsertRange(0, Iterable.Single(n));
                        list2.Insert(0, n);
                    }
                    else
                    {
                        list.AddRange(Iterable.Single(n));
                        list2.Add(n);
                    }
                }

                list.Sort();
                list2.Sort();
                ExpectList(list, list2);
            }
        }
Beispiel #3
0
        public void Insert(int index, T item)
        {
            if ((uint)index > (uint)_count)
            {
                throw new IndexOutOfRangeException();
            }
            AutoThrow();
            if (_listChanging != null)
            {
                CallListChanging(new ListChangeInfo <T>(NotifyCollectionChangedAction.Add, index, 1, Iterable.Single(item)));
            }

            try {
                _freezeMode = FrozenForConcurrency;
                if (_root == null || _root.IsFrozen)
                {
                    AutoCreateOrCloneRoot();
                }

                AListNode <T, T> splitLeft, splitRight;
                splitLeft = _root.Insert((uint)index, item, out splitRight, _observer);
                if (splitLeft != null)                 // redundant 'if' optimization
                {
                    AutoSplit(splitLeft, splitRight);
                }

                ++_version;
                checked { ++_count; }
                CheckPoint();
            } finally {
                _freezeMode = NotFrozen;
            }
        }
Beispiel #4
0
 private void SetHelper(uint index, T value)
 {
     if (_listChanging != null)
     {
         CallListChanging(new ListChangeInfo <T>(NotifyCollectionChangedAction.Replace, (int)index, 0, Iterable.Single(value)));
     }
     ++_version;
     if (_root.IsFrozen)
     {
         AutoCreateOrCloneRoot();
     }
     _root.SetAt(index, value, _observer);
     CheckPoint();
 }
Beispiel #5
0
        public override int DoSingleOperation(ref AListSingleOperation <K, T> op, out AListNode <K, T> splitLeft, out AListNode <K, T> splitRight)
        {
            T   searchItem = op.Item;
            int index      = _list.BinarySearch(op.Key, op.CompareToKey, op.LowerBound);

            if (op.Found = (index >= 0))
            {
                op.Item = _list[index];                 // save old value
                if (op.RequireExactMatch && (searchItem == null ? op.Item == null : !searchItem.Equals(op.Item)))
                {
                    op.Found = false;
                }
            }
            else
            {
                index = ~index;
            }

            splitLeft     = splitRight = null;
            op.BaseIndex += (uint)index;

            if (op.Mode == AListOperation.Retrieve)
            {
                return(0);
            }

            if (op.Mode >= AListOperation.Add)
            {
                // Possible operations: Add, AddOrReplace, AddIfNotPresent, AddOrThrow
                if (_list.Count >= _maxNodeSize && (op.Mode == AListOperation.Add || !op.Found))
                {
                    op.BaseIndex -= (uint)index;
                    op.Item       = searchItem;
                    return(SplitAndAdd(ref op, out splitLeft, out splitRight));
                }

                if (op.Found && op.Mode != AListOperation.Add)
                {
                    if (op.Mode == AListOperation.AddOrThrow)
                    {
                        throw new KeyAlreadyExistsException();
                    }
                    else if (op.Mode == AListOperation.AddIfNotPresent)
                    {
                        return(0);
                    }
                }
                else                 // add new item
                {
                    if (HasListChanging(op.List))
                    {
                        CallListChanging(op.List, new ListChangeInfo <T>(NotifyCollectionChangedAction.Add, (int)op.BaseIndex, 1, Iterable.Single(searchItem)));
                    }

                    if (index == _list.Count)
                    {                           // Highest key may change
                        splitLeft            = this;
                        op.AggregateChanged |= 1;
                        op.AggregateKey      = GetKey(op.List, searchItem);
                    }

                    _list.AutoRaiseCapacity(1, _maxNodeSize);
                    _list.Insert(index, searchItem);

                    if (GetObserver(op.List) != null)
                    {
                        if ((op.AggregateChanged & 2) == 0)
                        {
                            GetObserver(op.List).ItemAdded(searchItem, this);
                        }
                    }
                    return(1);
                }
                Debug.Assert(op.Mode == AListOperation.AddOrReplace);
            }
            else if (op.Found)
            {
                // Possible operations: ReplaceIfPresent, Remove
                if (op.Mode == AListOperation.Remove)
                {
                    if (HasListChanging(op.List))
                    {
                        CallListChanging(op.List, new ListChangeInfo <T>(NotifyCollectionChangedAction.Remove, (int)op.BaseIndex, -1, null));
                    }

                    _list.RemoveAt(index);

                    if (index == _list.Count)
                    {                           // Highest key may change
                        splitLeft = this;
                        if (_list.Count != 0)
                        {
                            op.AggregateChanged |= 1;
                            op.AggregateKey      = GetKey(op.List, _list.Last);
                        }
                    }
                    else if (IsUndersized)
                    {
                        splitLeft = this;
                    }

                    if (GetObserver(op.List) != null)
                    {
                        Debug.Assert((op.AggregateChanged & 2) == 0);
                        GetObserver(op.List).ItemRemoved(op.Item, this);
                    }

                    return(-1);
                }
                Debug.Assert(op.Mode == AListOperation.ReplaceIfPresent);
            }
            else
            {
                Debug.Assert(op.Mode == AListOperation.Remove || op.Mode == AListOperation.ReplaceIfPresent);
                return(0);                // can't remove/replace because item was not found.
            }

            // Fallthrough action: replace existing item
            Debug.Assert(op.Found);
            if (HasListChanging(op.List))
            {
                CallListChanging(op.List, new ListChangeInfo <T>(NotifyCollectionChangedAction.Replace, (int)op.BaseIndex, 0, Iterable.Single(searchItem)));
            }

            _list[index] = searchItem;

            if (index + 1 == _list.Count)
            {                   // Highest key may change
                splitLeft            = this;
                op.AggregateChanged |= 1;
                op.AggregateKey      = GetKey(op.List, searchItem);
            }

            if (GetObserver(op.List) != null)
            {
                GetObserver(op.List).ItemRemoved(op.Item, this);
                GetObserver(op.List).ItemAdded(searchItem, this);
            }
            return(0);
        }