Example #1
0
        public IChangeSet <T> WriteWithPreview(Action <IExtendedList <T> > updateAction, Action <IChangeSet <T> > previewHandler)
        {
            if (updateAction == null)
            {
                throw new ArgumentNullException(nameof(updateAction));
            }

            if (previewHandler == null)
            {
                throw new ArgumentNullException(nameof(previewHandler));
            }

            IChangeSet <T> result;

            // Make a copy, apply changes on the main list, perform the preview callback with the old list and swap the lists again to finalize the update.
            lock (_locker)
            {
                ChangeAwareList <T> copy = new ChangeAwareList <T>(_data, false);

                _updateInProgress = true;
                updateAction(_data);
                _updateInProgress = false;

                result = _data.CaptureChanges();

                InternalEx.Swap(ref _data, ref copy);

                previewHandler(result);

                InternalEx.Swap(ref _data, ref copy);
            }

            return(result);
        }
Example #2
0
        public IObservable <IVirtualChangeSet <T> > Run()
        {
            return(Observable.Create <IVirtualChangeSet <T> >(
                       observer =>
            {
                var locker = new object();
                var all = new List <T>();
                var virtualised = new ChangeAwareList <T>();

                IVirtualRequest parameters = new VirtualRequest(0, 25);

                var requestStream = _requests.Synchronize(locker).Select(
                    request =>
                {
                    parameters = request;
                    return CheckParamsAndVirtualise(all, virtualised, request);
                });

                var dataChanged = _source.Synchronize(locker).Select(changes => Virtualise(all, virtualised, parameters, changes));

                // TODO: Remove this shared state stuff ie. _parameters
                return requestStream.Merge(dataChanged).Where(changes => changes is not null && changes.Count != 0)
                .Select(x => x !)
                .Select(changes => new VirtualChangeSet <T>(changes, new VirtualResponse(virtualised.Count, parameters.StartIndex, all.Count))).SubscribeSafe(observer);
            }));
        }
Example #3
0
        private void Requery(Func<T, bool> predicate, List<ItemWithMatch> all, ChangeAwareList<ItemWithMatch> filtered)
        {
            var mutatedMatches = new List<Action>(all.Count);

            var newState = all.Select(item =>
            {
                var match = predicate(item.Item);
                var wasMatch = item.IsMatch;

                //Mutate match - defer until filtered list has been modified
                //[to prevent potential IndexOf failures]
                if (item.IsMatch != match)
                    mutatedMatches.Add(()=> item.IsMatch = match);

                return new
                {
                    Item = item,
                    IsMatch = match,
                    WasMatch = wasMatch
                };
            }).ToList();

            //reflect items which are no longer matched
            var noLongerMatched = newState.Where(state => !state.IsMatch && state.WasMatch).Select(state => state.Item);
            filtered.RemoveMany(noLongerMatched);

            //reflect new matches in the list
            var newMatched = newState.Where(state => state.IsMatch && !state.WasMatch).Select(state => state.Item);
            filtered.AddRange(newMatched);

            //finally apply mutations
            mutatedMatches.ForEach(m => m());
        }
