private ProgressiveCollection(Progressor <T> progressor, ICollection <T> cache, IEqualityComparer <T>?comparer) { Cache = cache ?? throw new ArgumentNullException(nameof(cache)); Progressor = progressor ?? throw new ArgumentNullException(nameof(progressor)); _subscription = Progressor.SubscribeAction(obj => Cache.Add(obj)); Comparer = comparer ?? EqualityComparer <T> .Default; }
protected ProgressiveCollection(Progressor <T> progressor, ICollection <T> cache, IEqualityComparer <T> comparer) { _cache = cache ?? throw new ArgumentNullException(nameof(cache)); Cache = _cache.WrapAsIReadOnlyCollection(); Progressor = progressor ?? throw new ArgumentNullException(nameof(progressor)); _subscription = Progressor.SubscribeAction(obj => _cache.Add(obj)); Comparer = comparer ?? EqualityComparer <T> .Default; }
protected ProgressiveLookup(TryTake <IGrouping <TKey, T> > tryTake, IDictionary <TKey, IGrouping <TKey, T> > cache, IEqualityComparer <TKey> keyComparer, IEqualityComparer <T> itemComparer) { _cache = Check.NotNullArgument(cache, "cache"); _progressor = new Progressor <IGrouping <TKey, T> >(tryTake, false); // false because the underlaying structure may change _progressor.SubscribeAction(obj => _cache.Add(new KeyValuePair <TKey, IGrouping <TKey, T> >(obj.Key, obj))); _keyComparer = keyComparer ?? EqualityComparer <TKey> .Default; _itemComparer = itemComparer ?? EqualityComparer <T> .Default; _keysReadonly = new ProgressiveSet <TKey>(Progressor <TKey> .CreateConverted(Progressor, input => input.Key), keyComparer); }
protected ProgressiveLookup(Progressor <IGrouping <TKey, T> > wrapped, IDictionary <TKey, IGrouping <TKey, T> > cache, IEqualityComparer <TKey> keyComparer, IEqualityComparer <T> itemComparer) { _cache = Check.NotNullArgument(cache, "cache"); _progressor = new Progressor <IGrouping <TKey, T> >(wrapped); _progressor.SubscribeAction(obj => _cache.Add(new KeyValuePair <TKey, IGrouping <TKey, T> >(obj.Key, obj))); _keyComparer = keyComparer ?? EqualityComparer <TKey> .Default; _itemComparer = itemComparer ?? EqualityComparer <T> .Default; _keysReadonly = new ProgressiveSet <TKey>(Progressor <TKey> .CreateConverted(Progressor, input => input.Key), keyComparer); }
protected ProgressiveLookup(Progressor <IGrouping <TKey, T> > progressor, IDictionary <TKey, IGrouping <TKey, T> > cache, IEqualityComparer <TKey> keyComparer, IEqualityComparer <T> itemComparer) { _cache = cache ?? throw new ArgumentNullException(nameof(cache)); Progressor = progressor ?? throw new ArgumentNullException(nameof(progressor)); _subscription = Progressor.SubscribeAction(obj => _cache.Add(new KeyValuePair <TKey, IGrouping <TKey, T> >(obj.Key, obj))); KeyComparer = keyComparer ?? EqualityComparer <TKey> .Default; ItemComparer = itemComparer ?? EqualityComparer <T> .Default; Keys = new EnumerationList <TKey>(this.ConvertProgressive(input => input.Key)); }
protected ProgressiveCollection(TryTake <T> tryTake, ICollection <T> cache, IEqualityComparer <T> comparer) { if (cache == null) { throw new ArgumentNullException("cache"); } _cache = cache; _progressor = new Progressor <T>(tryTake, false); // false because the underlaying structure may change _progressor.SubscribeAction(obj => _cache.Add(obj)); _comparer = comparer ?? EqualityComparer <T> .Default; }
protected ProgressiveCollection(IEnumerable <T> wrapped, ICollection <T> cache, IEqualityComparer <T> comparer) { if (cache == null) { throw new ArgumentNullException("cache"); } _cache = cache; _progressor = new Progressor <T>(wrapped); _progressor.SubscribeAction(obj => _cache.Add(obj)); _comparer = comparer ?? EqualityComparer <T> .Default; }
public Progressor(Progressor <T> wrapped) { if (wrapped == null) { throw new ArgumentNullException("wrapped"); } var control = 0; Predicate <T> newFilter = item => Thread.VolatileRead(ref control) == 0; var buffer = new SafeQueue <T>(); wrapped.SubscribeAction ( item => { if (newFilter(item)) { buffer.Add(item); } } ); _proxy = new ProxyObservable <T>(); _tryTake = (out T value) => { Interlocked.Increment(ref control); try { if (buffer.TryTake(out value) || wrapped.TryTake(out value)) { _proxy.OnNext(value); return(true); } else { _done = wrapped._done; return(false); } } finally { Interlocked.Decrement(ref control); } }; }
public Progressor(IEnumerable <T> preface, Progressor <T> wrapped) { if (wrapped == null) { throw new ArgumentNullException("wrapped"); } if (preface == null) { throw new ArgumentNullException("preface"); } var enumerator = preface.GetEnumerator(); if (enumerator == null) { throw new ArgumentException("preface.GetEnumerator()"); } var control = 0; var guard = 0; Predicate <T> newFilter = item => Thread.VolatileRead(ref control) == 0; var buffer = new SafeQueue <T>(); wrapped.SubscribeAction ( item => { if (newFilter(item)) { buffer.Add(item); } } ); _proxy = new ProxyObservable <T>(); TryTake <T> tryTakeReplacement = (out T value) => { Interlocked.Increment(ref control); try { if (buffer.TryTake(out value) || wrapped.TryTake(out value)) { _proxy.OnNext(value); return(true); } else { _done = wrapped._done; return(false); } } finally { Interlocked.Decrement(ref control); } }; _tryTake = (out T value) => { value = default(T); if (Thread.VolatileRead(ref guard) == 0) { bool result; // We need a lock, there is no way around it. IEnumerator is just awful. Use another overload if possible. lock (enumerator) { result = enumerator.MoveNext(); if (result) { value = enumerator.Current; } } if (result) { _proxy.OnNext(value); return(true); } enumerator.Dispose(); Interlocked.CompareExchange(ref guard, 1, 0); } if (Interlocked.CompareExchange(ref guard, 2, 1) == 1) { _tryTake = tryTakeReplacement; Thread.VolatileWrite(ref guard, 3); } else { ThreadingHelper.SpinWaitUntil(ref guard, 3); } var tryTake = _tryTake; return(tryTake(out value)); }; }
public Progressor(T[] preface, Progressor <T> wrapped) { if (wrapped == null) { throw new ArgumentNullException("wrapped"); } if (preface == null) { throw new ArgumentNullException("preface"); } var control = 0; var guard = 0; var index = -1; Predicate <T> newFilter = item => Thread.VolatileRead(ref control) == 0; var buffer = new SafeQueue <T>(); wrapped.SubscribeAction ( item => { if (newFilter(item)) { buffer.Add(item); } } ); _proxy = new ProxyObservable <T>(); TryTake <T> tryTakeReplacement = (out T value) => { Interlocked.Increment(ref control); try { if (buffer.TryTake(out value) || wrapped.TryTake(out value)) { _proxy.OnNext(value); return(true); } else { _done = wrapped._done; return(false); } } finally { Interlocked.Decrement(ref control); } }; _tryTake = (out T value) => { if (Thread.VolatileRead(ref guard) == 0) { var currentIndex = Interlocked.Increment(ref index); if (currentIndex < preface.Length) { value = preface[currentIndex]; _proxy.OnNext(value); return(true); } Interlocked.CompareExchange(ref guard, 1, 0); } if (Interlocked.CompareExchange(ref guard, 2, 1) == 1) { _tryTake = tryTakeReplacement; Thread.VolatileWrite(ref guard, 3); } else { ThreadingHelper.SpinWaitUntil(ref guard, 3); } var tryTake = _tryTake; return(tryTake(out value)); }; }