public void TestCompositeAggregator()
        {
            IEntryAggregator agg1 = CompositeAggregator.CreateInstance(
                new IEntryAggregator[] { GroupAggregator.CreateInstance(IdentityExtractor.Instance,
                                                                        new Count()),
                                         new LongMax((IdentityExtractor.Instance)) });
            ArrayList al = new ArrayList();

            al.Add(new TestInvocableCacheEntry("key1", 173));
            al.Add(new TestInvocableCacheEntry("key2", 173));
            al.Add(new TestInvocableCacheEntry("key3", 185));
            al.Add(new TestInvocableCacheEntry("key4", 164));
            al.Add(new TestInvocableCacheEntry("key5", 164));
            al.Add(new TestInvocableCacheEntry("key6", 164));
            object result = agg1.Aggregate(al);

            if (result is IList)
            {
                IDictionary results = (IDictionary)((IList)result)[0];

                Assert.AreEqual(results[185], 1);
                Assert.AreEqual(results[164], 3);

                Assert.AreEqual(((IList)result)[1], 185);
            }

            // aggragation on remote cache
            INamedCache cache = CacheFactory.GetCache(CacheName);

            cache.Clear();

            HashDictionary hd = new HashDictionary();

            hd.Add("Key1", 435);
            hd.Add("Key2", 253);
            hd.Add("Key3", 435);
            hd.Add("Key4", 435);
            hd.Add(null, -3);
            cache.InsertAll(hd);

            IEntryAggregator aggregator = CompositeAggregator.CreateInstance(
                new IEntryAggregator[] { GroupAggregator.CreateInstance(IdentityExtractor.Instance,
                                                                        new Count()),
                                         new LongMax((IdentityExtractor.Instance)) });

            result = cache.Aggregate(cache.Keys, aggregator);

            if (result is IList)
            {
                IDictionary results = (IDictionary)((IList)result)[0];

                Assert.AreEqual(results[435], 3);
                Assert.AreEqual(results[-3], 1);

                Assert.AreEqual(((IList)result)[1], 435);
            }

            CacheFactory.Shutdown();
        }
예제 #2
0
        /// <summary>
        /// Construct a GroupAggregator based on a specified
        /// <see cref="IValueExtractor"/> and underlying
        /// <see cref="IEntryAggregator"/>.
        /// </summary>
        /// <param name="extractor">
        /// An <b>IValueExtractor</b> object that is used to split
        /// <see cref="IInvocableCache"/> entries into
        /// non-intersecting subsets; may not be <c>null</c>.
        /// </param>
        /// <param name="aggregator">
        /// An <b>IEntryAggregator</b> object; may not be <c>null</c>.
        /// </param>
        /// <param name="filter">
        /// An optional <see cref="IFilter"/> object used to filter out
        /// results of individual group aggregation results.
        /// </param>
        protected GroupAggregator(IValueExtractor extractor, IEntryAggregator aggregator, IFilter filter)
        {
            Debug.Assert(extractor != null && aggregator != null);

            m_extractor  = extractor;
            m_aggregator = aggregator;
            m_filter     = filter;
        }
예제 #3
0
        /// <summary>
        /// Create an instance of GroupAggregator based on a specified member
        /// name(s), an <see cref="IEntryAggregator"/> and a result
        /// evaluation filter.
        /// </summary>
        /// <remarks>
        /// If the specified underlying aggregator is an instance of
        /// <see cref="IParallelAwareAggregator"/>, then a parallel-aware
        /// instance of the GroupAggregator will be created. Otherwise, the
        /// resulting GroupAggregator will not be parallel-aware and could be
        /// ill-suited for aggregations run against large partitioned caches.
        /// </remarks>
        /// <param name="member">
        /// A member name or a comma-delimited sequence of names that results
        /// in a <see cref="ReflectionExtractor"/> or a
        /// <see cref="MultiExtractor"/> that will be used to split
        /// <see cref="IInvocableCache"/> entries into distinct groups.
        /// </param>
        /// <param name="aggregator">
        /// An underlying <b>IEntryAggregator</b>.
        /// </param>
        /// <param name="filter">
        /// An optional <b>IFilter</b> object that will be used to evaluate
        /// results of each individual group aggregation.
        /// </param>
        /// <returns>
        /// An instance of GroupAggregator based on a specified member
        /// name(s), an <see cref="IEntryAggregator"/> and a result
        /// evaluation filter.
        /// </returns>
        public static GroupAggregator CreateInstance(string member, IEntryAggregator aggregator, IFilter filter)
        {
            IValueExtractor extractor = member.IndexOf(',') >= 0
                                            ? new MultiExtractor(member)
                                            : member.IndexOf('.') >= 0
                                                  ? new ChainedExtractor(member)
                                                  : (IValueExtractor) new ReflectionExtractor(member);

            return(CreateInstance(extractor, aggregator, filter));
        }
