Пример #1
0
        public void DoNotThrowAWobblyWhenRemovingaMutatedValue()
        {

            var pageController = new PageController();
            var sortController = new SortController<TestVm>(SortExpressionComparer<TestVm>.Ascending(t => t.DateFavorited ?? DateTime.MinValue));
            var filterController = new FilterController<TestVm>(myVm => myVm.Id != 0);
            var items = new ObservableCollectionExtended<TestVm>();
            var itemCache = new SourceCache<TestVm, int>(myVm => myVm.Id);

            var item1 = new TestVm(1) { DateFavorited = DateTime.Now };
            var item2 = new TestVm(2) { DateFavorited = DateTime.Now };

            itemCache.AddOrUpdate(item1);
            itemCache.AddOrUpdate(item2);

            bool error = false;
            itemCache.Connect()
                .Filter(filterController)
                .Sort(sortController)
                .Page(pageController)//error doesnt occur with paging disabled
                .Bind(items)
                .Subscribe(changes => { }, ex => error = true);

            pageController.Change(new PageRequest(1, 100));

            //NB: never errored if it was the first item which was removed
            item2.DateFavorited = null;
            itemCache.Remove(item2); //ERROR!

            Assert.IsFalse(error, "Error has been thrown");
        }
        public SearchInfoCollection(ISearchMetadataCollection searchMetadataCollection, IFileWatcher fileWatcher)
        {
            _metadataCollection = searchMetadataCollection;
            _fileWatcher = fileWatcher;

            //Add a complete file display
            All = fileWatcher.Latest.Index().Replay(1).RefCount();

            //create a collection with 1 item, which is used to show entire file
            var systemSearches = new SourceCache<SearchInfo, CaseInsensitiveString>(t => (CaseInsensitiveString)t.SearchText);
            systemSearches.AddOrUpdate(new SearchInfo("<All>", All, SearchType.All));

            //create a collection of all possible user filters
            var userSearches = searchMetadataCollection.Metadata
                .Connect(meta => meta.Filter)
                .IgnoreUpdateWhen((current,previous)=>current.Filter == previous.Filter)
                .Transform(meta =>
                {
                    var latest = _fileWatcher.Latest
                        .Search(s => s.Contains(meta.SearchText, StringComparison.OrdinalIgnoreCase))
                        .Replay(1).RefCount();

                    return new SearchInfo(meta.SearchText, latest, SearchType.User);
                });

            //combine te results into a single collection
            Searches = systemSearches.Connect()
                    .Or(userSearches)
                    .AsObservableCache();

            _cleanUp = new CompositeDisposable(Searches, systemSearches);
        }
Пример #3
0
        public SearchInfoCollection(ISearchMetadataCollection searchMetadataCollection,
            ISearchMetadataFactory searchMetadataFactory,
            IFileWatcher fileWatcher)
        {
            _metadataCollection = searchMetadataCollection;
            _searchMetadataFactory = searchMetadataFactory;
            _fileWatcher = fileWatcher;

            //Add a complete file display
            All = _fileWatcher.Latest.Index().Replay(1).RefCount();

            //create a collection with 1 item, which is used to show entire file
            var systemSearches = new SourceCache<SearchInfo, string>(t => t.SearchText);
            systemSearches.AddOrUpdate(new SearchInfo("<All>", All, SearchType.All));

            //create a collection of all possible user filters
            var userSearches = searchMetadataCollection.Metadata
                .Connect(meta => meta.Filter)
                .IgnoreUpdateWhen((current,previous)=> SearchMetadata.EffectsFilterComparer.Equals(current, previous))
                .Transform(meta =>
                {
                    var latest = _fileWatcher.Latest
                        .Search(meta.BuildPredicate())
                        .Replay(1).RefCount();

                    return new SearchInfo(meta.SearchText, latest, SearchType.User);
                });

            //combine te results into a single collection
            Searches = systemSearches.Connect()
                    .Or(userSearches)
                    .AsObservableCache();

            _cleanUp = new CompositeDisposable(Searches, systemSearches);
        }
