public void AddAndRemove_ManyManyItems_AllValuesFound() { int numberOfItems = 20000; List <object> values = new List <object>(numberOfItems); List <IndexingSkipList <object> .Node> nodes = new List <IndexingSkipList <object> .Node>(numberOfItems); IndexingSkipList <object> .Node lastNode = _target.BottomLeft; for (int i = 0; i < numberOfItems; i++) { var value = new object(); values.Add(value); lastNode = _target.AddAfter(lastNode, 3, value); nodes.Add(lastNode); } for (int i = 0; i < numberOfItems; i++) { _target.Remove(nodes[i]); } var currentNode = _target.TopLeft; while (currentNode != null && currentNode != _target.BottomLeft) { Assert.AreEqual(0, currentNode.ItemsInNode); Assert.AreEqual(null, currentNode.Next); currentNode = currentNode.Below; } Assert.AreEqual(_target.BottomLeft, currentNode); }
private bool TryGetPreviousNode(int indexInSource, out IndexingSkipList <IList <TResult> > .Node previousNode) { previousNode = null; if (indexInSource > 0) { List <IndexingSkipList <IList <TResult> > .Node> nodesForSource; TSource previousItemInSource = this.Source[indexInSource - 1]; nodesForSource = _sourceToCollectionNode[previousItemInSource]; if (nodesForSource.Count > 1) { return(false); } previousNode = nodesForSource[0]; } else { previousNode = _collectionIndex.BottomLeft; } return(true); }
private void AssertLinked(IndexingSkipList <object> .Node before, IndexingSkipList <object> .Node after) { Assert.IsNotNull(before); Assert.IsNotNull(after); Assert.AreEqual(before, after.Previous); Assert.AreEqual(after, before.Next); }
private void LinkNodes(IndexingSkipList <object> .Node before, IndexingSkipList <object> .Node after) { if (before != null) { before.Next = after; } if (after != null) { after.Previous = before; } }
private void StackNodes(IndexingSkipList <object> .Node below, IndexingSkipList <object> .Node above) { if (below != null) { below.Above = above; } if (above != null) { above.Below = below; } }
private void CreateAbove(IndexingSkipList <object> .Node node, int numberAbove) { var previousNode = node; for (int i = 0; i < numberAbove; i++) { var currentNode = new IndexingSkipList <object> .Node(); StackNodes(previousNode, currentNode); previousNode = currentNode; } }
private void RecordCurrentValues(IndexingSkipList <IList <TResult> > .Node nodeBefore, IList <TSource> items) { IndexingSkipList <IList <TResult> > .Node lastCollectionNodeAdded = nodeBefore; for (int i = 0; i < items.Count; i++) { var item = items[i]; var collection = _selectorFunction(item); var newNode = RecordItem(lastCollectionNodeAdded, item, collection); lastCollectionNodeAdded = newNode; } }
public void Setup() { _coinFlipper = new MockCoinFlipper(); _values = new List <object>() { new object(), new object(), new object(), }; _target = new IndexingSkipList <object>(); }
public void AddAfter_NoPromotions_UpdatesParents() { CreateThreeLevelTree(1); IndexingSkipList <object> .Node newNode = _target.AddAfter(_target.BottomLeft, 2, _values[0]); Assert.AreEqual(_values[0], newNode.Value); Assert.AreEqual(2, newNode.ItemsInNode); Assert.AreEqual(3, _headers[1].ItemsInNode); Assert.AreEqual(7, _headers[0].ItemsInNode); AssertLinked(_target.BottomLeft, newNode); }
private void RemoveItem(IndexingSkipList <IList <TResult> > .Node node, TSource item, IList <TResult> collection) { _collectionIndex.Remove(node); int numberOfInstancesOfCollectionLeft = RemoveNodeFromLookupTable(_collectionToNode, collection, node); RemoveNodeFromLookupTable(_sourceToCollectionNode, item, node); if (collection != null && numberOfInstancesOfCollectionLeft == 0) { var handler = _weakEventHandlers[collection]; handler.Deregister(); _weakEventHandlers.Remove(collection); } }
private void CreateLeaves(int leaves, int itemsPerNode) { _leaves = new List <IndexingSkipList <object> .Node>(); for (int i = 0; i < leaves; i++) { var currentNode = new IndexingSkipList <object> .Node(itemsPerNode, new object()); _leaves.Add(currentNode); if (i > 0) { LinkNodes(_leaves[i - 1], currentNode); } } }
private void CreateHeaders(int headers) { _headers = new List <IndexingSkipList <object> .HeaderNode>(); for (int i = 0; i < headers; i++) { var currentNode = new IndexingSkipList <object> .HeaderNode(); _headers.Add(currentNode); if (i > 0) { StackNodes(currentNode, _headers[i - 1]); } } }
public void AddAfter_ItemInListWithPromotions_UpdatesParents() { CreateThreeLevelTree(1); _coinFlipper.DefaultFlip = true; IndexingSkipList <object> .Node newNode = _target.AddAfter(_leaves[1], 2, _values[0]); Assert.AreEqual(_values[0], newNode.Value); Assert.AreEqual(2, newNode.ItemsInNode); Assert.AreEqual(3, newNode.Above.ItemsInNode); Assert.AreEqual(1, _leaves[1].Above.ItemsInNode); AssertLinked(_leaves[1], newNode); AssertLinked(_leaves[1].Above, newNode.Above); AssertLinked(_headers[0], newNode.Above.Above); AssertLinked(_headers[0].Above, newNode.Above.Above.Above); }
private IndexingSkipList <IList <TResult> > .Node RecordItem(IndexingSkipList <IList <TResult> > .Node nodeBefore, TSource item, IList <TResult> collection) { int count = GetCount(collection); var newNode = _collectionIndex.AddAfter(nodeBefore, count, collection); RecordNodeForItemInLookupTables(item, collection, newNode); if (collection != null && !_weakEventHandlers.ContainsKey(collection)) { WeakEventHandler weakEventHandler = WeakNotifyCollectionChangedEventHandler.Register( (INotifyCollectionChanged)collection, this, (me, sender, args) => me.OnSubCollectionChanged(sender, args)); _weakEventHandlers.Add(collection, weakEventHandler); } return(newNode); }
public SelectManyReadOnlyContinuousCollection( IList <TSource> list, Expression <Func <TSource, IList <TResult> > > manySelector) : base(list, ExpressionPropertyAnalyzer.Analyze(manySelector)) { _sourceToCollectionNode = new Dictionary <TSource, List <IndexingSkipList <IList <TResult> > .Node> >(); _collectionToNode = new Dictionary <IList <TResult>, List <IndexingSkipList <IList <TResult> > .Node> >(); _weakEventHandlers = new Dictionary <IList <TResult>, WeakEventHandler>(); _collectionIndex = new IndexingSkipList <IList <TResult> >(); _selectorFunction = manySelector.CachedCompile(); RecordCurrentValues(_collectionIndex.TopLeft, this.Source); this.NotifyCollectionChangedMonitor.Add += OnAdd; this.NotifyCollectionChangedMonitor.Remove += OnRemove; this.NotifyCollectionChangedMonitor.Reset += OnReset; this.NotifyCollectionChangedMonitor.Move += OnMove; this.NotifyCollectionChangedMonitor.Replace += OnReplace; this.NotifyCollectionChangedMonitor.ItemChanged += OnItemChanged; }
private List <TResult> AddItems(IEnumerable <TSource> newItems, IndexingSkipList <IList <TResult> > .Node previousNode) { List <TResult> newResults = new List <TResult>(); IndexingSkipList <IList <TResult> > .Node lastCollectionNodeAdded = previousNode; foreach (var item in newItems) { var collection = _selectorFunction(item); if (collection != null) { newResults.AddRange(collection); } var newNode = RecordItem(lastCollectionNodeAdded, item, collection); lastCollectionNodeAdded = newNode; } return(newResults); }
private List <TResult> RemoveItems(IEnumerable <TSource> oldItems, IndexingSkipList <IList <TResult> > .Node previousNode, out int oldStartingIndex) { var oldResults = new List <TResult>(); var firstNodeToRemove = previousNode.Next; var currentNode = firstNodeToRemove; oldStartingIndex = _collectionIndex.GetIndex(firstNodeToRemove); foreach (var item in oldItems) { var collection = currentNode.Value; oldResults.AddRange(collection); var nextNode = currentNode.Next; RemoveItem(currentNode, item, collection); currentNode = nextNode; } return(oldResults); }
private static void AddNodeToLookupTable <TKey>(Dictionary <TKey, List <IndexingSkipList <IList <TResult> > .Node> > dictionary, TKey key, IndexingSkipList <IList <TResult> > .Node node) { var nodesForItem = dictionary.GetOrCreate(key, () => new List <IndexingSkipList <IList <TResult> > .Node>(1)); nodesForItem.Add(node); }
private static int RemoveNodeFromLookupTable <TKey>(Dictionary <TKey, List <IndexingSkipList <IList <TResult> > .Node> > dictionary, TKey key, IndexingSkipList <IList <TResult> > .Node node) { var nodesForItem = dictionary[key]; nodesForItem.Remove(node); if (nodesForItem.Count == 0) { dictionary.Remove(key); } return(nodesForItem.Count); }
private void AssertLinked(IndexingSkipList<object>.Node before, IndexingSkipList<object>.Node after) { Assert.IsNotNull(before); Assert.IsNotNull(after); Assert.AreEqual(before, after.Previous); Assert.AreEqual(after, before.Next); }
private void StackNodes(IndexingSkipList<object>.Node below, IndexingSkipList<object>.Node above) { if (below != null) { below.Above = above; } if (above != null) { above.Below = below; } }
private void LinkNodes(IndexingSkipList<object>.Node before, IndexingSkipList<object>.Node after) { if (before != null) { before.Next = after; } if (after != null) { after.Previous = before; } }
private void CreateLeaves(int leaves, int itemsPerNode) { _leaves = new List<IndexingSkipList<object>.Node>(); for (int i = 0; i < leaves; i++) { var currentNode = new IndexingSkipList<object>.Node(itemsPerNode, new object()); _leaves.Add(currentNode); if (i > 0) { LinkNodes(_leaves[i - 1], currentNode); } } }
private void RecordNodeForItemInLookupTables(TSource source, IList <TResult> collection, IndexingSkipList <IList <TResult> > .Node node) { AddNodeToLookupTable(_sourceToCollectionNode, source, node); if (collection != null) { AddNodeToLookupTable(_collectionToNode, collection, node); } }
private void CreateAbove(IndexingSkipList<object>.Node node, int numberAbove) { var previousNode = node; for (int i = 0; i < numberAbove; i++) { var currentNode = new IndexingSkipList<object>.Node(); StackNodes(previousNode, currentNode); previousNode = currentNode; } }
private void CreateHeaders(int headers) { _headers = new List<IndexingSkipList<object>.HeaderNode>(); for (int i = 0; i < headers; i++) { var currentNode = new IndexingSkipList<object>.HeaderNode(); _headers.Add(currentNode); if (i > 0) { StackNodes(currentNode, _headers[i - 1]); } } }
public void Setup() { _coinFlipper = new MockCoinFlipper(); _values = new List<object>() { new object(), new object(), new object(), }; _target = new IndexingSkipList<object>(); }