Ejemplo n.º 1
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
                            }
                        }
                    }
                }