Пример #4
0
        public LineScroller(FileInfo file,
                IObservable<ILineProvider> latest,
                IObservable<ScrollRequest> scrollRequest,
                ILogger logger,
                IScheduler scheduler = null)
        {
            if (file == null) throw new ArgumentNullException(nameof(file));
            if (latest == null) throw new ArgumentNullException(nameof(latest));
            if (logger == null) throw new ArgumentNullException(nameof(logger));

            logger.Info($"Constructing file tailer for {file.FullName}");

            var lines = new SourceCache<Line, LineKey>(l=>l.Key);
            Lines = lines.AsObservableCache();

            var locker = new object();
            scrollRequest = scrollRequest.Synchronize(locker);


            var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) => currentLines.ReadLines(scroll).ToArray())
                .Subscribe(currentPage =>
                {
                    var previous = lines.Items.ToArray();
                    var added = currentPage.Except(previous,Line.TextStartComparer).ToArray();
                    var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray();

                    lines.Edit(innerCache =>
                    {
                        if (removed.Any()) innerCache.Remove(removed);
                        if (added.Any()) innerCache.AddOrUpdate(added);
                    });
                });

            _cleanUp = new CompositeDisposable(Lines, lines, aggregator);
        }
        public CombinedSearchMetadataCollection([NotNull] ISearchMetadataCollection metadataCollection, [NotNull] IGlobalSearchOptions globalSearchOptions)
        {
            if (metadataCollection == null) throw new ArgumentNullException(nameof(metadataCollection));
            if (globalSearchOptions == null) throw new ArgumentNullException(nameof(globalSearchOptions));

            Local = metadataCollection;
            Global = globalSearchOptions.Metadata;

            var cache = new SourceCache<SearchMetadata, string>(t => t.SearchText);

            ////Prioritise local before global and renumber
            var localItems = metadataCollection.Metadata.Connect().ToCollection().Select(items => items.ToArray()).StartWith(Enumerable.Empty<SearchMetadata>());

            var globalItems = globalSearchOptions.Metadata.Metadata.Connect().ToCollection().Select(items => items.ToArray()).StartWith(Enumerable.Empty<SearchMetadata>());

            var combiner = localItems.CombineLatest(globalItems, (local, global) => new {local, global}).Select(x => Combine(x.local, x.global)).Subscribe(uppdatedItems =>
            {
                cache.Edit(innerCache =>
                {
                    var toRemove = innerCache.Items.Except(uppdatedItems,SearchMetadata.SearchTextComparer).ToArray();
                    innerCache.Remove(toRemove);
                    innerCache.AddOrUpdate(uppdatedItems);
                });
            });

            Combined = cache.Connect().IgnoreUpdateWhen((current, previous) => current.Equals(previous)).AsObservableCache();

            _cleanUp = new CompositeDisposable(Combined, cache, combiner);
        }
        public void Does_Not_Reuse_Disposed_Wrappers()
        {
            var subject = new SourceCache <Widget, int>(w => w.Id);

            var activeObservable   = new ObservableCollectionExtended <WidgetWrapper>();
            var inactiveObservable = new ObservableCollectionExtended <WidgetWrapper>();

            var activeFilter   = new FilterController <WidgetWrapper>(wrapper => wrapper.Wrapped.Active);
            var inactiveFilter = new FilterController <WidgetWrapper>(wrapper => !wrapper.Wrapped.Active);

            subject.Connect()
            .Transform(w => new WidgetWrapper(w))
            .Filter(activeFilter)
            .Bind(activeObservable)
            .DisposeMany()
            .Subscribe();

            subject.Connect()
            .Transform(w => new WidgetWrapper(w))
            .Filter(inactiveFilter)
            .Bind(inactiveObservable)
            .DisposeMany()
            .Subscribe();

            var w1 = new Widget()
            {
                Id = 0, Active = true
            };
            var w2 = new Widget()
            {
                Id = 1, Active = true
            };

            subject.AddOrUpdate(w1);
            subject.AddOrUpdate(w2);
            Assert.AreEqual(2, activeObservable.Count);
            Assert.AreEqual(0, inactiveObservable.Count);
            Assert.IsFalse(activeObservable[0].IsDisposed);
            Assert.IsFalse(activeObservable[1].IsDisposed);

            //This needs to be done twice to trigger the behavior
            w1.Active = !w1.Active;
            activeFilter.Reevaluate();
            inactiveFilter.Reevaluate();

            w1.Active = !w1.Active;
            activeFilter.Reevaluate();
            inactiveFilter.Reevaluate();

            Assert.AreEqual(2, activeObservable.Count);

            Assert.False(activeObservable[0].IsDisposed);
            Assert.False(activeObservable[1].IsDisposed);
        }
        public void TransformToNull()
        {
            using var source  = new SourceCache <Person, string>(p => p.Name);
            using var results = new ChangeSetAggregator <PersonWithGender?, string>(source.Connect()
                                                                                    .Transform((Func <Person, PersonWithGender?>)(p => null), new ParallelisationOptions(ParallelType.Parallelise)));
            source.AddOrUpdate(new Person("Adult1", 50));

            results.Messages.Count.Should().Be(1, "Should be 1 updates");
            results.Data.Count.Should().Be(1, "Should be 1 item in the cache");
            results.Data.Items.First().Should().Be(null, "Should be same person");
        }
Пример #8
0
        public CatalogProvider(
            IChatLoader chatLoader,
            IChatUpdater chatUpdater
            )
        {
            _chatLoader  = chatLoader;
            _chatUpdater = chatUpdater;

            _entryStore = new Dictionary <long, EntryModel>();
            _chats      = new SourceCache <EntryModel, long>(m => m.Id);
        }
Пример #9
0
 public void Filter_ItemsBeforeSubscribe()
 {
     using (var list = new SourceCache <Person, string>(i => i.Name))
     {
         foreach (var item in People)
         {
             list.AddOrUpdate(item);
         }
         list.Connect().Filter(v => v.Age % 2 == 0).Subscribe(v => { });
     }
 }
        public void StocksEmptyResultTotalNumberZeroTotalMarketValueZeroTotalStockWeightZero()
        {
            var scheduler  = new TestScheduler();
            var stocks     = new SourceCache <Stock, long>(t => t.Id);
            var fundStocks = new SourceCache <Stock, string>(t => t.Type.ToString() + t.Id);

            var target = new BaseSummaryService <long, string>(stocks, fundStocks, scheduler);

            Assert.AreEqual(0, target.TotalMarketValue);
            Assert.AreEqual(0, target.TotalNumber);
            Assert.AreEqual(0, target.TotalStockWeight);
        }
        public void TransformManyWithKey()
        {
            var children = Enumerable.Range(1, 100).Select(i => new Person("Name" + i, i)).ToArray();

            int childIndex = 0;
            var parents    = Enumerable.Range(1, 50)
                             .Select(i =>
            {
                var parent = new Parent(i, new[]
                {
                    children[childIndex],
                    children[childIndex + 1]
                });

                childIndex = childIndex + 2;
                return(parent);
            }).ToArray();


            using (var source = new SourceCache <Parent, int>(x => x.Id))
                using (var aggregator = source.Connect()
                                        .TransformMany(p => p.Children, c => c.Name)
                                        .AsAggregator())
                {
                    source.AddOrUpdate(parents);

                    aggregator.Data.Count.Should().Be(100);

                    //add a child to an observable collection and check the new item is added
                    parents[0].Children.Add(new Person("NewlyAddded", 100));
                    aggregator.Data.Count.Should().Be(101);

                    ////remove first parent and check children have gone
                    source.RemoveKey(1);
                    aggregator.Data.Count.Should().Be(98);


                    //check items can be cleared and then added back in
                    var childrenInZero = parents[1].Children.ToArray();
                    parents[1].Children.Clear();
                    aggregator.Data.Count.Should().Be(96);
                    parents[1].Children.AddRange(childrenInZero);
                    aggregator.Data.Count.Should().Be(98);

                    //replace produces an update
                    var replacedChild = parents[1].Children[0];
                    parents[1].Children[0] = new Person("Replacement", 100);
                    aggregator.Data.Count.Should().Be(98);

                    aggregator.Data.Lookup(replacedChild.Name).HasValue.Should().BeFalse();
                    aggregator.Data.Lookup("Replacement").HasValue.Should().BeTrue();
                }
        }
