Ejemplo n.º 1
0
        public IObservable <IChangeSet <TObject, TKey> > Run()
        {
            return(Observable.Create <IChangeSet <TObject, TKey> >(observer =>
            {
                var locker = new object();

                var destination = new LockFreeObservableCache <TObject, TKey>();

                var populator = Observable.Switch(_sources
                                                  .Do(_ =>
                {
                    lock (locker)
                        destination.Clear();
                }))
                                .Synchronize(locker)
                                .PopulateInto(destination);

                var publisher = destination.Connect().SubscribeSafe(observer);
                return new CompositeDisposable(destination, populator, publisher);
            }));
        }
Ejemplo n.º 2
0
        public IObservable <IChangeSet <TDestination, TLeftKey> > Run()
        {
            return(Observable.Create <IChangeSet <TDestination, TLeftKey> >(observer =>
            {
                var locker = new object();

                //create local backing stores
                var leftCache = _left.Synchronize(locker).AsObservableCache(false);
                var rightCache = _right.Synchronize(locker).ChangeKey(_rightKeySelector).AsObservableCache(false);

                //joined is the final cache
                var joinedCache = new LockFreeObservableCache <TDestination, TLeftKey>();

                var rightLoader = rightCache.Connect()
                                  .Subscribe(changes =>
                {
                    joinedCache.Edit(innerCache =>
                    {
                        foreach (var change in changes.ToConcreteType())
                        {
                            switch (change.Reason)
                            {
                            case ChangeReason.Add:
                            case ChangeReason.Update:
                                //Update with right (and right if it is presents)
                                var right = change.Current;
                                var left = leftCache.Lookup(change.Key);
                                innerCache.AddOrUpdate(_resultSelector(change.Key, left, right), change.Key);
                                break;

                            case ChangeReason.Remove:
                                //remove from result because a right value is expected
                                innerCache.Remove(change.Key);
                                break;

                            case ChangeReason.Refresh:
                                //propagate upstream
                                innerCache.Refresh(change.Key);
                                break;
                            }
                        }
                    });
                });

                var leftLoader = leftCache.Connect()
                                 .Subscribe(changes =>
                {
                    joinedCache.Edit(innerCache =>
                    {
                        foreach (var change in changes.ToConcreteType())
                        {
                            TLeft left = change.Current;
                            Optional <TRight> right = rightCache.Lookup(change.Key);

                            switch (change.Reason)
                            {
                            case ChangeReason.Add:
                            case ChangeReason.Update:
                                {
                                    if (right.HasValue)
                                    {
                                        //Update with left and right value
                                        innerCache.AddOrUpdate(_resultSelector(change.Key, left, right.Value), change.Key);
                                    }
                                    else
                                    {
                                        //There is no right so remove if  already in the cache
                                        innerCache.Remove(change.Key);
                                    }
                                }
                                break;

                            case ChangeReason.Remove:
                                {
                                    if (right.HasValue)
                                    {
                                        //Update with no left value
                                        innerCache.AddOrUpdate(_resultSelector(change.Key, Optional <TLeft> .None, right.Value), change.Key);
                                    }
                                    else
                                    {
                                        //remove if it is already in the cache
                                        innerCache.Remove(change.Key);
                                    }
                                }
                                break;

                            case ChangeReason.Refresh:
                                //propagate upstream
                                innerCache.Refresh(change.Key);
                                break;
                            }
                        }
                    });
                });


                return new CompositeDisposable(
                    joinedCache.Connect().NotEmpty().SubscribeSafe(observer),
                    leftCache,
                    rightCache,
                    rightLoader,
                    joinedCache,
                    leftLoader);
            }));
        }
