Exemple #1
0
 protected ProgressiveDictionary(Progressor <KeyValuePair <TKey, TValue> > wrapped, IDictionary <TKey, TValue> cache, IEqualityComparer <TKey> keyComparer, IEqualityComparer <TValue> valueComparer)
     : base
         ((out KeyValuePair <TKey, TValue> pair) =>
 {
     again:
     if (wrapped.TryTake(out pair))
     {
         if (cache.ContainsKey(pair.Key))
         {
             goto again;
         }
         return(true);
     }
     else
     {
         return(false);
     }
 }, cache, new KeyValuePairEqualityComparer <TKey, TValue>(keyComparer, valueComparer))
 {
     _cache          = Check.NotNullArgument(cache, "cache");
     _keyComparer    = keyComparer ?? EqualityComparer <TKey> .Default;
     _keyComparer    = EqualityComparer <TKey> .Default;
     _valuesReadonly = new ProgressiveSet <TValue>(Progressor <TValue> .CreateConverted(Progressor, input => input.Value), valueComparer);
     _keysReadonly   = new ProgressiveSet <TKey>(Progressor <TKey> .CreateConverted(Progressor, input => input.Key), keyComparer);
 }
Exemple #2
0
 protected ProgressiveSet(Progressor <T> wrapped, ISet <T> cache, IEqualityComparer <T> comparer)
     : base
     (
         (out T value) =>
 {
     again:
     if (wrapped.TryTake(out value))
     {
         if (cache.Contains(value))
         {
             goto again;
         }
         return(true);
     }
     else
     {
         return(false);
     }
 },
         cache,
         comparer
     )
 {
     // Empty
 }
Exemple #3
0
 TValue IDictionary <TKey, TValue> .this[TKey key]
 {
     get
     {
         try
         {
             return(_cache[key]);
         }
         catch (KeyNotFoundException)
         {
             KeyValuePair <TKey, TValue> _item;
             while (Progressor.TryTake(out _item))
             {
                 if (_keyComparer.Equals(key, _item.Key))
                 {
                     return(_item.Value);
                 }
             }
             throw;
         }
     }
     set
     {
         throw new NotSupportedException();
     }
 }
Exemple #4
0
        public bool Contains(T item)
        {
            if (CacheContains(item))
            {
                return(true);
            }
            T found;

            while (_progressor.TryTake(out found))
            {
                if (_comparer.Equals(item, found))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #5
0
        public bool Contains(TKey key)
        {
            if (_cache.ContainsKey(key))
            {
                return(true);
            }
            IGrouping <TKey, T> item;

            while (_progressor.TryTake(out item))
            {
                if (_keyComparer.Equals(key, item.Key))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #6
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);
                }
            };
        }
        public bool ContainsKey(TKey key)
        {
            if (_cache.ContainsKey(key))
            {
                return(true);
            }
            KeyValuePair <TKey, TValue> item;

            while (Progressor.TryTake(out item))
            {
                if (_keyComparer.Equals(key, item.Key))
                {
                    return(true);
                }
            }
            return(false);
        }
Exemple #8
0
 public TValue this[TKey key]
 {
     get
     {
         try
         {
             return(_cache[key]);
         }
         catch (KeyNotFoundException)
         {
             KeyValuePair <TKey, TValue> _item;
             while (Progressor.TryTake(out _item))
             {
                 if (_keyComparer.Equals(key, _item.Key))
                 {
                     return(_item.Value);
                 }
             }
             throw;
         }
     }
 }
Exemple #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));
            };
        }
Exemple #10
0
        public static Progressor <T> CreateDistinct(Progressor <T> wrapped)
        {
            if (wrapped == null)
            {
                throw new ArgumentNullException("wrapped");
            }

            var control = 0;

            SafeDictionary <T, bool> buffer    = new SafeDictionary <T, bool>();
            Predicate <T>            newFilter = item => Thread.VolatileRead(ref control) == 0;
            var proxy = new ProxyObservable <T>();

            Progressor <T> result = new Progressor <T>(
                (out T value) =>
            {
                Interlocked.Increment(ref control);
                try
                {
                    again:
                    foreach (KeyValuePair <T, bool> item in buffer)
                    {
                        if (!item.Value)
                        {
                            value = item.Key;
                            buffer.Set(value, true);
                            proxy.OnNext(value);
                            return(true);
                        }
                    }
                    if (wrapped.TryTake(out value))
                    {
                        bool seen;
                        if (!buffer.TryGetValue(value, out seen) || !seen)
                        {
                            buffer.Set(value, true);
                            proxy.OnNext(value);
                            return(true);
                        }
                        else
                        {
                            goto again;
                        }
                    }
                    else
                    {
                        return(false);
                    }
                }
                finally
                {
                    Interlocked.Decrement(ref control);
                }
            },
                proxy
                );

            wrapped.Subscribe
            (
                new CustomObserver <T>
                (
                    () => result._done        = true,
                    exception => result._done = true,
                    item =>
            {
                if (newFilter(item))
                {
                    buffer.TryAdd(item, false);
                }
            }
                )
            );
            return(result);
        }
Exemple #11
0
        public static Progressor <T> CreatedFilteredConverted <TInput>(Progressor <TInput> wrapped, Predicate <TInput> filter, Converter <TInput, T> converter)
        {
            if (wrapped == null)
            {
                throw new ArgumentNullException("wrapped");
            }
            if (filter == null)
            {
                throw new ArgumentNullException("filter");
            }
            if (converter == null)
            {
                throw new ArgumentNullException("converter");
            }

            var control = 0;

            Predicate <TInput> newFilter = item => Thread.VolatileRead(ref control) == 0 && filter(item);
            var buffer = new SafeQueue <T>();
            var proxy  = new ProxyObservable <T>();

            var result = new Progressor <T>(
                (out T value) =>
            {
                Interlocked.Increment(ref control);
                try
                {
                    TInput item;
                    again:
                    if (buffer.TryTake(out value))
                    {
                        proxy.OnNext(value);
                        return(true);
                    }
                    else if (wrapped.TryTake(out item))
                    {
                        if (filter(item))
                        {
                            value = converter(item);
                            proxy.OnNext(value);
                            return(true);
                        }
                        else
                        {
                            goto again;
                        }
                    }
                    value = default(T);
                    return(false);
                }
                finally
                {
                    Interlocked.Decrement(ref control);
                }
            },
                proxy
                );

            wrapped.Subscribe
            (
                new CustomObserver <TInput>
                (
                    () => result._done        = true,
                    exception => result._done = true,
                    item =>
            {
                if (newFilter(item))
                {
                    buffer.Add(converter(item));
                }
            }
                )
            );
            return(result);
        }
Exemple #12
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));
            };
        }