예제 #4
0
        /// <summary>
        /// Process a collection of <see cref="IInvocableCacheEntry"/>
        /// objects using the underlying extractor to split the entries
        /// into non-intersecting (distinct) groups and then apply the
        /// underlying aggregator separately to each group.
        /// </summary>
        /// <param name="entries">
        /// A collection of read-only <b>IInvocableCacheEntry</b>
        /// objects to aggregate.
        /// </param>
        /// <returns>
        /// A dictionary that has the unique tuples as keys and results of
        /// the corresponding subset aggregation as values.
        /// </returns>
        public virtual object Aggregate(ICollection entries)
        {
            IValueExtractor  extractor  = m_extractor;
            IEntryAggregator aggregator = m_aggregator;
            IFilter          filter     = m_filter;

            // create non-intersecting groups of entry sets
            IDictionary result = new HashDictionary();

            foreach (IInvocableCacheEntry entry in entries)
            {
                if (entry.IsPresent)
                {
                    // extract a distinct value (or a tuple)
                    object distinct = entry.Extract(extractor);

                    // add the entry to the corresponding group
                    ICollection group = (ICollection)result[distinct];
                    if (group == null)
                    {
                        result.Add(distinct, group = new ArrayList());
                    }
                    CollectionUtils.Add(group, entry);
                }
            }

            // run the aggregation
            IDictionary newResult = new HashDictionary(result);

            foreach (DictionaryEntry entry in result)
            {
                ICollection group = (ICollection)entry.Value;
                object      res   = aggregator.Aggregate(group);
                if (filter == null || filter.Evaluate(res))
                {
                    newResult[entry.Key] = res;
                }
                else
                {
                    newResult.Remove(entry.Key);
                }
            }

            return(newResult);
        }
예제 #5
0
 /// <summary>
 /// Perform an aggregating operation against the collection of
 /// entries that are selected by the given <b>IFilter</b>.
 /// </summary>
 /// <param name="filter">
 /// an <see cref="IFilter"/> that is used to select entries within
 /// this cache to aggregate across.
 /// </param>
 /// <param name="agent">
 /// The <see cref="IEntryAggregator"/> that is used to aggregate
 /// across the selected entries of this cache.
 /// </param>
 /// <returns>
 /// The result of the aggregation.
 /// </returns>
 public virtual object Aggregate(IFilter filter, IEntryAggregator agent)
 {
     return(NamedCache.Aggregate(filter, agent));
 }
예제 #6
0
 /// <summary>
 /// Perform an aggregating operation against the entries specified by
 /// the passed keys.
 /// </summary>
 /// <param name="keys">
 /// The collection of keys that specify the entries within this cache
 /// to aggregate across.
 /// </param>
 /// <param name="agent">
 /// The <see cref="IEntryAggregator"/> that is used to aggregate
 /// across the specified entries of this cache.
 /// </param>
 /// <returns>
 /// The result of the aggregation.
 /// </returns>
 public virtual object Aggregate(ICollection keys, IEntryAggregator agent)
 {
     return(NamedCache.Aggregate(keys, agent));
 }
        public void TestGroupAggregator()
        {
            GroupAggregator agg1 = GroupAggregator.CreateInstance(IdentityExtractor.Instance,
                                                                  new Count());

            Assert.IsNotNull(agg1);
            Assert.AreSame(IdentityExtractor.Instance, agg1.Extractor);
            Assert.IsInstanceOf(typeof(Count), agg1.Aggregator);

            GroupAggregator agg2 = GroupAggregator.CreateInstance(IdentityExtractor.Instance,
                                                                  new Count(),
                                                                  new LessFilter(
                                                                      IdentityExtractor.Instance, 3));

            Assert.IsNotNull(agg2);
            Assert.IsInstanceOf(typeof(IdentityExtractor), agg2.Extractor);

            GroupAggregator agg3 =
                GroupAggregator.CreateInstance("dummy", new Count());

            Assert.IsNotNull(agg3);
            Assert.IsInstanceOf(typeof(ReflectionExtractor), agg3.Extractor);
            agg3 = GroupAggregator.CreateInstance("dummy.test", new Count());
            Assert.IsNotNull(agg3);
            Assert.IsInstanceOf(typeof(ChainedExtractor), agg3.Extractor);
            agg3 = GroupAggregator.CreateInstance("dummy.test1, dummy.test2", new Count());
            Assert.IsNotNull(agg3);
            Assert.IsInstanceOf(typeof(MultiExtractor), agg3.Extractor);

            ArrayList al = new ArrayList();

            al.Add(new TestInvocableCacheEntry("key1", 173));
            al.Add(new TestInvocableCacheEntry("key2", 173));
            al.Add(new TestInvocableCacheEntry("key3", 185));
            al.Add(new TestInvocableCacheEntry("key4", 164));
            al.Add(new TestInvocableCacheEntry("key5", 164));
            al.Add(new TestInvocableCacheEntry("key6", 164));
            object result = agg2.Aggregate(al);

            if (result is IDictionary)
            {
                Assert.AreEqual(((IDictionary)result)[173], 2);
                Assert.AreEqual(((IDictionary)result)[185], 1);
                Assert.AreEqual(((IDictionary)result)[164], null);
            }

            // aggragation on remote cache
            INamedCache cache = CacheFactory.GetCache(CacheName);

            cache.Clear();

            Hashtable ht = new Hashtable();

            ht.Add("Key1", 435);
            ht.Add("Key2", 253);
            ht.Add("Key3", 435);
            ht.Add("Key4", 435);
            ht.Add("Key5", -3);
            cache.InsertAll(ht);

            IEntryAggregator aggregator = GroupAggregator.CreateInstance(IdentityExtractor.Instance,
                                                                         new Count());

            result = cache.Aggregate(cache.Keys, aggregator);
            if (result is IDictionary)
            {
                Assert.AreEqual(((IDictionary)result)[435], 3);
                Assert.AreEqual(((IDictionary)result)[-3], 1);
            }
            CacheFactory.Shutdown();
        }