Пример #12
0
        public void Grouping()
        {
            var domainCache  = new SourceCache <DomainDto, int>(d => d.Id);
            var projectCache = new SourceCache <ProjectDto, int>(p => p.Id);

            //if domain has a project id, it is very efficient to use Group
            var domainWithInnerGroup = domainCache.Connect().Group(d => d.ProjectId);


            IObservable <IChangeSet <ProjectWithDomainCache, int> > combind = projectCache.Connect()
                                                                              .InnerJoin(domainWithInnerGroup, domain => domain.Key, (key, left, right) => new ProjectWithDomainCache(left, right.Cache));
        }
Пример #13
0
        public void ReapplyFilterDoesntThrow()
        {
            using (var source = new SourceCache <Person, string>(p => p.Key))
            {
                source.AddOrUpdate(Enumerable.Range(1, 100).Select(i => new Person("P" + i, i)).ToArray());

                var ex = Record.Exception(() => source.Connect()
                                          .Filter(Observable.Return(Unit.Default))
                                          .AsObservableCache());
                Assert.Null(ex);
            }
        }
Пример #14
0
        private void LoadLinkedGames()
        {
            _linkedGames = new SourceCache <LinkedGameModel, Guid>(p => p.Id);
            foreach (var linkedGameEntity in _linkedGameAccessor.GetAll())
            {
                var linkedGame = _mapper.Map <LinkedGameModel>(linkedGameEntity);
                _linkedGames.AddOrUpdate(linkedGame);
            }

            LinkedGames.WhenAnyPropertyWithAttributeChanged(typeof(ReactiveAttribute))
            .Subscribe(p => AddOrUpdate(p).Wait());
        }
Пример #15
0
 public TradeTask(IEnumerable <OrderTrade> exchangeTrades = null)
 {
     Trades = new SourceCache <OrderTrade, string>(x => x.Id);
     Events = new Dictionary <DateTime, string>();
     if (exchangeTrades != null)
     {
         Trades.Edit(innerList => innerList.AddOrUpdate(exchangeTrades));
     }
     Jobs         = new List <OrderTask>();
     FinishedJobs = new Queue <OrderTask>();
     Events       = new Dictionary <DateTime, string>();
 }
        public EmployeesService(IDbContextFactory <SampleAvaloniaApplicationClientContext> contextFactory, IMapper mapper)
        {
            _mapper         = mapper;
            _contextFactory = contextFactory;

            _employees = new SourceCache <EmployeeModel, Guid>(e => e.Id);

            using (var context = _contextFactory.Create())
            {
                _employees.AddOrUpdate(_mapper.ProjectTo <EmployeeModel>(context.Employees));
            }
        }
Пример #17
0
        public void OnItemAddCalled()
        {
            var called = false;
            var source = new SourceCache <Person, int>(x => x.Age);

            source.Connect().OnItemAdded(_ => called = true).Subscribe();

            var person = new Person("A", 1);

            source.AddOrUpdate(person);
            Assert.True(called);
        }
Пример #18
0
        public ChangeSetToCache(Func <TValue, TKey> keySelector, IObservable <IChangeSet <TValue> > set)
        {
            _cache = new SourceCache <TValue, TKey>(keySelector);

            _subscription = set.OnItemAdded(_cache.AddOrUpdate).OnItemRemoved(_cache.Remove).Subscribe();

            //_subscription = set.Receive(cs =>
            //{
            //    foreach (var change in cs)
            //    {
            //        switch (change.Reason)
            //        {
            //            case ListChangeReason.Add:
            //                _cache.AddOrUpdate(change.Item.Current);
            //                break;
            //            case ListChangeReason.AddRange:
            //                _cache.AddOrUpdate(change.Range);
            //                break;
            //            case ListChangeReason.Replace:
            //                change.Item.Previous.IfHasValue(tv => _cache.Remove(tv));
            //                _cache.AddOrUpdate(change.Item.Current);
            //                break;
            //            case ListChangeReason.Remove:
            //                _cache.Remove(change.Item.Current);
            //                break;
            //            case ListChangeReason.RemoveRange:
            //                _cache.Remove(change.Range);
            //                break;
            //            case ListChangeReason.Refresh:
            //                switch (change.Type)
            //                {
            //                    case ChangeType.Item:
            //                        _cache.Refresh(change.Item.Current);
            //                        break;
            //                    case ChangeType.Range:
            //                        _cache.Refresh(change.Range);
            //                        break;
            //                    default:
            //                        throw new ArgumentOutOfRangeException();
            //                }

            //                break;
            //            case ListChangeReason.Clear:
            //                _cache.Clear();
            //                break;
            //            case ListChangeReason.Moved:
            //                break;
            //            default:
            //                throw new ArgumentOutOfRangeException();
            //        }
            //    }
            //});
        }
Пример #19
0
        public LineScroller(FileInfo file,
                            IObservable <ILineProvider> latest,
                            IObservable <ScrollRequest> scrollRequest,
                            ILogger logger,
                            IScheduler scheduler = null)
        {
            if (file == null)
            {
                throw new ArgumentNullException(nameof(file));
            }
            if (latest == null)
            {
                throw new ArgumentNullException(nameof(latest));
            }
            if (logger == null)
            {
                throw new ArgumentNullException(nameof(logger));
            }

            logger.Info($"Constructing file tailer for {file.FullName}");

            var lines = new SourceCache <Line, LineKey>(l => l.Key);

            Lines = lines.AsObservableCache();

            var locker = new object();

            scrollRequest = scrollRequest.Synchronize(locker);


            var aggregator = latest.CombineLatest(scrollRequest, (currentLines, scroll) => currentLines.ReadLines(scroll).ToArray())
                             .RetryWithBackOff <Line[], Exception>((ex, i) => TimeSpan.FromSeconds(1))
                             .Subscribe(currentPage =>
            {
                var previous = lines.Items.ToArray();
                var added    = currentPage.Except(previous, Line.TextStartComparer).ToArray();
                var removed  = previous.Except(currentPage, Line.TextStartComparer).ToArray();

                lines.Edit(innerCache =>
                {
                    if (removed.Any())
                    {
                        innerCache.Remove(removed);
                    }
                    if (added.Any())
                    {
                        innerCache.AddOrUpdate(added);
                    }
                });
            });

            _cleanUp = new CompositeDisposable(Lines, lines, aggregator);
        }
