示例#1
0
        /// <summary>
        ///  Delete items from this Partition which meet the provided criteria.
        /// </summary>
        /// <param name="where">Expression matching items to delete</param>
        /// <param name="details">Details of execution</param>
        /// <returns>Result including number deleted</returns>
        public DeleteResult Delete(IExpression where)
        {
            if (where == null)
            {
                throw new ArgumentNullException("where");
            }

            DeleteResult result = new DeleteResult();

            // Find the set of items to delete
            ShortSet whereSet = new ShortSet(this.Count);

            where.TryEvaluate(this, whereSet, result.Details);

            if (result.Details.Succeeded)
            {
                // Swap each item to delete with the last item in the set
                ushort   lastItemIndex = (ushort)(this.Count - 1);
                ushort[] itemsToDelete = whereSet.Values;
                for (int i = itemsToDelete.Length - 1; i >= 0; --i)
                {
                    // If this isn't the last item, swap the last item with it
                    ushort itemToDelete = itemsToDelete[i];
                    if (itemToDelete != lastItemIndex)
                    {
                        foreach (IColumn <object> c in this.Columns.Values)
                        {
                            c[itemToDelete] = c[lastItemIndex];
                        }
                    }

                    lastItemIndex--;
                }

                // Resize the set to exclude all of the deleted items (now at the end)
                foreach (IColumn <object> c in this.Columns.Values)
                {
                    c.SetSize((ushort)(lastItemIndex + 1));
                }

                // Record the new count in the Partition itself
                _itemCount = (ushort)(lastItemIndex + 1);

                // Return the count deleted
                result.Count = whereSet.Count();
            }

            return(result);
        }
示例#2
0
        public void TryEvaluate(Partition partition, ShortSet result, ExecutionDetails details)
        {
            if (partition == null)
            {
                throw new ArgumentNullException("partition");
            }
            if (result == null)
            {
                throw new ArgumentNullException("result");
            }

            ushort itemCount = partition.Count;

            foreach (IExpression part in _set)
            {
                part.TryEvaluate(partition, result, details);
                if (result.Count() == itemCount)
                {
                    break;
                }
            }
        }
示例#3
0
        public DataBlockResult Compute(Partition p)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }
            DataBlockResult result = new DataBlockResult(this);

            // Verify the column exists
            if (!p.ContainsColumn(this.Column))
            {
                result.Details.AddError(ExecutionDetails.ColumnDoesNotExist, this.Column);
                return(result);
            }

            // Verify we were able to get percentile values
            if (this.Buckets == null)
            {
                result.Details.AddError(ExecutionDetails.ColumnDoesNotSupportOperator, "percentile", this.Column);
                return(result);
            }

            // Find the set of items matching the where clause
            ShortSet whereSet = new ShortSet(p.Count);

            this.Where.TryEvaluate(p, whereSet, result.Details);

            IUntypedColumn column = p.Columns[this.Column];

            if (result.Details.Succeeded)
            {
                Bucketer bucketer = NativeContainer.CreateTypedInstance <Bucketer>(typeof(Bucketer <>), column.ColumnType);
                result.Values = bucketer.Bucket(column.InnerColumn, whereSet, this.Buckets, this.Inclusive);
                result.Total  = whereSet.Count();
            }

            return(result);
        }
示例#4
0
        public override void VerifyConsistency(VerificationLevel level, ExecutionDetails details)
        {
            base.VerifyConsistency(level, details);

            // Verify SortedIDCount agrees with ItemCount
            if (this.SortedIDCount != this.Count)
            {
                if (details != null)
                {
                    details.AddError(ExecutionDetails.ColumnDoesNotHaveEnoughValues, this.Name, this.SortedIDCount, this.Count);
                }
            }

            // Verify that all IDs are in SortedIDs, all values are ordered, and no unexpected values are found
            ushort      lastID    = 0;
            IComparable lastValue = null;

            ShortSet idsInList = new ShortSet(this.Count);

            for (int i = 0; i < this.Count; ++i)
            {
                ushort id = this.SortedIDs[i];

                if (id >= this.Count)
                {
                    if (details != null)
                    {
                        details.AddError(ExecutionDetails.SortedIdOutOfRange, this.Name, id, this.Count);
                    }
                }
                else if (idsInList.Contains(id))
                {
                    if (details != null)
                    {
                        details.AddError(ExecutionDetails.SortedIdAppearsMoreThanOnce, this.Name, id);
                    }
                }
                else
                {
                    idsInList.Add(id);

                    IComparable value = (IComparable)this[id];
                    if (lastValue != null)
                    {
                        int compareResult = lastValue.CompareTo(value);
                        if (compareResult > 0)
                        {
                            if (details != null)
                            {
                                details.AddError(ExecutionDetails.SortedValuesNotInOrder, this.Name, lastID, lastValue, id, value);
                            }
                        }
                    }

                    lastValue = value;
                    lastID    = id;
                }
            }

            idsInList.Not();
            if (idsInList.Count() > 0)
            {
                if (details != null)
                {
                    details.AddError(ExecutionDetails.SortedColumnMissingIDs, this.Name, String.Join(", ", idsInList.Values));
                }
            }
        }
