Пример #1
0
        public virtual GroupCollection <T> Perform(
            IReadOnlyCollection <T> items,
            int level,
            Group <T> parent)
        {
            GroupDescriptorCollection groupDescriptors = this.index.CollectionView.GroupDescriptors;

            if (level >= groupDescriptors.Count)
            {
                return(GroupCollection <T> .Empty);
            }
            IGroupFactory <T>   groupFactory = this.index.CollectionView.GroupFactory;
            GroupCollection <T> cachedGroups = this.GetCachedGroups(items, level);

            if (!GroupBuilder <T> .IsValid(level, groupDescriptors))
            {
                cachedGroups?.Dispose();
                return(groupFactory.CreateCollection((IList <Group <T> >)GroupBuilder <T> .Empty));
            }
            IComparer <Group <T> > comparer = Activator.CreateInstance(this.Comparer.GetType()) as IComparer <Group <T> > ?? this.Comparer;

            if (comparer is GroupComparer <T> )
            {
                ((GroupComparer <T>)comparer).Directions = this.GetComparerDirections(level);
            }
            AvlTree <Group <T> > avlTree1 = new AvlTree <Group <T> >(comparer);
            AvlTree <Group <T> > avlTree2 = new AvlTree <Group <T> >((IComparer <Group <T> >) new GroupComparer <T>(this.GetComparerDirections(level)));

            foreach (T key1 in !this.CollectionView.CanPage || level != 0 || !this.CollectionView.PagingBeforeGrouping ? (IEnumerable <T>)items : (IEnumerable <T>) this.index.GetItemsOnPage(this.CollectionView.PageIndex))
            {
                object    key2   = this.GroupPredicate(key1, level);
                Group <T> group1 = (Group <T>) new DataItemGroup <T>(key2);
                Group <T> group2 = avlTree2.Find(group1);
                if (group2 == null)
                {
                    group2 = this.GetGroup(cachedGroups, group1, parent, key2, level);
                    avlTree2.Add(group2);
                }
                group2.Items.Add(key1);
                if (this.itemGroupsCache.ContainsKey(key1))
                {
                    this.itemGroupsCache[key1] = group2;
                }
                else
                {
                    this.itemGroupsCache.Add(key1, group2);
                }
            }
            for (int index = 0; index < avlTree2.Count; ++index)
            {
                avlTree1.Add(avlTree2[index]);
            }
            cachedGroups?.Dispose();
            return(groupFactory.CreateCollection((IList <Group <T> >)avlTree1));
        }
Пример #2
0
        /// <summary>
        /// Performs the grouping operation for specified items.
        /// </summary>
        /// <param name="items">The items.</param>
        /// <param name="level">The level.</param>
        /// <param name="parent">The parent.</param>
        /// <returns></returns>
        public virtual GroupCollection <T> Perform(IReadOnlyCollection <T> items, int level, Group <T> parent)
        {
            GroupDescriptorCollection groupDescriptors = this.index.CollectionView.GroupDescriptors;

            if (level >= groupDescriptors.Count)
            {
                return(GroupCollection <T> .Empty);
            }
            IGroupFactory <T> groupFactory = this.index.CollectionView.GroupFactory;

            GroupCollection <T> cache = GetCachedGroups(items, level);

            if (!IsValid(level, groupDescriptors))
            {
                if (cache != null)
                {
                    cache.Dispose();
                }
                return(this.index.CollectionView.GroupFactory.CreateCollection(GroupBuilder <T> .Empty));
            }

            IComparer <Group <T> > newComparer = Activator.CreateInstance(this.Comparer.GetType()) as IComparer <Group <T> >;

            if (newComparer == null)
            {
                newComparer = this.Comparer;
            }
            if (newComparer is GroupComparer <T> )
            {
                ((GroupComparer <T>)newComparer).Directions = this.GetComparerDirections(level);
            }

            AvlTree <Group <T> > groupList = new AvlTree <Group <T> >(newComparer);
            AvlTree <Group <T> > list      = new AvlTree <Group <T> >(new GroupComparer <T>(this.GetComparerDirections(level)));

            foreach (T item in items)
            {
                object    key = this.GroupPredicate(item, level);
                Group <T> group, newGroup = new DataItemGroup <T>(key);
                group = list.Find(newGroup); groupList.Find(newGroup);
                if (group == null)
                {
                    group = GroupBuilder <T> .GetCachedGroup(cache, newGroup);

                    if (group == null)
                    {
                        group = groupFactory.CreateGroup(key, parent);
                        DataItemGroup <T> dataGroup = group as DataItemGroup <T>;
                        dataGroup.GroupBuilder = this;
                    }

                    list.Add(group);// groupList.Add(group);
                }

                group.Items.Add(item);
            }

            for (int i = 0; i < list.Count; i++)
            {
                groupList.Add(list[i]);
            }

            if (cache != null)
            {
                cache.Dispose();
            }

            return(groupFactory.CreateCollection(groupList));
        }