Пример #20
0
 public void AddModpack()
 {
     new TestScheduler().With(scheduler =>
     {
         var cache = new SourceCache <Modpack, Guid>(_ => Guid.NewGuid());
         var vm    = new LibraryViewModel(cache);
         vm.Modpacks.Should().BeEmpty();
         cache.AddOrUpdate(new Modpack(new Common.Models.DTO.Repo.Modpack()));
         scheduler.AdvanceBy(1);
         vm.Modpacks.Should().HaveCount(1);
     });
 }
Пример #21
0
        public void RefreshAllTest()
        {
            using (var refresher = new Subject <Unit>())
                using (var cache = new SourceCache <Valuable <string>, Guid>(x => x.Key))
                    using (var aggregator = cache.Connect().AutoRefreshOnObservable(x => refresher).AsAggregator())
                    {
                        cache.AddOrUpdate(_items);
                        refresher.OnNext(Unit.Default);

                        Assert.AreEqual(101, aggregator.Messages.Count);
                        EnumerableAssert.All(aggregator.Messages.SelectMany(x => x), x => x.Reason == ChangeReason.Refresh);
                    }
        }
Пример #22
0
        public Domain0Model()
        {
            UserProfiles     = new SourceCache <UserProfile, int>(x => x.Id);
            Roles            = new SourceCache <Role, int>(x => x.Id.Value);
            Permissions      = new SourceCache <Permission, int>(x => x.Id.Value);
            Applications     = new SourceCache <Application, int>(x => x.Id.Value);
            Environments     = new SourceCache <Environment, int>(x => x.Id.Value);
            MessageTemplates = new SourceCache <MessageTemplate, int>(x => x.Id.Value);

            RolePermissions = new SourceList <RolePermission>();
            UserRoles       = new SourceList <UserRole>();
            UserPermissions = new SourceList <UserPermission>();
        }
Пример #23
0
        public void AddPresynaptic(SourceCache <NeuronDto, int> cache, NeuronDto neuronDto)
        {
            var presyn = new NeuronDto(
                Guid.NewGuid().GetHashCode(),
                neuronDto.Id,
                Guid.NewGuid().ToString(),
                neuronDto.ParentNeuronId,
                "New Presynaptic",
                ChildType.Presynaptic
                );

            cache.AddOrUpdate(presyn);
        }
Пример #24
0
        private void LoadPlays()
        {
            _plays = new SourceCache <PlayModel, Guid>(p => p.Id);
            foreach (var entity in _playAccessor.GetAll())
            {
                var play = _mapper.Map <PlayModel>(entity);

                _plays.AddOrUpdate(play);
            }

            Plays.WhenAnyPropertyWithAttributeChanged(typeof(ReactiveAttribute))
            .Subscribe(p => AddOrUpdate(p).Wait());
        }
        public void ImageExplorerViewModel_SyncsIntialItemsFromCache_WhenItemsAvailable() =>
        new TestScheduler().With(scheduler =>
        {
            var source = new SourceCache <ImageHandle, string>(x => x.LoadingSettings.FilePath);
            source.AddOrUpdate(GetDummyHandle("foo"));

            var sut = new ImageExplorerViewModel(source.AsObservableCache());
            sut.Activator.Activate();

            scheduler.AdvanceBy(2);

            Assert.Equal(1, sut.Children.Count);
        });
Пример #26
0
        public void GroupTest_Add()
        {
            using (var cache = new SourceCache <Groupable <int, string>, Guid>(x => x.Key))
                using (var aggregator = cache.Connect()
                                        .Group(x => x.GroupKey)
                                        .AsAggregator())
                {
                    cache.AddOrUpdate(_items);
                    cache.AddOrUpdate(new Groupable <int, string>(1, "Group 2"));

                    Assert.AreEqual(2, aggregator.Messages.Count);
                }
        }
Пример #27
0
        public void PopulateCache_Observers()
        {
            var items = Enumerable.Range(1, 10_000).Select(j => new Person("P" + j, j)).ToList();

            var cache      = new SourceCache <Person, string>(p => p.Name);
            var subscribed = cache.Connect().Subscribe();
            var result     = Allocations.Run(() =>
            {
                cache.AddOrUpdate(items);
            });

            Console.WriteLine(result);
        }
Пример #28
0
        public void Setup()
        {
            _scheduler = new TestScheduler();

            var routingState = new RoutingState();
            var screenMock   = new Mock <IScreen>()
            {
                DefaultValue = DefaultValue.Mock
            };

            screenMock.SetupGet(x => x.Router).Returns(routingState);
            _screen = screenMock.Object;

            _movieService = new Mock <IMovieService>()
            {
                DefaultValue = DefaultValue.Mock
            };
            _movieService.Setup(x => x.LoadUpcomingMovies(It.Is <int>(y => y >= 0 && y < 100))).Returns(() => Observable.Return(Unit.Default));
            _movieService.Setup(x => x.LoadUpcomingMovies(It.Is <int>(y => y >= 100))).Returns(() => throw new Exception("Boom!"));

            var movies = new List <Movie>();

            for (int i = 0; i < 20; i++)
            {
                movies.Add(new Movie
                {
                    Id          = i,
                    Overview    = $"Overview {i}",
                    PosterBig   = "PosterPath/",
                    PosterSmall = "PosterPath/",
                    ReleaseDate = DateTime.Now,
                    Title       = $"Title {i}"
                });
            }

            _moviesSourceCache = new SourceCache <Movie, int>(x => x.Id);
            _moviesSourceCache.AddOrUpdate(movies);
            _movieService.Setup(x => x.UpcomingMovies).Returns(_moviesSourceCache);

            _target = new UpcomingMoviesListViewModel(_scheduler, _scheduler, _movieService.Object, _screen);

            _alertOutput = null;
            _target.ShowAlert.RegisterHandler(handler =>
            {
                _alertOutput = handler.Input;
                handler.SetOutput(Unit.Default);
            });

            _screen.Router.NavigateAndReset.Execute(_target);
        }
