예제 #1
0
                public ICommitContext Fill(IValueSource valueSource, Func <IValueSource, MappedObjectKeys> getKeyFunction, Func <T> createObject)
                {
                    lock (_cache)
                    {
                        Init(true);

                        CommitContext commitContext = new CommitContext(this);
                        while (valueSource.Next())
                        {
                            MappedObjectKeys keys = getKeyFunction(valueSource);
                            if (_cache._itemsByKey.ContainsKey(keys))
                            {
                                IFillAbleObject item = _cache._itemsByKey[keys].Value;
                                if (item == null)
                                {
                                    _cache._itemsByKey[keys] = new WeakReference <IFillAbleObject>(item = (IFillAbleObject)createObject());
                                    ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged += _cache.EntryValuePropertyChanged;
                                }
                                item.Fill(valueSource);
                                commitContext.AddEntryToCommit((T)item);
                            }
                            else
                            {
                                IFillAbleObject newObject = (IFillAbleObject)createObject();
                                newObject.Fill(valueSource);
                                _cache._itemsByKey.Add(keys, new WeakReference <IFillAbleObject>(newObject));
                                commitContext.AddEntryToCommit((T)newObject);
                                ((System.ComponentModel.INotifyPropertyChanged)newObject).PropertyChanged += _cache.EntryValuePropertyChanged;
                            }
                        }

                        return(commitContext);
                    }
                }
예제 #2
0
                private void AppendEntry(T item)
                {
                    Init(false);
                    IFillAbleObject fillableObject = (IFillAbleObject)item;

                    if (fillableObject.State == State.Deleted)
                    {
                        lock (_deletedItems)
                        {
                            if (_deletedItems.Contains(item))
                            {
                                return;
                            }

                            _deletedItems.Add(item);
                        }
                        ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged += ItemsNotifyPropertyChanged;
                    }
                    else
                    {
                        lock (_items)
                        {
                            if (_items.Contains(item))
                            {
                                return;
                            }

                            ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged += ItemsNotifyPropertyChanged;
                            if (_context.OrderExpressions == null || _context.OrderExpressions.Count == 0)
                            {
                                InsertAt(_items.Count, item);
                            }
                            else
                            {
                                #region Ordered Insert
                                if (_items.Count == 0)
                                {
                                    InsertAt(0, item);
                                    _expectedNextInsertIndex = 1;
                                }
                                else if (
                                    (_items.Count == _expectedNextInsertIndex && _context.Compare(item, _items[_expectedNextInsertIndex - 1]) >= 0) ||
                                    (_expectedNextInsertIndex == 0 && _context.Compare(item, _items[0]) <= 0) ||
                                    (_expectedNextInsertIndex < _items.Count && _expectedNextInsertIndex > 0 &&
                                     _context.Compare(item, _items[_expectedNextInsertIndex]) <= 0 &&
                                     _context.Compare(item, _items[_expectedNextInsertIndex - 1]) >= 0)
                                    )
                                {
                                    InsertAt(_expectedNextInsertIndex++, item);
                                }
                                else
                                {
                                    void binarySearch(int min, int max)
                                    {
                                        int spread = max - min;

                                        if (spread == 0)
                                        {
                                            InsertAt(_expectedNextInsertIndex = (_context.Compare(item, _items[min]) < 0 ? min : ++min), item);
                                        }
                                        else if (spread == 1)
                                        {
                                            InsertAt(_expectedNextInsertIndex = (_context.Compare(item, _items[min]) < 0 ? min : _context.Compare(item, _items[max]) < 0 ? max : ++max), item);
                                        }
                                        else
                                        {
                                            int mid     = min + (spread / 2);
                                            int compare = _context.Compare(item, _items[mid]);
                                            if (compare == 0)
                                            {
                                                InsertAt(_expectedNextInsertIndex = mid, item);
                                            }
                                            else if (compare > 0)
                                            {
                                                binarySearch(mid, max);
                                            }
                                            else
                                            {
                                                binarySearch(min, mid);
                                            }
                                        }
                                    }

                                    binarySearch(0, _items.Count - 1);
                                }
                                #endregion
                            }
                        }
                    }
                }
예제 #3
0
                public void ReportEntryValueChanged(IFillAbleObject item)
                {
                    if (_disableReportEntryValueChanged)
                    {
                        return;
                    }

                    Init(false);

                    T    obj = (T)item;
                    bool match;

                    try
                    {
                        match = _context.GetPredicateCompiled()(obj);
                    }
#if DEBUG && !NETCOREAPP1_0
                    catch (Exception ex)
                    {
                        if (!_isWeakCacheExceptionSent)
                        {
                            _isWeakCacheExceptionSent = true;
                            System.Diagnostics.Trace.TraceError("Error while evaluating Predicate in PropertyChanged event. Predicate: {0}\nException:\n{1}", _context.GetPredicate(), ex);
                        }
                        else
                        {
                            throw;
                        }
#else
                    catch
                    {
#endif
                        match = false;
                    }
                    bool contains = item.State == State.Deleted ? _deletedItems.Contains(obj) : _items.Contains(obj);
                    if (match && !contains)
                    {
                        AppendEntry(obj);
                    }
                    else if (!match && contains)
                    {
                        if (((IFillAbleObject)item).State == State.Deleted)
                        {
                            if (_deletedItems.Remove(obj))
                            {
                                ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged -= ItemsNotifyPropertyChanged;
                            }
                            return;
                        }
                        else
                        {
                            int index = _items.IndexOf(obj);
                            if (index == -1)
                            {
                                return;
                            }

                            _items.RemoveAt(index);
                            ((System.ComponentModel.INotifyPropertyChanged)item).PropertyChanged -= ItemsNotifyPropertyChanged;
                            OnCollectionChanged(new System.Collections.Specialized.NotifyCollectionChangedEventArgs(System.Collections.Specialized.NotifyCollectionChangedAction.Remove, item, index));
                        }
                    }
                }