示例#5
0
        public AggregationResult Compute(Partition p)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }

            Stopwatch         w      = Stopwatch.StartNew();
            AggregationResult result = new AggregationResult(this);

            result.AggregationContext = this.Aggregator.CreateContext();

            // Get any columns passed to the aggregation function
            IUntypedColumn[] columns = null;
            if (this.AggregationColumns != null)
            {
                columns = new IUntypedColumn[this.AggregationColumns.Length];

                for (int i = 0; i < this.AggregationColumns.Length; ++i)
                {
                    string columnName = this.AggregationColumns[i];

                    if (!p.Columns.TryGetValue(columnName, out columns[i]))
                    {
                        result.Details.AddError(ExecutionDetails.ColumnDoesNotExist, columnName);
                        return(result);
                    }
                }
            }

            // Find the number of dimensions and number of "cells" for which we'll aggregate
            List <string> resultBlockColumns = new List <string>();
            int           rowCount           = 1;

            for (int i = 0; i < this.Dimensions.Count; ++i)
            {
                AggregationDimension dimension = this.Dimensions[i];

                if (!String.IsNullOrEmpty(dimension.Name))
                {
                    resultBlockColumns.Add(dimension.Name);
                }
                else
                {
                    resultBlockColumns.Add(StringExtensions.Format("Dimension {0}", i + 1));
                }

                rowCount *= (dimension.GroupByWhere.Count + 1);
            }

            resultBlockColumns.Add("Aggregate");

            // Create the DataBlock to hold the final results
            result.Values = new DataBlock(resultBlockColumns, rowCount);

            // Find the set of items in the base query
            ShortSet baseWhereSet = new ShortSet(p.Count);

            this.Where.TryEvaluate(p, baseWhereSet, result.Details);
            result.Total = baseWhereSet.Count();

            // If this is only one dimension, use only one ShortSet and aggregate as we go
            if (this.Dimensions.Count == 1)
            {
                AggregationDimension dimension       = this.Dimensions[0];
                ShortSet             setForDimension = new ShortSet(p.Count);
                int nextBlockRow = 0;

                foreach (IExpression dimensionValue in dimension.GroupByWhere)
                {
                    // Get the set for this value intersected with the base set
                    setForDimension.Clear();
                    dimensionValue.TryEvaluate(p, setForDimension, result.Details);
                    setForDimension.And(baseWhereSet);

                    // Compute and store the aggregate value
                    if (!setForDimension.IsEmpty())
                    {
                        result.Values[nextBlockRow, 1] = this.Aggregator.Aggregate(result.AggregationContext, setForDimension, columns);
                    }

                    nextBlockRow++;
                }

                // Add the total
                result.Values[nextBlockRow, 1] = this.Aggregator.Aggregate(result.AggregationContext, baseWhereSet, columns);
            }
            else
            {
                // Compute the set of items actually matching each dimension-value
                List <List <Tuple <IExpression, ShortSet> > > allDimensionValueSets = new List <List <Tuple <IExpression, ShortSet> > >();
                foreach (AggregationDimension dimension in this.Dimensions)
                {
                    List <Tuple <IExpression, ShortSet> > dimensionSet = new List <Tuple <IExpression, ShortSet> >();

                    // Add one item for each value in this dimension
                    foreach (IExpression dimensionValue in dimension.GroupByWhere)
                    {
                        ShortSet setForDimensionValue = new ShortSet(p.Count);
                        dimensionValue.TryEvaluate(p, setForDimensionValue, result.Details);

                        dimensionSet.Add(new Tuple <IExpression, ShortSet>(dimensionValue, setForDimensionValue));
                    }

                    // Add one 'Total row' item
                    dimensionSet.Add(new Tuple <IExpression, ShortSet>(new AllExpression(), baseWhereSet));

                    allDimensionValueSets.Add(dimensionSet);
                }

                // Run the aggregator over the items
                AggregateAllDimensionsFlat(result.AggregationContext, result.Values, p.Count, baseWhereSet, allDimensionValueSets, columns, this.Aggregator);
            }

            // Add the dimension names to the result if this is the only partition; otherwise, merge will add it
            if (p.Mask.Equals(PartitionMask.All))
            {
                AddDimensionsToBlock(result.Values);
            }

            // Capture timing and return
            result.Runtime = w.Elapsed;
            return(result);
        }