Пример #29
0
        public void GroupTest_Update()
        {
            using (var cache = new SourceCache <Groupable <int, string>, Guid>(x => x.Key))
                using (var aggregator = cache.Connect()
                                        .Group(x => x.GroupKey)
                                        .AsAggregator())
                {
                    cache.AddOrUpdate(_items);
                    cache.AddOrUpdate(_items[0]);

                    Assert.AreEqual(2, aggregator.Messages.Count);
                    EnumerableAssert.All(aggregator.Messages.SelectMany(x => x), x => x.Reason == ChangeReason.Refresh);
                }
        }
Пример #30
0
        public void Activate()
        {
            if (active != ActiveState.NotStarted)
                throw new InvalidOperationException("Wrong state");

            active = ActiveState.Active;

            dbg = zm.Debug();
            src = new SourceCache(sourcePath);

            io.PutString("ZLR Debugger\n");
            dbg.Restart();
            ShowStatus();
        }
Пример #31
0
 protected virtual void Dispose(bool disposing)
 {
     if (!_disposedValue)
     {
         if (disposing)
         {
             // dispose
             this.cache.Dispose();
         }
         // large fields, unmanaged
         this.cache     = null;
         _disposedValue = true;
     }
 }
Пример #32
0
        public static bool TryLookup <TValue, TKey>(this SourceCache <TValue, TKey> cache, TKey key,
                                                    [MaybeNullWhen(false)] out TValue value)
        {
            var option = cache.Lookup(key);

            if (option.HasValue)
            {
                value = option.Value;
                return(true);
            }

            value = default;
            return(false);
        }
Пример #33
0
        public PriceService()
        {
            _availableEntitiesCache = new SourceCache <IPrice, String>(price => price.EntityCacheKey);
            _availableEntities      = _availableEntitiesCache.AsObservableCache();

            TestHelper.Assets.ForEach(asset => _availableEntitiesCache.AddOrUpdate(new Price(DateTime.Now.Ticks, asset, asset.StartingPrice)));

            Observable
            .Interval(TimeSpan.FromMilliseconds(500))
            .Subscribe((_) =>
            {
                var price = CreatePrice();
                _availableEntitiesCache.AddOrUpdate(price);
            });
        }
Пример #34
0
        public Cp77Controller(ILoggerService loggerService,
                              IProjectManager projectManager,
                              ISettingsManager settingsManager,
                              IHashService hashService,
                              ModTools modTools
                              )
        {
            _loggerService   = loggerService;
            _projectManager  = projectManager;
            _settingsManager = settingsManager;
            _hashService     = hashService;
            _modTools        = modTools;

            _rootCache = new SourceCache <GameFileTreeNode, string>(t => t.FullPath);
        }
Пример #35
0
        public void ChangeData(SourceCache <NeuronDto, int> cache, NeuronDto dto, string value)
        {
            // TODO: update data source
            // TODO: retrieve updated value and replace value in children
            var newValue = new NeuronDto(
                dto.Id,
                dto.ParentId,
                dto.NeuronId,
                dto.ParentNeuronId,
                value,
                dto.Type
                );

            cache.AddOrUpdate(newValue);
        }
Пример #36
0
        public void GroupTest_RefreshGroupsWithoutGroupKeyChanged()
        {
            using (var refresher = new Subject <Unit>())
                using (var cache = new SourceCache <Groupable <int, string>, Guid>(x => x.Key))
                    using (var aggregator = cache.Connect()
                                            .Group(x => x.GroupKey, refresher)
                                            .AsAggregator())
                    {
                        cache.AddOrUpdate(_items);
                        refresher.OnNext(Unit.Default);

                        Assert.AreEqual(1, aggregator.Messages.Count);
                        EnumerableAssert.None(aggregator.Messages.SelectMany(x => x), x => x.Reason == ChangeReason.Refresh);
                    }
        }
Пример #37
0
        public void ErrorUpdatingStreamIsHandled()
        {
            bool completed = false;
            bool error = false;

            var feeder = new SourceCache<ErrorInKey, int>(p=>p.Key);

            var subscriber = feeder.Connect().Finally(() => completed = true)
                                 .Subscribe(updates => { Console.WriteLine(); }, ex => error = true);

            feeder.BatchUpdate(updater => updater.AddOrUpdate(new ErrorInKey()));
            subscriber.Dispose();

            Assert.IsTrue(error, "Error has not been invoked");
            Assert.IsTrue(completed, "Completed has not been called");
        }
Пример #38
0
        public void Initialise()
        {
            _source = new SourceCache<Person, string>(p => p.Name);

            _accumulator = _source.Connect().ForAggregation()
                .Scan(0, (current, items) =>
                {
                    items.ForEach(x =>
                    {
                        if (x.Type == AggregateType.Add)
                            current = current + x.Item.Age;
                        else
                            current = current - x.Item.Age;
                    });
                    return current;
                });
        }
Пример #39
0
        public LineScroller([NotNull] IObservable<ILineProvider> latest, [NotNull] IObservable<ScrollRequest> scrollRequest)
        {
            if (latest == null) throw new ArgumentNullException(nameof(latest));
            if (scrollRequest == null) throw new ArgumentNullException(nameof(scrollRequest));


            var lines = new SourceCache<Line, LineKey>(l => l.Key);
            Lines = lines.AsObservableCache();

            var locker = new object();

            scrollRequest = scrollRequest.Synchronize(locker);
            latest = latest.Synchronize(locker);

            var aggregator = latest
                .CombineLatest(scrollRequest, (currentLines, scroll) =>
                {
                    try
                    {
                        var x = currentLines.ReadLines(scroll).ToArray();
                        return x;
                    }
                    catch (Exception ex)
                    {
                        throw ex;
                    }

                })
                .Subscribe(currentPage =>
                {

                    var previous = lines.Items.ToArray();
                    var added = currentPage.Except(previous, Line.TextStartComparer).ToArray();
                    var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray();


                    lines.Edit(innerCache =>
                    {
                        if (removed.Any()) innerCache.Remove(removed);
                        if (added.Any()) innerCache.AddOrUpdate(added);
                    });
                });

            _cleanUp = new CompositeDisposable(Lines, lines, aggregator);
        }