Ejemplo n.º 3
0
        public IObservable <IChangeSet <TDestination, TLeftKey> > Run()
        {
            return(Observable.Create <IChangeSet <TDestination, TLeftKey> >(observer =>
            {
                var locker = new object();

                //create local backing stores
                var leftCache = _left.Synchronize(locker).AsObservableCache();
                var rightCache = _right.Synchronize(locker).ChangeKey(_rightKeySelector).AsObservableCache();

                //joined is the final cache
                var joinedCache = new LockFreeObservableCache <TDestination, TLeftKey>();

                var leftLoader = leftCache.Connect()
                                 .Subscribe(changes =>
                {
                    joinedCache.Edit(innerCache =>
                    {
                        foreach (var change in changes.ToConcreteType())
                        {
                            var left = change.Current;
                            var right = rightCache.Lookup(change.Key);

                            switch (change.Reason)
                            {
                            case ChangeReason.Add:
                            case ChangeReason.Update:
                                {
                                    if (right.HasValue)
                                    {
                                        innerCache.AddOrUpdate(_resultSelector(change.Key, left, right.Value), change.Key);
                                    }
                                    else
                                    {
                                        innerCache.Remove(change.Key);
                                    }

                                    break;
                                }

                            case ChangeReason.Remove:
                                innerCache.Remove(change.Key);
                                break;

                            case ChangeReason.Refresh:
                                //propagate upstream
                                innerCache.Refresh(change.Key);
                                break;
                            }
                        }
                    });
                });

                var rightLoader = rightCache.Connect()
                                  .Subscribe(changes =>
                {
                    joinedCache.Edit(innerCache =>
                    {
                        foreach (var change in changes.ToConcreteType())
                        {
                            var right = change.Current;
                            var left = leftCache.Lookup(change.Key);

                            switch (change.Reason)
                            {
                            case ChangeReason.Add:
                            case ChangeReason.Update:
                                {
                                    if (left.HasValue)
                                    {
                                        innerCache.AddOrUpdate(_resultSelector(change.Key, left.Value, right), change.Key);
                                    }
                                    else
                                    {
                                        innerCache.Remove(change.Key);
                                    }
                                }

                                break;

                            case ChangeReason.Remove:
                                {
                                    innerCache.Remove(change.Key);
                                }

                                break;

                            case ChangeReason.Refresh:
                                //propagate upstream
                                innerCache.Refresh(change.Key);
                                break;
                            }
                        }
                    });
                });

                return new CompositeDisposable(
                    joinedCache.Connect().NotEmpty().SubscribeSafe(observer),
                    leftCache,
                    rightCache,
                    leftLoader,
                    rightLoader,
                    joinedCache);
            }));
        }
Ejemplo n.º 4
0
        public IObservable <IChangeSet <TDestination, TLeftKey> > Run()
        {
            return(Observable.Create <IChangeSet <TDestination, TLeftKey> >(observer =>
            {
                var locker = new object();

                //create local backing stores
                var leftCache = _left.Synchronize(locker).AsObservableCache(false);
                var rightCache = _right.Synchronize(locker).ChangeKey(_rightKeySelector).AsObservableCache(false);

                //joined is the final cache
                var joinedCache = new LockFreeObservableCache <TDestination, TLeftKey>();

                var leftLoader = leftCache.Connect()
                                 .Subscribe(changes =>
                {
                    joinedCache.Edit(innerCache =>
                    {
                        changes.ForEach(change =>
                        {
                            var left = change.Current;
                            var right = rightCache.Lookup(change.Key);

                            switch (change.Reason)
                            {
                            case ChangeReason.Add:
                            case ChangeReason.Update:
                                innerCache.AddOrUpdate(_resultSelector(change.Key, left, right), change.Key);
                                break;

                            case ChangeReason.Remove:

                                if (!right.HasValue)
                                {
                                    //remove from result because there is no left and no rights
                                    innerCache.Remove(change.Key);
                                }
                                else
                                {
                                    //update with no left value
                                    innerCache.AddOrUpdate(_resultSelector(change.Key, Optional <TLeft> .None, right), change.Key);
                                }
                                break;

                            case ChangeReason.Evaluate:
                                //propagate upstream
                                innerCache.Evaluate(change.Key);
                                break;
                            }
                        });
                    });
                });

                var rightLoader = rightCache.Connect()
                                  .Subscribe(changes =>
                {
                    joinedCache.Edit(innerCache =>
                    {
                        changes.ForEach(change =>
                        {
                            var right = change.Current;
                            var left = leftCache.Lookup(change.Key);

                            switch (change.Reason)
                            {
                            case ChangeReason.Add:
                            case ChangeReason.Update:
                                {
                                    innerCache.AddOrUpdate(_resultSelector(change.Key, left, right), change.Key);
                                }
                                break;

                            case ChangeReason.Remove:
                                {
                                    if (!left.HasValue)
                                    {
                                        //remove from result because there is no left and no rights
                                        innerCache.Remove(change.Key);
                                    }
                                    else
                                    {
                                        //update with no right value
                                        innerCache.AddOrUpdate(_resultSelector(change.Key, left, Optional <TRight> .None), change.Key);
                                    }
                                }
                                break;

                            case ChangeReason.Evaluate:
                                //propagate upstream
                                innerCache.Evaluate(change.Key);
                                break;
                            }
                        });
                    });
                });


                return new CompositeDisposable(
                    joinedCache.Connect().NotEmpty().SubscribeSafe(observer),
                    leftCache,
                    rightCache,
                    leftLoader,
                    joinedCache,
                    rightLoader);
            }));
        }