예제 #8
0
 /// <summary>
 /// Create an instance of GroupAggregator based on a specified
 /// extractor and an <b>IEntryAggregator</b> and a result
 /// evaluation filter.
 /// </summary>
 /// <remarks>
 /// If the specified aggregator is an instance of
 /// <b>IParallelAwareAggregator</b>, then a parallel-aware instance
 /// of the GroupAggregator will be created. Otherwise, the resulting
 /// GroupAggregator will not be parallel-aware and could be
 /// ill-suited for aggregations run against large partitioned caches.
 /// </remarks>
 /// <param name="extractor">
 /// An <b>IValueExtractor</b> that will be used to split a set of
 /// <b>IInvocableDictionary</b> entries into distinct groups.
 /// </param>
 /// <param name="aggregator">
 /// An underlying <b>IEntryAggregator</b>.
 /// </param>
 /// <param name="filter">
 /// An optional <b>IFilter</b> object used to filter out results of
 /// individual group aggregation results.
 /// </param>
 /// <returns>
 /// An instance of GroupAggregator based on a specified
 /// extractor and an <b>IEntryAggregator</b> and a result
 /// evaluation filter.
 /// </returns>
 public static GroupAggregator CreateInstance(IValueExtractor extractor, IEntryAggregator aggregator, IFilter filter)
 {
     return(new GroupAggregator(extractor, aggregator, filter));
 }
예제 #9
0
 /// <summary>
 /// Create an instance of GroupAggregator based on a specified
 /// extractor and an <b>IEntryAggregator</b>.
 /// </summary>
 /// <remarks>
 /// If the specified aggregator is an instance of
 /// <b>IParallelAwareAggregator</b>, then a parallel-aware instance
 /// of the GroupAggregator will be created. Otherwise, the resulting
 /// GroupAggregator will not be parallel-aware and could be
 /// ill-suited for aggregations run against large partitioned caches.
 /// </remarks>
 /// <param name="extractor">
 /// An <b>IValueExtractor</b> that will be used to split a set of
 /// <b>IInvocableDictionary</b> entries into distinct groups.
 /// </param>
 /// <param name="aggregator">
 /// An underlying <b>IEntryAggregator</b>.
 /// </param>
 /// <returns>
 /// An instance of GroupAggregator based on a specified
 /// extractor and an <b>IEntryAggregator</b>.
 /// </returns>
 public static GroupAggregator CreateInstance(IValueExtractor extractor, IEntryAggregator aggregator)
 {
     return(CreateInstance(extractor, aggregator, null));
 }
예제 #10
0
 /// <summary>
 /// Create an instance of GroupAggregator based on a specified member
 /// name(s) and an <see cref="IEntryAggregator"/>.
 /// </summary>
 /// <remarks>
 /// If the specified underlying aggregator is an instance of
 /// <see cref="IParallelAwareAggregator"/>, then a parallel-aware
 /// instance of the GroupAggregator will be created. Otherwise, the
 /// resulting GroupAggregator will not be parallel-aware and could be
 /// ill-suited for aggregations run against large partitioned caches.
 /// </remarks>
 /// <param name="member">
 /// A member name or a comma-delimited sequence of names that results
 /// in a <see cref="ReflectionExtractor"/> or a
 /// <see cref="MultiExtractor"/> that will be used to split
 /// <see cref="IInvocableCache"/> entries into distinct groups.
 /// </param>
 /// <param name="aggregator">
 /// An underlying <b>IEntryAggregator</b>.
 /// </param>
 /// <returns>
 /// An instance of GroupAggregator based on a specified member
 /// name(s) and an <see cref="IEntryAggregator"/>.
 /// </returns>
 public static GroupAggregator CreateInstance(string member, IEntryAggregator aggregator)
 {
     return(CreateInstance(member, aggregator, null));
 }