Пример #40
0
        public void FilterError()
        {
            bool completed = false;
            bool error = false;

            var feeder = new SourceCache<TransformEntityWithError, int>(e=>e.Key);

            var subscriber = feeder.Connect()
                            .Filter(x=>true)
                            .Finally(() => completed = true)
                            .Subscribe(updates => { Console.WriteLine(); }, ex => error = true);

            feeder.BatchUpdate(updater => updater.AddOrUpdate(new TransformEntityWithError(new Entity())));
            subscriber.Dispose();

            Assert.IsTrue(error, "Error has not been invoked");
            Assert.IsTrue(completed, "Completed has not been called");
        }
        public void SkipInitialDoesNotReturnTheFirstBatchOfData()
        {
            bool updateReceived = false;

            var cache = new SourceCache<Person, string>(p => p.Name);


            var deferStream = cache.Connect().SkipInitial()
                                .Subscribe(changes => updateReceived = true);

            Assert.IsFalse(updateReceived, "No update should be received");

            cache.AddOrUpdate(new Person("P1", 1));

            Assert.IsFalse(updateReceived, "No update should be received for initial batch of changes");

            cache.AddOrUpdate(new Person("P2", 2));
            Assert.IsTrue(updateReceived, "Replace should be received");
            deferStream.Dispose();
        }
Пример #42
0
        public void CachePerformance(int n)
        {

            /*
                Tricks to make it fast = 

                1) use cache.AddRange(Enumerable.Range(0, n))
                instead of  for (int i = 0; i < n; i++) cache.AddOrUpdate(i);

                2)  Uncomment Buffer(n/10).FlattenBufferResult()
                or just use buffer by time functions

                With both of these the speed can be almost negligable

            */
            var cache = new SourceCache<int, int>(i => i);
            double calculated = 0;

            var sw = Stopwatch.StartNew();

            var summation = cache.Connect()
                .StdDev(i => i)
                .Subscribe(result => calculated = result);


            //1. this is very slow if there are loads of updates (each updates causes a new summation)
            for (int i = 1; i < n; i++)
                cache.AddOrUpdate(i);

            //2. much faster to to this (whole range is 1 update and 1 calculation):
            //  cache.AddOrUpdate(Enumerable.Range(0,n));

            sw.Stop();

            summation.Dispose();
            cache.Dispose();

            Console.WriteLine("Total items: {0}. Value = {1}", n, calculated);
            Console.WriteLine("Cache: {0} updates took {1} ms {2:F3} ms each. {3}", n, sw.ElapsedMilliseconds, sw.Elapsed.TotalMilliseconds / n, DateTime.Now.ToShortDateString());

        }
Пример #43
0
        public void TransformError()
        {
            bool completed = false;
            bool error = false;

            var feeder = new SourceCache<Entity, int>(e => e.Key);

            var subscriber = feeder.Connect()
                            .Transform(e => new TransformEntityWithError(e))

                            .Finally(() => completed = true)
                            .Subscribe(updates => { Console.WriteLine(); }, ex => error = true);

            feeder.BatchUpdate(updater => updater.AddOrUpdate(Enumerable.Range(0, 10000).Select(_ => new Entity()).ToArray()));
            feeder.BatchUpdate(updater => updater.AddOrUpdate(new Entity()));

            subscriber.Dispose();

            Assert.IsTrue(error, "Error has not been invoked");
            Assert.IsTrue(completed, "Completed has not been called");
        }
Пример #44
0
        public LineScroller([NotNull] IObservable<ILineProvider> latest, [NotNull] IObservable<ScrollRequest> scrollRequest)
        {
            if (latest == null) throw new ArgumentNullException(nameof(latest));
            if (scrollRequest == null) throw new ArgumentNullException(nameof(scrollRequest));

            var lines = new SourceCache<Line, LineKey>(l => l.Key);
            Lines = lines.Connect().IgnoreUpdateWhen((current,previous)=> current.Key==previous.Key).AsObservableCache();

            var locker = new object();

            scrollRequest = scrollRequest.Synchronize(locker);
            latest = latest.Synchronize(locker);

            var aggregator = latest
                .CombineLatest(scrollRequest, (currentLines, scroll) => new { currentLines, scroll})
                .Sample(TimeSpan.FromMilliseconds(50))
                .Select(x =>
                {
                    if (x.scroll== ScrollRequest.None ||  x.scroll.PageSize == 0 || x.currentLines.Count == 0)
                        return new Line[0];

                    return x.currentLines.ReadLines(x.scroll).ToArray();
                })
                .RetryWithBackOff<Line[], Exception>((ex, i) => TimeSpan.FromSeconds(1))
                .Subscribe(currentPage =>
                {
                    var previous = lines.Items.ToArray();
                    var added = currentPage.Except(previous, Line.TextStartComparer).ToArray();
                    var removed = previous.Except(currentPage, Line.TextStartComparer).ToArray();

                    lines.Edit(innerCache =>
                    {
                        if (currentPage.Length == 0) innerCache.Clear();
                        if (removed.Any()) innerCache.Remove(removed);
                        if (added.Any()) innerCache.AddOrUpdate(added);
                    });
                });

            _cleanUp = new CompositeDisposable(Lines, lines, aggregator);
        }
        public void DeferUntilLoadedDoesNothingUntilDataHasBeenReceived()
        {
            bool updateReceived = false;
            IChangeSet<Person, string> result = null;

            var cache = new SourceCache<Person, string>(p => p.Name);


            var deferStream = cache.Connect().DeferUntilLoaded()
                                .Subscribe(changes =>
                                           {
                                               updateReceived = true;
                                               result = changes;
                                           });

            Assert.IsFalse(updateReceived,"No update should be received");
            cache.AddOrUpdate(new Person("Test",1));

            Assert.IsTrue(updateReceived,"Replace should be received");
            Assert.AreEqual(1,result.Adds);
            Assert.AreEqual(new Person("Test",1), result.First().Current);
            deferStream.Dispose();
        }
