/// <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); }
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; } } }
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); }
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)); } } }
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); }
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); }
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); }