Ejemplo n.º 1
0
        /// <summary>
        /// Creates jobs for the parallel group by.
        /// Note that the last job in the array has the end set to the end of the result table.
        /// Each job will receive a range from result table, hasher, comparer and aggregates.
        /// Note that they are all copies, because they contain a private stete (hasher contains reference to the equality comparers to enable caching when computing the hash, aggregates
        /// contain references to storage arrays to avoid casting in a tight loop).
        /// The comparers and hashers build in the constructor of this class are given to the last job, just like the aggregates passed to the construtor.
        /// The global Dictionary recieves a comparer that has no internal comparers set to some hasher.
        /// </summary>
        private GroupByJob[] CreateJobs(ITableResults resTable, Aggregate[] aggs, ExpressionComparer[] comparers, ExpressionHasher[] hashers)
        {
            GroupByJob[] jobs     = new GroupByJob[this.ThreadCount];
            int          current  = 0;
            int          addition = resTable.NumberOfMatchedElements / this.ThreadCount;

            if (addition == 0)
            {
                throw new ArgumentException($"{this.GetType()}, a range for a thread cannot be 0.");
            }

            var lastComp   = RowEqualityComparerGroupKey.Factory(resTable, comparers, true);
            var lastHasher = new RowHasher(hashers);

            lastHasher.SetCache(lastComp.comparers);

            // It needs only comparator that has no comparers set as a cache to some hasher.
            var globalGroups = new ConcurrentDictionary <GroupDictKey, AggregateBucketResult[]>(lastComp.Clone(cacheResults: false));

            for (int i = 0; i < jobs.Length - 1; i++)
            {
                var tmpComp = lastComp.Clone(cacheResults: true);
                var tmpHash = lastHasher.Clone();
                tmpHash.SetCache(tmpComp.comparers);
                jobs[i]  = CreateJob(tmpHash, tmpComp, aggs, resTable, current, current + addition, globalGroups);
                current += addition;
            }
            jobs[jobs.Length - 1] = CreateJob(lastHasher, lastComp, aggs, resTable, current, resTable.NumberOfMatchedElements, globalGroups);
            return(jobs);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Creates jobs for the parallel group by.
        /// Note that the last job in the array has the end set to the end of the result table.
        /// Each job will receive a range from result table, hasher, comparer (cache on) and aggregates.
        /// Note that they are all copies, because they contain a private state (hasher contains reference to the equality comparers to enable caching when computing the hash).
        /// The comparers and hashers build in the constructor of this class are given to the last job, just like the aggregates passed to the construtor.
        /// </summary>
        private GroupByJob[] CreateJobs(ITableResults resTable, Aggregate[] aggs, ExpressionComparer[] comparers, ExpressionHasher[] hashers)
        {
            GroupByJob[] jobs     = new GroupByJob[this.ThreadCount];
            int          current  = 0;
            int          addition = resTable.NumberOfMatchedElements / this.ThreadCount;

            if (addition == 0)
            {
                throw new ArgumentException($"{this.GetType()}, a range for a thread cannot be 0.");
            }

            // Set their internal cache.
            var lastComp   = RowEqualityComparerGroupKey.Factory(resTable, comparers, true);
            var lastHasher = new RowHasher(hashers);

            lastHasher.SetCache(lastComp.comparers);

            for (int i = 0; i < jobs.Length - 1; i++)
            {
                var tmpComp = lastComp.Clone(cacheResults: true);
                var tmpHash = lastHasher.Clone();
                tmpHash.SetCache(tmpComp.comparers);
                jobs[i]  = CreateJob(tmpHash, tmpComp, aggs, resTable, current, current + addition);
                current += addition;
            }

            jobs[jobs.Length - 1] = CreateJob(lastHasher, lastComp, aggs, resTable, current, resTable.NumberOfMatchedElements);
            return(jobs);
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Creates jobs for the parallel group by.
        /// Note that the last job in the array has the end set to the end of the result table.
        /// Each job will receive a range from result table, aggregates and a global place to store groups and the aggregated values.
        /// Note that there is a single comparer for the ConcurrentDictionary, thus no caching of the expression is done.
        /// </summary>
        private GroupByJob[] CreateJobs(RowEqualityComparerInt equalityComparer, ITableResults resTable)
        {
            GroupByJob[] jobs     = new GroupByJob[this.ThreadCount];
            int          current  = 0;
            int          addition = resTable.NumberOfMatchedElements / this.ThreadCount;

            if (addition == 0)
            {
                throw new ArgumentException($"{this.GetType()}, a range for a thread cannot be 0.");
            }

            return(CreateSpecJobs(jobs, equalityComparer, resTable, current, addition));
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Creates jobs for the parallel group by.
        /// Note that the last job in the array has the start/end set to the end of result table.
        ///
        /// Note that the passed aggregates results, are the ones that the rest will be merged into.
        /// They are expected to be at the last index of the jobs => they must have at least one result assigned.
        /// </summary>
        /// <param name="resTable"> A place to store aggregation results. </param>
        /// <param name="aggs"> Aggregation functions. </param>
        /// <param name="aggResults"> The results of the merge is stored in this isntances. It is placed into the last job. </param>
        private GroupByJob[] CreateJobs(ITableResults resTable, Aggregate[] aggs, AggregateBucketResult[] aggResults)
        {
            GroupByJob[] jobs    = new GroupByJob[this.ThreadCount];
            int          current = 0;
            // No that this is never <= 0 because it was checked when picking the impl.
            int addition = resTable.NumberOfMatchedElements / this.ThreadCount;

            for (int i = 0; i < jobs.Length - 1; i++)
            {
                jobs[i]  = new GroupByJob(aggs, AggregateBucketResult.CreateBucketResults(aggs), current, current + addition, resTable);
                current += addition;
            }

            jobs[jobs.Length - 1] = new GroupByJob(aggs, aggResults, current, resTable.NumberOfMatchedElements, resTable);
            return(jobs);
        }
        protected override GroupByResults CreateGroupByResults(GroupByJob job)
        {
            var tmp = (GroupByJobBuckets)job;

            return(new DictGroupDictKeyBucket(tmp.groups, tmp.resTable));
        }
Ejemplo n.º 6
0
 private GroupByResults CreateGroupByResults(GroupByJob job)
 {
     return(new ConDictGroupByResultsBucket(job.globalGroups, job.resTable));
 }
Ejemplo n.º 7
0
        /// <summary>
        /// Computes single threadedly aggregates.
        /// </summary>
        /// <param name="resTable"> A place to store aggregation results. </param>
        /// <param name="aggs"> Aggregation functions. </param>
        /// <param name="aggResults"> The results of the merge is stored in this isntances. </param>
        private void SingleThreadGroupBy(ITableResults resTable, Aggregate[] aggs, AggregateBucketResult[] aggResults)
        {
            var job = new GroupByJob(aggs, aggResults, 0, resTable.NumberOfMatchedElements, resTable);

            SingleThreadGroupByWork(job);
        }
Ejemplo n.º 8
0
 protected abstract GroupByResults CreateGroupByResults(GroupByJob job);
Ejemplo n.º 9
0
        protected override GroupByResults CreateGroupByResults(GroupByJob job)
        {
            var tmpJob = (GroupByJobBuckets)job;

            return(new ConDictIntBucket(tmpJob.groups, tmpJob.resTable));
        }
        protected override GroupByResults CreateGroupByResults(GroupByJob job)
        {
            var tmp = (GroupByJobLists)job;

            return(new GroupByResultsList(tmp.groups, tmp.aggResults, tmp.resTable));
        }
Ejemplo n.º 11
0
        protected override GroupByResults CreateGroupByResults(GroupByJob job)
        {
            var tmpJob = (GroupByJobArrays)job;

            return(new GroupByResultsArray(tmpJob.groups, tmpJob.aggResults, tmpJob.resTable));
        }