Пример #46
0
        public FileSearcher([NotNull] IObservable<FileSegmentCollection> fileSegments, 
            [NotNull] Func<string, bool> predicate,
            int arbitaryNumberOfMatchesBeforeWeBailOutBecauseMemoryGetsHammered = 50000,
            Encoding encoding = null,
            IScheduler scheduler =null)
        {
            if (fileSegments == null) throw new ArgumentNullException(nameof(fileSegments));
            if (predicate == null) throw new ArgumentNullException(nameof(predicate));

            _predicate = predicate;
            _arbitaryNumberOfMatchesBeforeWeBailOutBecauseMemoryGetsHammered = arbitaryNumberOfMatchesBeforeWeBailOutBecauseMemoryGetsHammered;
            _scheduler = scheduler ?? Scheduler.Default;

            var shared = fileSegments.Replay(1).RefCount();

            var infoSubscriber = shared.Select(segments => segments.Info)
                .Take(1)
                .Subscribe(info =>
                {
                    Info = info;
                    Encoding = encoding ?? info.GetEncoding();
                });
            //Create a cache of segments which are to be searched
            var segmentCache = shared.Select(s => s.Segments)
                .ToObservableChangeSet(s => s.Key)
                .IgnoreUpdateWhen((current,previous)=>current==previous)
                .AsObservableCache();

            //manually maintained search results and status
            var searchData= new SourceCache<FileSegmentSearch, FileSegmentKey>(s=>s.Key);

            SearchResult = searchData.Connect()
                .Flatten()
                .Select(change=>change.Current)
                .Scan((FileSearchResult)null, (previous, current) => previous==null
                                ? new FileSearchResult(current, Info, Encoding, _arbitaryNumberOfMatchesBeforeWeBailOutBecauseMemoryGetsHammered)
                                : new FileSearchResult(previous, current, Info, Encoding, _arbitaryNumberOfMatchesBeforeWeBailOutBecauseMemoryGetsHammered))
                .StartWith(FileSearchResult.None)
                .Replay(1).RefCount();

            //initialise a pending state for all segments
            var loader = segmentCache.Connect()
                .Transform(fs => new FileSegmentSearch(fs))
                .WhereReasonsAre(ChangeReason.Add)
                .PopulateInto(searchData);

            //scan end of file, then tail
            var tailSearch = segmentCache.WatchValue(FileSegmentKey.Tail)
                .Scan((FileSegmentSearch) null, (previous, current) =>
                {
                    if (previous == null)
                    {
                        var result = Search(current.Start, current.End);
                        return new FileSegmentSearch(current, result);
                    }
                    else
                    {
                        var result = Search(previous.Segment.End, current.End);
                        return result == null ? previous : new FileSegmentSearch(previous, result);
                    }
                })
                .DistinctUntilChanged()
                .Publish();

            //start tailing
            var tailSubscriber = tailSearch.Subscribe(tail => searchData.AddOrUpdate(tail));

            //load the rest of the file segment by segment, reporting status after each search
            var headSubscriber = tailSearch.Take(1).WithContinuation(() =>
            {
                var locker = new object();

                return searchData.Connect(fss=>fss.Segment.Type == FileSegmentType.Head )
                    .Do(head => Debug.WriteLine(head.First().Current))
                    .WhereReasonsAre(ChangeReason.Add)
                    .SelectMany(changes=>changes.Select(c=>c.Current).OrderByDescending(c=>c.Segment.Index).ToArray())
                    .ObserveOn(_scheduler)
                    .Synchronize(locker)
                    .Do(head => searchData.AddOrUpdate(new FileSegmentSearch(head.Segment,FileSegmentSearchStatus.Searching) ))
                   .Select(fileSegmentSearch =>
                   {
                       /*
                            This hack imposes a limitation on the number of items returned as memory can be
                            absolutely hammered [I have seen 20MB memory when searching a 1 GB file - obviously not an option]
                           TODO: A proper solution.
                                   1. How about index to file?
                                   2. Allow auto pipe of large files
                                   3. Allow user to have some control here
                       */

                       var sum = searchData.Items.Sum(fss => fss.Lines.Length);

                       if (sum >= _arbitaryNumberOfMatchesBeforeWeBailOutBecauseMemoryGetsHammered)
                       {
                           return new FileSegmentSearch(fileSegmentSearch,  FileSegmentSearchStatus.Complete);
                       }
                       var result = Search(fileSegmentSearch.Segment.Start, fileSegmentSearch.Segment.End);
                       return new FileSegmentSearch(fileSegmentSearch, result);
                   });
            })
               .Subscribe(head => searchData.AddOrUpdate(head));

            _cleanUp = new CompositeDisposable(
                segmentCache,
                loader,
                tailSubscriber,
                headSubscriber,
                tailSearch.Connect(),
                infoSubscriber);
        }