Example #4
0
        public IObservable <IChangeSet <T> > Run()
        {
            return(Observable.Create <IChangeSet <T> >(observer =>
            {
                var locker = new object();

                Func <T, bool> predicate = t => false;
                var all = new List <ItemWithMatch>();
                var filtered = new ChangeAwareList <ItemWithMatch>();
                var immutableFilter = _predicate != null;

                IObservable <IChangeSet <ItemWithMatch> > predicateChanged;

                if (immutableFilter)
                {
                    predicateChanged = Observable.Never <IChangeSet <ItemWithMatch> >();
                    predicate = _predicate;
                }
                else
                {
                    predicateChanged = _predicates
                                       .Synchronize(locker)
                                       .Select(newPredicate =>
                    {
                        predicate = newPredicate;
                        return Requery(predicate, all, filtered);
                    });
                }

                /*
                 * Apply the transform operator so 'IsMatch' state can be evaluated and captured one time only
                 * This is to eliminate the need to re-apply the predicate when determining whether an item was previously matched,
                 * which is essential when we have mutable state
                 */

                //Need to get item by index and store it in the transform
                var filteredResult = _source
                                     .Synchronize(locker)
                                     .Transform <T, ItemWithMatch>((t, previous) =>
                {
                    var wasMatch = previous.ConvertOr(p => p.IsMatch, () => false);
                    return new ItemWithMatch(t, predicate(t), wasMatch);
                }, true)
                                     .Select(changes =>
                {
                    //keep track of all changes if filtering on an observable
                    if (!immutableFilter)
                    {
                        all.Clone(changes);
                    }

                    return Process(filtered, changes);
                });

                return predicateChanged.Merge(filteredResult)
                .NotEmpty()
                .Select(changes => changes.Transform(iwm => iwm.Item))             // use convert, not transform
                .SubscribeSafe(observer);
            }));
        }
        /// <summary>
        /// Convert a binding list into an observable change set.
        /// Change set observes list change events.
        /// </summary>
        /// <typeparam name="TCollection">The collection type.</typeparam>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <param name="source">The source.</param>
        /// <returns>An observable which emits change set values.</returns>
        /// <exception cref="System.ArgumentNullException">source.</exception>
        public static IObservable <IChangeSet <T> > ToObservableChangeSet <TCollection, T>(this TCollection source)
            where TCollection : IBindingList, IEnumerable <T>
        {
            if (source is null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Observable.Create <IChangeSet <T> >(
                       observer =>
            {
                var data = new ChangeAwareList <T>(source);

                if (data.Count > 0)
                {
                    observer.OnNext(data.CaptureChanges());
                }

                return source.ObserveCollectionChanges().Scan(
                    data,
                    (list, args) =>
                {
                    var changes = args.EventArgs;

                    switch (changes.ListChangedType)
                    {
                    case ListChangedType.ItemAdded when source[changes.NewIndex] is T newItem:
                        {
                            list.Add(newItem);
                            break;
                        }
Example #6
0
        private IObservable <IChangeSet <TDestination> > CreateWithChangeset()
        {
            return(Observable.Create <IChangeSet <TDestination> >(observer =>
            {
                var result = new ChangeAwareList <TDestination>();

                var transformed = _source.Transform(t =>
                {
                    var locker = new object();
                    var collection = _manyselector(t);
                    var changes = _childChanges(t).Synchronize(locker).Skip(1);
                    return new ManyContainer(collection, changes);
                })
                                  .Publish();

                var outerLock = new object();
                var intial = transformed
                             .Synchronize(outerLock)
                             .Select(changes => new ChangeSet <TDestination>(new DestinationEnumerator(changes, _equalityComparer)));

                var subsequent = transformed
                                 .MergeMany(x => x.Changes)
                                 .Synchronize(outerLock);

                var allChanges = intial.Merge(subsequent).Select(changes =>
                {
                    result.Clone(changes);
                    return result.CaptureChanges();
                });

                return new CompositeDisposable(allChanges.SubscribeSafe(observer), transformed.Connect());
            }));
        }
        public IObservable <IChangeSet <TDestination> > Run()
        {
            if (_childChanges != null)
            {
                return(CreateWithChangeset());
            }

            return(Observable.Create <IChangeSet <TDestination> >(observer =>
            {
                //NB: ChangeAwareList is used internally by dd to capture changes to a list and ensure they can be replayed by subsequent operators
                var result = new ChangeAwareList <TDestination>();

                return _source.Transform(item => new ManyContainer(_manyselector(item).ToArray()), true)
                .Select(changes =>
                {
                    var destinationChanges = new ChangeSet <TDestination>(new DestinationEnumerator(changes, _equalityComparer));
                    result.Clone(destinationChanges, _equalityComparer);
                    return result.CaptureChanges();
                })

                .NotEmpty()
                .SubscribeSafe(observer);
            }
                                                                  ));
        }
Example #8
0
        public IObservable <IChangeSet <T> > Run()
        {
            return(Observable.Create <IChangeSet <T> >(
                       observer =>
            {
                var locker = new object();
                var original = new List <T>();
                var target = new ChangeAwareList <T>();

                var changed = _source.Synchronize(locker).Select(
                    changes =>
                {
                    if (_resetThreshold > 1)
                    {
                        original.Clone(changes);
                    }

                    return changes.TotalChanges > _resetThreshold ? Reset(original, target) : Process(target, changes);
                });
                var resort = _resort.Synchronize(locker).Select(_ => Reorder(target));
                var changeComparer = _comparerObservable.Synchronize(locker).Select(comparer => ChangeComparer(target, comparer));

                return changed.Merge(resort).Merge(changeComparer).Where(changes => changes.Count != 0).SubscribeSafe(observer);
            }));
        }
Example #9
0
        public IObservable <IChangeSet <IGroup <TObject, TGroupKey> > > Run()
        {
            return(Observable.Create <IChangeSet <IGroup <TObject, TGroupKey> > >(
                       observer =>
            {
                var groupings = new ChangeAwareList <IGroup <TObject, TGroupKey> >();
                var groupCache = new Dictionary <TGroupKey, Group <TObject, TGroupKey> >();

                // capture the grouping up front which has the benefit that the group key is only selected once
                var itemsWithGroup = _source.Transform <TObject, ItemWithGroupKey>((t, previous) => new ItemWithGroupKey(t, _groupSelector(t), previous.Convert(p => p.Group)), true);

                var locker = new object();
                var shared = itemsWithGroup.Synchronize(locker).Publish();

                var grouper = shared.Select(changes => Process(groupings, groupCache, changes));

                IObservable <IChangeSet <IGroup <TObject, TGroupKey> > > regrouper = _regrouper is null ?
                                                                                     Observable.Never <IChangeSet <IGroup <TObject, TGroupKey> > >() :
                                                                                     _regrouper.Synchronize(locker).CombineLatest(shared.ToCollection(), (_, collection) => Regroup(groupings, groupCache, collection));

                var publisher = grouper.Merge(regrouper).DisposeMany()         // dispose removes as the grouping is disposable
                                .NotEmpty().SubscribeSafe(observer);

                return new CompositeDisposable(publisher, shared.Connect());
            }));
        }
Example #10
0
        private IChangeSet <IGrouping <TObject, TGroupKey> > CreateChangeSet(ChangeAwareList <IGrouping <TObject, TGroupKey> > result, IDictionary <TGroupKey, GroupContainer> allGroupings, IDictionary <TGroupKey, IGrouping <TObject, TGroupKey> > initialStateOfGroups)
        {
            //Now maintain target list
            foreach (var intialGroup in initialStateOfGroups)
            {
                var key     = intialGroup.Key;
                var current = allGroupings[intialGroup.Key];

                if (current.List.Count == 0)
                {
                    //remove if empty
                    allGroupings.Remove(key);
                    result.Remove(intialGroup.Value);
                }
                else
                {
                    var currentState = GetGroupState(current);
                    if (intialGroup.Value.Count == 0)
                    {
                        //an add
                        result.Add(currentState);
                    }
                    else
                    {
                        //a replace (or add if the old group has already been removed)
                        result.Replace(intialGroup.Value, currentState);
                    }
                }
            }
            return(result.CaptureChanges());
        }
Example #11
0
        public IObservable <IPageChangeSet <T> > Run()
        {
            return(Observable.Create <IPageChangeSet <T> >(observer =>
            {
                var locker = new object();
                var all = new List <T>();
                var paged = new ChangeAwareList <T>();

                IPageRequest parameters = new PageRequest(0, 25);

                var requestStream = _requests
                                    .Synchronize(locker)
                                    .Select(request =>
                {
                    parameters = request;
                    return CheckParametersAndPage(all, paged, request);
                });

                var datachanged = _source
                                  .Synchronize(locker)
                                  .Select(changes => Page(all, paged, parameters, changes));

                return requestStream.Merge(datachanged)
                .Where(changes => changes != null && changes.Count != 0)
                .SubscribeSafe(observer);
            }));
        }
Example #12
0
        private void Process(ChangeAwareList <T> filtered, IChangeSet <T> changes)
        {
            foreach (var item in changes)
            {
                switch (item.Reason)
                {
                case ListChangeReason.Add:
                {
                    var change = item.Item;
                    if (_predicate(change.Current))
                    {
                        filtered.Add(change.Current);
                    }

                    break;
                }

                case ListChangeReason.AddRange:
                {
                    var matches = item.Range.Where(t => _predicate(t)).ToList();
                    filtered.AddRange(matches);
                    break;
                }

                case ListChangeReason.Replace:
                {
                    var change = item.Item;
                    var match  = _predicate(change.Current);
                    if (match)
                    {
                        filtered.ReplaceOrAdd(change.Previous.Value, change.Current);
                    }
                    else
                    {
                        filtered.Remove(change.Previous.Value);
                    }

                    break;
                }

                case ListChangeReason.Remove:
                {
                    filtered.Remove(item.Item.Current);
                    break;
                }

                case ListChangeReason.RemoveRange:
                {
                    filtered.RemoveMany(item.Range);
                    break;
                }

                case ListChangeReason.Clear:
                {
                    filtered.ClearOrRemoveMany(item);
                    break;
                }
                }
            }
        }
Example #13
0
        public IObservable <IChangeSet <List.IGrouping <TObject, TGroupKey> > > Run()
        {
            return(Observable.Create <IChangeSet <IGrouping <TObject, TGroupKey> > >(observer =>
            {
                var groupings = new ChangeAwareList <IGrouping <TObject, TGroupKey> >();
                var groupCache = new Dictionary <TGroupKey, GroupContainer>();

                var itemsWithGroup = _source
                                     .Transform(t => new ItemWithValue <TObject, TGroupKey>(t, _groupSelector(t)));

                var locker = new object();
                var shared = itemsWithGroup.Synchronize(locker).Publish();

                var grouper = shared
                              .Select(changes => Process(groupings, groupCache, changes));

                IObservable <IChangeSet <IGrouping <TObject, TGroupKey> > > regrouper;
                if (_regrouper == null)
                {
                    regrouper = Observable.Never <IChangeSet <IGrouping <TObject, TGroupKey> > >();
                }
                else
                {
                    regrouper = _regrouper.Synchronize(locker)
                                .CombineLatest(shared.ToCollection(), (_, collection) => Regroup(groupings, groupCache, collection));
                }

                var publisher = grouper.Merge(regrouper)
                                .NotEmpty()
                                .SubscribeSafe(observer);

                return new CompositeDisposable(publisher, shared.Connect());
            }));
        }
        public IObservable <IChangeSet <T> > Run()
        {
            return(Observable.Create <IChangeSet <T> >(observer =>
            {
                long orderItemWasAdded = -1;
                var locker = new object();

                var sourceList = new ChangeAwareList <ExpirableItem <T> >();

                var sizeLimited = _source.Synchronize(locker)
                                  .Scan(sourceList, (state, latest) =>
                {
                    var items = latest.AsArray();
                    var expirable = items.Select(t => CreateExpirableItem(t, ref orderItemWasAdded));

                    if (items.Length == 1)
                    {
                        sourceList.Add(expirable);
                    }
                    else
                    {
                        sourceList.AddRange(expirable);
                    }

                    if (_limitSizeTo > 0 && state.Count > _limitSizeTo)
                    {
                        //remove oldest items [these will always be the first x in the list]
                        var toRemove = state.Count - _limitSizeTo;
                        state.RemoveRange(0, toRemove);
                    }
                    return state;
                })
                                  .Select(state => state.CaptureChanges())
                                  .Publish();

                var timeLimited = (_expireAfter == null ? Observable.Never <IChangeSet <ExpirableItem <T> > >() : sizeLimited)
                                  .Filter(ei => ei.ExpireAt != DateTime.MaxValue)
                                  .GroupWithImmutableState(ei => ei.ExpireAt)
                                  .MergeMany(grouping =>
                {
                    var expireAt = grouping.Key.Subtract(_scheduler.Now.DateTime);
                    return Observable.Timer(expireAt, _scheduler).Select(_ => grouping);
                })
                                  .Synchronize(locker)
                                  .Select(grouping =>
                {
                    sourceList.RemoveMany(grouping.Items);
                    return sourceList.CaptureChanges();
                });

                var publisher = sizeLimited
                                .Merge(timeLimited)
                                .Cast(ei => ei.Item)
                                .NotEmpty()
                                .SubscribeSafe(observer);

                return new CompositeDisposable(publisher, sizeLimited.Connect());
            }));
        }
Example #15
0
        private IChangeSet <T> Reset(List <T> original, ChangeAwareList <T> target)
        {
            var sorted = original.OrderBy(t => t, _comparer).ToList();

            target.Clear();
            target.AddRange(sorted);
            return(target.CaptureChanges());
        }
Example #16
0
        private static IChangeSet <T>?CheckParamsAndVirtualise(IList <T> all, ChangeAwareList <T> virtualised, IVirtualRequest?request)
        {
            if (request is null || request.StartIndex < 0 || request.Size < 1)
            {
                return(null);
            }

            return(Virtualise(all, virtualised, request));
        }
Example #17
0
        private PageChangeSet <T> CheckParametersAndPage(List <T> all, ChangeAwareList <T> paged, IPageRequest request)
        {
            if (request == null || request.Page < 0 || request.Size < 1)
            {
                return(null);
            }

            return(Page(all, paged, request));
        }
Example #18
0
        private IChangeSet <T> ChangeComparer(ChangeAwareList <T> target, IComparer <T> comparer)
        {
            _comparer = comparer;
            var sorted = target.OrderBy(t => t, _comparer).ToList();

            target.Clear();
            target.AddRange(sorted);
            return(target.CaptureChanges());
        }
Example #19
0
        /// <summary>
        /// Convert a binding list into an observable change set
        /// </summary>
        /// <typeparam name="T">The type of the object.</typeparam>
        /// <typeparam name="TCollection"></typeparam>
        /// <param name="source">The source.</param>
        /// <returns></returns>
        /// <exception cref="System.ArgumentNullException">source</exception>
        public static IObservable <IChangeSet <T> > ToObservableChangeSet <TCollection, T>(this TCollection source)
            where TCollection : IBindingList, IEnumerable <T>
        {
            if (source == null)
            {
                throw new ArgumentNullException(nameof(source));
            }

            return(Observable.Create <IChangeSet <T> >(observer =>
            {
                var data = new ChangeAwareList <T>(source);

                if (data.Count > 0)
                {
                    observer.OnNext(data.CaptureChanges());
                }

                return source.ObserveCollectionChanges()
                .Scan(data, (list, args) =>
                {
                    var changes = args.EventArgs;

                    switch (changes.ListChangedType)
                    {
                    case ListChangedType.ItemAdded:
                        {
                            list.Add((T)source[changes.NewIndex]);
                            break;
                        }

                    case ListChangedType.ItemDeleted:
                        {
                            list.RemoveAt(changes.NewIndex);
                            break;
                        }

                    case ListChangedType.ItemChanged:
                        {
                            list[changes.NewIndex] = (T)source[changes.NewIndex];
                            break;
                        }

                    case ListChangedType.Reset:
                        {
                            list.Clear();
                            list.AddRange(source);
                            break;
                        }
                    }

                    return list;
                })
                .Select(list => list.CaptureChanges())
                .SubscribeSafe(observer);
            }));
        }
Example #20
0
        private int GetCurrentPosition(ChangeAwareList <T> target, T item)
        {
            var index = _sortOptions == SortOptions.UseBinarySearch ? target.BinarySearch(item, _comparer) : target.IndexOf(item);

            if (index < 0)
            {
                throw new SortException($"Cannot find item: {typeof(T).Name} -> {item}");
            }

            return(index);
        }
Example #21
0
 private int GetInsertPositionLinear(ChangeAwareList <T> target, T item)
 {
     for (var i = 0; i < target.Count; i++)
     {
         if (_comparer.Compare(item, target[i]) < 0)
         {
             return(i);
         }
     }
     return(target.Count);
 }
Example #22
0
        private void Requery(Func <T, bool> predicate, List <ItemWithMatch> all, ChangeAwareList <ItemWithMatch> filtered)
        {
            if (_policy == ListFilterPolicy.ClearAndReplace)
            {
                var newMatches = all.Where(iwm => predicate(iwm.Item)).ToList();

                //mark items as matched?
                filtered.Clear();
                filtered.AddRange(newMatches);

                //reset state
                all.Where(iwm => iwm.IsMatch).ForEach(iwm => iwm.IsMatch = false);
                newMatches.ForEach(iwm => iwm.IsMatch = true);

                return;
            }


            var mutatedMatches = new List <Action>(all.Count);

            var newState = all.Select(item =>
            {
                var match    = predicate(item.Item);
                var wasMatch = item.IsMatch;

                //Mutate match - defer until filtered list has been modified
                //[to prevent potential IndexOf failures]
                if (item.IsMatch != match)
                {
                    mutatedMatches.Add(() => item.IsMatch = match);
                }

                return(new
                {
                    Item = item,
                    IsMatch = match,
                    WasMatch = wasMatch
                });
            }).ToList();

            //reflect items which are no longer matched
            var noLongerMatched = newState.Where(state => !state.IsMatch && state.WasMatch).Select(state => state.Item);

            filtered.RemoveMany(noLongerMatched);

            //reflect new matches in the list
            var newMatched = newState.Where(state => state.IsMatch && !state.WasMatch).Select(state => state.Item);

            filtered.AddRange(newMatched);

            //finally apply mutations
            mutatedMatches.ForEach(m => m());
        }
Example #23
0
        private IChangeSet <T> Process(ChangeAwareList <T> target, IChangeSet <T> changes)
        {
            // if all removes and not Clear, then more efficient to try clear range
            if (changes.TotalChanges == changes.Removes && changes.All(c => c.Reason != ListChangeReason.Clear) && changes.Removes > 1)
            {
                var removed = changes.Unified().Select(u => u.Current);
                target.RemoveMany(removed);
                return(target.CaptureChanges());
            }

            return(ProcessImpl(target, changes));
        }
Example #24
0
        private int GetInsertPositionBinary(ChangeAwareList <T> target, T item)
        {
            int index       = target.BinarySearch(item, _comparer);
            int insertIndex = ~index;

            //sort is not returning uniqueness
            if (insertIndex < 0)
            {
                throw new SortException("Binary search has been specified, yet the sort does not yeild uniqueness");
            }
            return(insertIndex);
        }
Example #25
0
        public IObservable <IChangeSet <TValue> > Run()
        {
            return(Observable.Create <IChangeSet <TValue> >(
                       observer =>
            {
                var valueCounters = new Dictionary <TValue, int>();
                var result = new ChangeAwareList <TValue>();

                return _source.Transform <T, ItemWithMatch>(
                    (t, previous, _) =>
                {
                    var previousValue = previous.ConvertOr(p => p is null ? default : p.Value, () => default);
Example #26
0
        private static IChangeSet <T> Virtualise(List <T> all, ChangeAwareList <T> virtualised, IVirtualRequest request, IChangeSet <T> changeset = null)
        {
            if (changeset != null)
            {
                all.Clone(changeset);
            }

            var previous = virtualised;

            var current = all.Skip(request.StartIndex)
                          .Take(request.Size)
                          .ToList();

            var adds    = current.Except(previous);
            var removes = previous.Except(current);

            virtualised.RemoveMany(removes);

            adds.ForEach(t =>
            {
                var index = current.IndexOf(t);
                virtualised.Insert(index, t);
            });

            var moves = changeset.EmptyIfNull()
                        .Where(change => change.Reason == ListChangeReason.Moved &&
                               change.MovedWithinRange(request.StartIndex, request.StartIndex + request.Size));

            foreach (var change in moves)
            {
                //check whether an item has moved within the same page
                var currentIndex  = change.Item.CurrentIndex - request.StartIndex;
                var previousIndex = change.Item.PreviousIndex - request.StartIndex;
                virtualised.Move(previousIndex, currentIndex);
            }

            //find replaces [Is this ever the case that it can be reached]
            for (var i = 0; i < current.Count; i++)
            {
                var currentItem  = current[i];
                var previousItem = previous[i];

                if (ReferenceEquals(currentItem, previousItem))
                {
                    continue;
                }

                var index = virtualised.IndexOf(currentItem);
                virtualised.Move(i, index);
            }

            return(virtualised.CaptureChanges());
        }
Example #27
0
        public IObservable <IChangeSet <TValue> > Run()
        {
            return(Observable.Create <IChangeSet <TValue> >(observer =>
            {
                var valueCounters = new Dictionary <TValue, int>();
                var result = new ChangeAwareList <TValue>();

                return _source.Transform(t => new ItemWithValue <T, TValue>(t, _valueSelector(t)))
                .Select(changes => Process(valueCounters, result, changes))
                .NotEmpty()
                .SubscribeSafe(observer);
            }));
        }
Example #28
0
        private int GetCurrentPosition(ChangeAwareList <T> target, T item)
        {
            int index = _sortOptions == SortOptions.UseBinarySearch
                ? target.BinarySearch(item, _comparer)
                : target.IndexOf(item);

            if (index < 0)
            {
                throw new SortException("Current item cannot be found");
            }

            return(index);
        }
Example #29
0
        private IChangeSet <T> ChangeComparer(ChangeAwareList <T> target, IComparer <T> comparer)
        {
            _comparer = comparer;
            if (_resetThreshold > 0 && target.Count <= _resetThreshold)
            {
                return(Reorder(target));
            }

            var sorted = target.OrderBy(t => t, _comparer).ToList();

            target.Clear();
            target.AddRange(sorted);
            return(target.CaptureChanges());
        }
Example #30
0
        public IObservable <IChangeSet <TValue> > Run()
        {
            return(Observable.Create <IChangeSet <TValue> >(observer =>
            {
                var valueCounters = new Dictionary <TValue, int>();
                var result = new ChangeAwareList <TValue>();

                return _source.Transform <T, ItemWithMatch>((t, previous, idx) =>
                {
                    var previousValue = previous.ConvertOr(p => p.Value, () => default(TValue));

                    return new ItemWithMatch(t, _valueSelector(t), previousValue);
                }, true)
                .Select(changes => Process(valueCounters, result, changes))
                .NotEmpty()
                .SubscribeSafe(observer);
            }));
        }
        public void Setup()
        {
            _source = new ChangeAwareList<int>();
            _clone = new List<int>();

        }
 public void Setup()
 {
     _list = new ChangeAwareList<int>();
 }