示例#6
0
            public SelectResult Compute(Partition p)
            {
                if (p == null)
                {
                    throw new ArgumentNullException("p");
                }

                SelectResult result = new SelectResult(this.Query);


                // Find the set of items matching all terms
                ShortSet whereSet = new ShortSet(p.Count);

                this.Where.TryEvaluate(p, whereSet, result.Details);

                // Verify that the ORDER BY column exists
                if (!String.IsNullOrEmpty(this.OrderByColumn) && !p.Columns.ContainsKey(this.OrderByColumn))
                {
                    result.Details.AddError(ExecutionDetails.ColumnDoesNotExist, this.OrderByColumn);
                    return(result);
                }

                if (result.Details.Succeeded)
                {
                    IUntypedColumn column = null;

                    result.Total = whereSet.Count();

                    // Find the set of IDs to return for the query (up to 'Count' after 'Skip' in ORDER BY order)
                    ushort[] lidsToReturn = GetLIDsToReturn(p, this, result, whereSet);
                    result.CountReturned = (ushort)lidsToReturn.Length;

                    // Get the order-by column
                    if (!p.Columns.TryGetValue(this.OrderByColumn, out column))
                    {
                        result.Details.AddError(ExecutionDetails.ColumnDoesNotExist, this.OrderByColumn);
                        return(result);
                    }
                    Array orderByColumn = column.GetValues(lidsToReturn);

                    // Get all of the response columns and return them
                    Array columns = new Array[this.Columns.Count];
                    for (int i = 0; i < this.Columns.Count; ++i)
                    {
                        string columnName = this.Columns[i];

                        if (columnName == this.OrderByColumn)
                        {
                            columns.SetValue(orderByColumn, i);
                        }
                        else
                        {
                            if (!p.Columns.TryGetValue(columnName, out column))
                            {
                                result.Details.AddError(ExecutionDetails.ColumnDoesNotExist, columnName);
                                return(result);
                            }

                            Array values = column.GetValues(lidsToReturn);
                            if (Query.Highlighter != null)
                            {
                                Query.Highlighter.Highlight(values, column, Query);
                            }

                            columns.SetValue(values, i);
                        }
                    }

                    result.Values        = new DataBlock(p.GetDetails(this.Columns), result.CountReturned, columns);
                    result.OrderByValues = new DataBlock(p.GetDetails(new string[] { this.OrderByColumn }), result.CountReturned, new Array[] { orderByColumn });
                }

                return(result);
            }
示例#7
0
        public override DistinctResult Compute(Partition p)
        {
            if (p == null)
            {
                throw new ArgumentNullException("p");
            }
            DistinctResult result = new DistinctResult(this);

            // Verify the column exists
            if (!p.ContainsColumn(this.Column))
            {
                result.Details.AddError(ExecutionDetails.ColumnDoesNotExist, this.Column);
                return(result);
            }

            // Find the set of items matching the base where clause
            ShortSet whereSet = new ShortSet(p.Count);

            this.Where.TryEvaluate(p, whereSet, result.Details);

            // Capture the total of the base query
            result.Total = whereSet.Count();

            // Add a prefix filter for the prefix so far, if any and the column can prefix match
            if (!String.IsNullOrEmpty(this.ValuePrefix))
            {
                ExecutionDetails prefixDetails = new ExecutionDetails();
                ShortSet         prefixSet     = new ShortSet(p.Count);
                new TermExpression(this.Column, Operator.StartsWith, this.ValuePrefix).TryEvaluate(p, prefixSet, prefixDetails);
                if (prefixDetails.Succeeded)
                {
                    whereSet.And(prefixSet);
                }
            }

            if (result.Details.Succeeded)
            {
                // Count the occurences of each value
                Dictionary <object, int> countByValue = new Dictionary <object, int>();
                IUntypedColumn           column       = p.Columns[this.Column];

                for (int i = 0; i < column.Count; ++i)
                {
                    ushort lid = (ushort)i;
                    if (whereSet.Contains(lid))
                    {
                        object value = column[lid];

                        int count;
                        countByValue.TryGetValue(value, out count);
                        countByValue[value] = count + 1;
                    }
                }

                // Convert the top this.Count rows by count into a DataBlock
                result.Values = ToDataBlock(countByValue, this.Column, (int)this.Count);

                result.AllValuesReturned = result.Values.RowCount == countByValue.Count;
            }

            return(result);
        }