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); } }
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); } }
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; } }
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(); }
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); }