public void Add() { var person = new Person("Adult1", 50); _updater.AddOrUpdate(person); IChangeSet <Person, string> updates = _updater.AsChangeSet(); _cache.Lookup("Adult1").Value.Should().Be(person); _cache.Count.Should().Be(1); 1.Should().Be(updates.Count, "Should be 1 updates"); updates.First().Should().Be(new Change <Person, string>(ChangeReason.Add, person.Name, person), "Should be 1 updates"); }
public void Add() { var person = new Person("Adult1", 50); _updater.AddOrUpdate(person); 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"); }
public static IChangeSet <TObject, TKey> RefreshFilteredFrom <TObject, TKey>( this ChangeAwareCache <TObject, TKey> filtered, Cache <TObject, TKey> allData, Func <TObject, bool> predicate) { foreach (var kvp in allData.KeyValues) { var exisiting = filtered.Lookup(kvp.Key); var matches = predicate(kvp.Value); if (matches) { if (!exisiting.HasValue) { filtered.AddOrUpdate(kvp.Value, kvp.Key); } } else { if (exisiting.HasValue) { filtered.Remove(kvp.Key); } } } return(filtered.CaptureChanges()); }
public Optional <TObject> Lookup(TKey key) { Optional <TObject> result; lock (_locker) result = _cache.Lookup(key); return(result); }
/// <summary> /// Returns an observable of any changes which match the specified key. The sequence starts with the inital item in the cache (if there is one). /// </summary> /// <param name="key">The key.</param> /// <returns></returns> public IObservable <Change <TObject, TKey> > Watch(TKey key) { return(Observable.Create <Change <TObject, TKey> > ( observer => { var initial = _innerCache.Lookup(key); if (initial.HasValue) { observer.OnNext(new Change <TObject, TKey>(ChangeReason.Add, key, initial.Value)); } return _changes.Subscribe(changes => { var matches = changes.Where(update => update.Key.Equals(key)); foreach (var match in matches) { observer.OnNext(match); } }); })); }
public static IObservable <IChangeSet <TCache, TKey> > TransformAndCache <TObject, TKey, TCache>( this IObservable <IChangeSet <TObject, TKey> > obs, Func <TKey, TObject, TCache> onAdded, Action <Change <TObject, TKey>, TCache> onUpdated) { var cache = new ChangeAwareCache <TCache, TKey>(); return(obs .Select(changeSet => { foreach (var change in changeSet) { switch (change.Reason) { case ChangeReason.Add: case ChangeReason.Update: case ChangeReason.Refresh: var lookup = cache.Lookup(change.Key); TCache val; if (lookup.HasValue) { val = lookup.Value; } else { val = onAdded(change.Key, change.Current); cache.Add(val, change.Key); } onUpdated(change, val); break; case ChangeReason.Remove: cache.Remove(change.Key); break; case ChangeReason.Moved: break; default: throw new NotImplementedException(); } } return cache.CaptureChanges(); }) .Where(cs => cs.Count > 0)); }
private void ProcessItem(ChangeAwareCache <TObject, TKey> target, MergeContainer[] sourceLists, TObject item, TKey key) { var cached = target.Lookup(key); var shouldBeInResult = MatchesConstraint(sourceLists, key); if (shouldBeInResult) { if (!cached.HasValue) { target.AddOrUpdate(item, key); } else if (!ReferenceEquals(item, cached.Value)) { target.AddOrUpdate(item, key); } } else { if (cached.HasValue) { target.Remove(key); } } }
public Optional <TObject> Lookup(TKey key) { var item = _cache.Lookup(key); return(item.HasValue ? item.Value : Optional.None <TObject>()); }
private IChangeSet <TObject, TKey> UpdateCombined(IChangeSet <TObject, TKey> updates) { //child caches have been updated before we reached this point. foreach (var update in updates) { var 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 var cached = _combinedCache.Lookup(key); var contained = cached.HasValue; var match = MatchesConstraint(key); if (match) { if (contained) { if (!ReferenceEquals(update.Current, cached.Value)) { _combinedCache.AddOrUpdate(update.Current, key); } } else { _combinedCache.AddOrUpdate(update.Current, key); } } else { if (contained) { _combinedCache.Remove(key); } } } break; case ChangeReason.Remove: { var cached = _combinedCache.Lookup(key); var contained = cached.HasValue; var shouldBeIncluded = MatchesConstraint(key); if (shouldBeIncluded) { var firstOne = _sourceCaches.Select(s => s.Lookup(key)) .SelectValues() .First(); if (!cached.HasValue) { _combinedCache.AddOrUpdate(firstOne, key); } else if (!ReferenceEquals(firstOne, cached.Value)) { _combinedCache.AddOrUpdate(firstOne, key); } } else { if (contained) { _combinedCache.Remove(key); } } } break; case ChangeReason.Refresh: { _combinedCache.Refresh(key); } break; } } return(_combinedCache.CaptureChanges()); }
public static void FilterChanges <TObject, TKey>(this ChangeAwareCache <TObject, TKey> cache, IChangeSet <TObject, TKey> changes, Func <TObject, bool> predicate) { foreach (var change in changes) { var key = change.Key; switch (change.Reason) { case ChangeReason.Add: { if (predicate(change.Current)) { cache.AddOrUpdate(change.Current, key); } } break; case ChangeReason.Update: { if (predicate(change.Current)) { cache.AddOrUpdate(change.Current, key); } else { cache.Remove(key); } } break; case ChangeReason.Remove: cache.Remove(key); break; case ChangeReason.Refresh: { var exisiting = cache.Lookup(key); if (predicate(change.Current)) { if (!exisiting.HasValue) { cache.AddOrUpdate(change.Current, key); } else { cache.Refresh(key); } } else { if (exisiting.HasValue) { cache.Remove(key); } } } break; } } }