示例#1
0
 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;
 }
示例#3
0
 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);
 }
示例#4
0
 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);
 }
示例#5
0
 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));
 }
示例#6
0
 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;
 }
示例#7
0
 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;
 }
示例#8
0
        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);
                }
            };
        }
示例#9
0
        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));
            };
        }
示例#10
0
        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));
            };
        }