public void Add() { var person = new Person("Adult1", 50); _updater.AddOrUpdate(person, "Adult1"); IChangeSet <Person, string> updates = _updater.AsChangeSet(); Assert.AreEqual(person, _cache.Lookup("Adult1").Value); Assert.AreEqual(1, _cache.Count); Assert.AreEqual(updates.Count, 1, "Should be 1 updates"); Assert.AreEqual(new Change <Person, string>(ChangeReason.Add, person.Name, person), updates.First(), "Should be 1 updates"); }
private IChangeSet <TObject, TKey> UpdateCombined(IChangeSet <TObject, TKey> updates) { //child caches have been updated before we reached this point. var updater = new IntermediateUpdater <TObject, TKey>(_combinedCache); foreach (var update in updates) { TKey key = update.Key; switch (update.Reason) { case ChangeReason.Add: case ChangeReason.Update: { // get the current key. //check whether the item should belong to the cache Optional <TObject> cached = updater.Lookup(key); bool contained = cached.HasValue; bool match = MatchesConstraint(key); if (match) { if (contained) { if (!ReferenceEquals(update.Current, cached.Value)) { updater.AddOrUpdate(update.Current, key); } } else { updater.AddOrUpdate(update.Current, key); } } else { if (contained) { updater.Remove(key); } } } break; case ChangeReason.Remove: { var cached = updater.Lookup(key); var contained = cached.HasValue; bool shouldBeIncluded = MatchesConstraint(key); if (shouldBeIncluded) { var firstOne = _sourceCaches.Select(s => s.Lookup(key)) .SelectValues() .First(); if (!cached.HasValue) { updater.AddOrUpdate(firstOne, key); } else if (!ReferenceEquals(firstOne, cached.Value)) { updater.AddOrUpdate(firstOne, key); } } else { if (contained) { updater.Remove(key); } } } break; case ChangeReason.Evaluate: { updater.Evaluate(key); } break; } } return(updater.AsChangeSet()); // } // return up }
/// <summary> /// Sorts using the specified sorter. Will return null if there are no changes /// </summary> /// <param name="sortReason">The sort reason.</param> /// <param name="changes">The changes.</param> /// <returns></returns> private ISortedChangeSet <TObject, TKey> DoSort(SortReason sortReason, IChangeSet <TObject, TKey> changes = null) { if (changes != null) { _updater.Update(changes); changes = _updater.AsChangeSet(); _haveReceivedData = true; if (_comparer == null) { return(null); } } //if the comparer is not set, return nothing if (_comparer == null || !_haveReceivedData) { return(null); } if (!_initialised) { sortReason = SortReason.InitialLoad; _initialised = true; } else if (changes != null && (_resetThreshold > 0 && changes.Count >= _resetThreshold)) { sortReason = SortReason.Reset; } //TODO: Create a sorted cache (could create an sorted observable list perhaps?) IChangeSet <TObject, TKey> changeSet; switch (sortReason) { case SortReason.InitialLoad: { //For the first batch, changes may have arrived before the comparer was set. //therefore infer the first batch of changes from the cache _calculator = new IndexCalculator <TObject, TKey>(_comparer, _optimisations); changeSet = _calculator.Load(_cache); } break; case SortReason.Reset: { _calculator.Reset(_cache); changeSet = changes; } break; case SortReason.DataChanged: { changeSet = _calculator.Calculate(changes); } break; case SortReason.ComparerChanged: { sortReason = SortReason.ComparerChanged; changeSet = _calculator.ChangeComparer(_comparer); } break; case SortReason.Reorder: { changeSet = _calculator.Reorder(); } break; default: throw new ArgumentOutOfRangeException(nameof(sortReason)); } Debug.Assert(changeSet != null, "changeSet != null"); if ((sortReason == SortReason.InitialLoad || sortReason == SortReason.DataChanged) && changeSet.Count == 0) { return(null); } if (sortReason == SortReason.Reorder && changeSet.Count == 0) { return(null); } _sorted = new KeyValueCollection <TObject, TKey>(_calculator.List, _comparer, sortReason, _optimisations); return(new SortedChangeSet <TObject, TKey>(_sorted, changeSet)); }