Пример #47
0
        public FileSearch([NotNull] IObservable<FileSegmentCollection> fileSegments, [NotNull] Func<string, bool> predicate,
             Encoding encoding = null,
            IScheduler scheduler =null)
        {
            if (fileSegments == null) throw new ArgumentNullException(nameof(fileSegments));
            if (predicate == null) throw new ArgumentNullException(nameof(predicate));

            _predicate = predicate;
            _scheduler = scheduler ?? Scheduler.Default;

            var shared = fileSegments.Replay(1).RefCount();

            var infoSubscriber = shared.Select(segments => segments.Info)
                .Take(1)
                .Subscribe(info =>
                {
                    Info = info;
                    Encoding = encoding ?? info.GetEncoding();
                });
            //Create a cache of segments which are to be searched
            var segmentCache = shared.Select(s => s.Segments)
                .ToObservableChangeSet(s => s.Key)
                .IgnoreUpdateWhen((current,previous)=>current==previous)
                .AsObservableCache();

            //manually maintained search results and status
            var searchData= new SourceCache<FileSegmentSearch, FileSegmentKey>(s=>s.Key);

            SearchResult = searchData.Connect()
                .Flatten()
                .Select(change=>change.Current)
                .Scan((FileSearchResult)null, (previous, current) => previous==null
                                ? new FileSearchResult(current, Info, Encoding)
                                : new FileSearchResult(previous, current, Info, Encoding))
                .StartWith(FileSearchResult.None)
                .Replay(1).RefCount();

            //initialise a pending state for all segments
            var loader = segmentCache.Connect()
                .Transform(fs => new FileSegmentSearch(fs))
                .WhereReasonsAre(ChangeReason.Add)
                .PopulateInto(searchData);

            //scan end of file, then tail
            var tailSearch = segmentCache.WatchValue(FileSegmentKey.Tail)
                .Scan((FileSegmentSearch) null, (previous, current) =>
                {
                    if (previous == null)
                    {
                        var result = Search(current.Start, current.End);
                        return new FileSegmentSearch(current, result);
                    }
                    else
                    {
                        var result = Search(previous.Segment.End, current.End);
                        return result == null ? previous : new FileSegmentSearch(previous, result);
                    }
                })
                .DistinctUntilChanged()
                .Publish();

            //start tailing
            var tailSubscriber = tailSearch.Subscribe(tail => searchData.AddOrUpdate(tail));

            //load the rest of the file segment by segment, reporting status after each search
            var headSubscriber = tailSearch.Take(1).WithContinuation(() =>
            {
                var locker = new object();
                return searchData.Connect(fss=>fss.Segment.Type == FileSegmentType.Head )
                    .Do(head => Debug.WriteLine(head.First().Current))
                    .WhereReasonsAre(ChangeReason.Add)
                    .SelectMany(changes=>changes.Select(c=>c.Current).OrderByDescending(c=>c.Segment.Index).ToArray())
                    .ObserveOn(_scheduler)
                    .Synchronize(locker)
                    .Do(head => searchData.AddOrUpdate(new FileSegmentSearch(head.Segment,FileSegmentSearchStatus.Searching) ))
                    .Select(fss =>
                    {
                       // Debug.WriteLine($"Running Search For: {fss.Key}");
                        var result = Search(fss.Segment.Start, fss.Segment.End);
                        return new FileSegmentSearch(fss, result);
                    });
            })
               .Subscribe(head => searchData.AddOrUpdate(head));

            _cleanUp = new CompositeDisposable(
                segmentCache,
                loader,
                tailSubscriber,
                headSubscriber,
                tailSearch.Connect(),
                infoSubscriber);
        }
Пример #48
0
 public void Initialise()
 {
     _source = new SourceCache<Person, string>(p => p.Name);
 }
        public SearchInfoCollection(ICombinedSearchMetadataCollection combinedSearchMetadataCollection,
            ISearchMetadataFactory searchMetadataFactory,
            IFileWatcher fileWatcher)
        {
            _localMetadataCollection = combinedSearchMetadataCollection.Local;
            _combinedSearchMetadataCollection = combinedSearchMetadataCollection;
            _searchMetadataFactory = searchMetadataFactory;
            _fileWatcher = fileWatcher;

            var exclusionPredicate = combinedSearchMetadataCollection.Combined.Connect()
                    .IncludeUpdateWhen((current, previous) => !SearchMetadata.EffectsFilterComparer.Equals(current, previous))
                    .Filter(meta=> meta.IsExclusion)
                    .ToCollection()
                    .Select(searchMetadataItems =>
                    {
                        Func<string, bool> predicate = null;

                        if (searchMetadataItems.Count == 0)
                            return predicate;

                        var predicates = searchMetadataItems.Select(meta => meta.BuildPredicate()).ToArray();
                        predicate = str =>
                        {
                            return !predicates.Any(item => item(str));
                        };
                        return predicate;
                    }).StartWith((Func<string, bool>)null)
                    .Replay(1).RefCount();

            All = exclusionPredicate.Select(predicate =>
            {
                if (predicate==null)
                    return _fileWatcher.Latest.Index();

                return _fileWatcher.Latest.Search(predicate);

            }).Switch().Replay(1).RefCount();

            //create a collection with 1 item, which is used to show entire file
            var systemSearches = new SourceCache<SearchInfo, string>(t => t.SearchText);
            systemSearches.AddOrUpdate(new SearchInfo("<All>", false, All, SearchType.All));

            //create a collection of all possible user filters
            var userSearches = combinedSearchMetadataCollection.Combined
                .Connect(meta => meta.Filter)
                .IgnoreUpdateWhen((current,previous)=> SearchMetadata.EffectsFilterComparer.Equals(current, previous))
                .Transform(meta =>
                {
                    var latest = exclusionPredicate
                                .Select(exclpredicate =>
                                {
                                    Func<string, bool> resultingPredicate;
                                    if (exclpredicate == null)
                                    {
                                        resultingPredicate = meta.BuildPredicate();
                                    }
                                    else
                                    {
                                        var toMatch = meta.BuildPredicate();
                                        resultingPredicate =  str=> toMatch(str) && exclpredicate(str);
                                    }
                                    return _fileWatcher.Latest.Search(resultingPredicate);

                                })
                                .Switch()
                                .Replay(1).RefCount();

                    return new SearchInfo(meta.SearchText, meta.IsGlobal, latest, SearchType.User);
                });

            //combine te results into a single collection
            Searches = systemSearches.Connect()
                    .Or(userSearches)
                    .AsObservableCache();

            _cleanUp = new CompositeDisposable(Searches, systemSearches);
        }
Пример #50
0
 public void Initialise()
 {
     _source = new SourceCache<ObjectWithObservable, int>(p => p.Id);
 }