private int HighestSearch(DataObject ob, IList <int> list, int lower, int higher) { if ((higher - lower) <= 5) { // Start from the bottom up until we find the highest val for (var i = higher; i >= lower; --i) { int res = ob.CompareTo(GetValue(list[i])); if (res >= 0) { return(i + 1); } } // Didn't find return lowest return(lower); } var mid = (lower + higher) / 2; int compResult = ob.CompareTo(GetValue(list[mid])); if (compResult == 0) { // We know the bottom is between 'mid' and 'higher' return(HighestSearch(ob, list, mid, higher)); } if (compResult < 0) { return(HighestSearch(ob, list, lower, mid - 1)); } return(HighestSearch(ob, list, mid + 1, higher)); }
/// <summary> /// Searches for a given <see cref="DataObject"/> (<paramref name="ob"/>) in the /// row list between the two bounds. /// </summary> /// <param name="ob"></param> /// <param name="list"></param> /// <param name="lower"></param> /// <param name="higher"></param> /// <remarks> /// This returns the place to insert ob into the vector, it should not be used to /// determine if <paramref name="ob"/> is in the list or not. /// </remarks> /// <returns> /// This will return the highest row of the set of values that are equal to <paramref name="ob"/>. /// </returns> private long HighestSearch(DataObject ob, IList <long> list, long lower, long higher) { if ((higher - lower) <= 5) { // Start from the bottom up until we find the highest val for (long i = higher; i >= lower; --i) { int res = ob.CompareTo(GetCellContents(list[(int)i])); if (res >= 0) { return(i + 1); } } // Didn't find return lowest return(lower); } long mid = (lower + higher) / 2; int compResult = ob.CompareTo(GetCellContents(list[(int)mid])); if (compResult == 0) { // We know the bottom is between 'mid' and 'higher' return(HighestSearch(ob, list, mid, higher)); } if (compResult < 0) { return(HighestSearch(ob, list, lower, mid - 1)); } return(HighestSearch(ob, list, mid + 1, higher)); }
/// <summary> /// Returns a list of rows that represent the maximum row of the given column /// from each distinct group in this table. /// </summary> /// <param name="colNum"></param> /// <remarks> /// This should be used to construct a virtual table of rows from /// each distinct group. /// </remarks> /// <returns></returns> private IList <long> GetMaxFromEachGroup(int colNum) { Table refTab = ReferenceTable; List <long> extractRows = new List <long>(); int size = groupLinks.Count; long toTakeInGroup = -1; DataObject max = null; bool take = true; for (int i = 0; i < size; ++i) { long r = groupLinks[i]; long actRIndex = r & 0x03FFFFFFF; DataObject cell = refTab.GetValue(colNum, actRIndex); if (max == null || cell.CompareTo(max) > 0) { max = cell; toTakeInGroup = actRIndex; } if ((r & 0x040000000) != 0) { extractRows.Add(toTakeInGroup); max = null; } } return(extractRows); }
/// <summary> /// Unions the current range set with the given range set. /// </summary> public void Union(SelectableRangeSet unionTo) { List <SelectableRange> inputSet = unionTo.rangeSet; int inSz = inputSet.Count; int n = 0; while (n < inSz) { SelectableRange inRange = (SelectableRange)inputSet[n]; int sz = rangeSet.Count; List <SelectableRange> i = rangeSet.GetRange(0, rangeSet.Count); int j = 0; while (j < i.Count) { SelectableRange range = i[j]; if (RangeIntersectedBy(inRange, range)) { i.RemoveAt(j); inRange = ChangeRangeSizeToEncompass(inRange, range); } j++; } // Insert into sorted position RangePosition startPoint = inRange.StartPosition; DataObject start = inRange.Start; RangePosition endPoint = inRange.EndPosition; DataObject end = inRange.End; if (start == SelectableRange.FirstInSet) { rangeSet.Insert(0, inRange); } else { DataObject startCell = start; i = rangeSet.GetRange(0, rangeSet.Count); j = 0; while (j < i.Count) { SelectableRange range = i[j]; DataObject curStart = range.Start; if (curStart != SelectableRange.FirstInSet) { if (curStart.CompareTo(startCell) > 0) { i[j] = i[j - 1]; break; } } j++; } i.Add(inRange); } n++; } }
/// <summary> /// Alters the first range so it encompasses the second range. /// </summary> /// <remarks> /// This assumes that range1 intersects range2. /// </remarks> private static SelectableRange ChangeRangeSizeToEncompass(SelectableRange range1, SelectableRange range2) { RangePosition startPosition1 = range1.StartPosition; DataObject start1 = range1.Start; RangePosition endPosition1 = range1.EndPosition; DataObject end1 = range1.End; RangePosition startPosition2 = range2.StartPosition; DataObject start2 = range2.Start; RangePosition endPosition2 = range2.EndPosition; DataObject end2 = range2.End; if (start1 != SelectableRange.FirstInSet) { if (start2 != SelectableRange.FirstInSet) { DataObject cell = start1; int c = cell.CompareTo(start2); if (c > 0 || c == 0 && startPosition1 == RangePosition.AfterLastValue && startPosition2 == RangePosition.FirstValue) { start1 = start2; startPosition1 = startPosition2; } } else { start1 = start2; startPosition1 = startPosition2; } } if (end1 != SelectableRange.LastInSet) { if (end2 != SelectableRange.LastInSet) { DataObject cell = end1; int c = cell.CompareTo(end2); if (c < 0 || c == 0 && endPosition1 == RangePosition.BeforeFirstValue && endPosition2 == RangePosition.LastValue) { end1 = end2; endPosition1 = endPosition2; } } else { end1 = end2; endPosition1 = endPosition2; } } return(new SelectableRange(startPosition1, start1, endPosition1, end1)); }
/// <summary> /// Returns true if the two SelectableRange ranges intersect. /// </summary> private static bool RangeIntersectedBy(SelectableRange range1, SelectableRange range2) { RangePosition startFlag1 = range1.StartPosition; DataObject start1 = range1.Start; RangePosition endFlag1 = range1.EndPosition; DataObject end1 = range1.End; RangePosition startFlag2 = range2.StartPosition; DataObject start2 = range2.Start; RangePosition endFlag2 = range2.EndPosition; DataObject end2 = range2.End; DataObject startCell1 = start1 == SelectableRange.FirstInSet ? null : start1; DataObject endCell1 = end1 == SelectableRange.LastInSet ? null : end1; DataObject startCell2 = start2 == SelectableRange.FirstInSet ? null : start2; DataObject endCell2 = end2 == SelectableRange.LastInSet ? null : end2; bool intersect1 = false; if (startCell1 != null && endCell2 != null) { int c = startCell1.CompareTo(endCell2); if (c < 0 || (c == 0 && (startFlag1 == RangePosition.FirstValue || endFlag2 == RangePosition.LastValue))) { intersect1 = true; } } else { intersect1 = true; } bool intersect2 = false; if (startCell2 != null && endCell1 != null) { int c = startCell2.CompareTo(endCell1); if (c < 0 || (c == 0 && (startFlag2 == RangePosition.FirstValue || endFlag1 == RangePosition.LastValue))) { intersect2 = true; } } else { intersect2 = true; } return(intersect1 && intersect2); }
public static ITable Distinct(this ITable table, int[] columns) { var theTable = table as Table; if (theTable == null) { return(table); } List <long> resultList = new List <long>(); IList <long> rowList = theTable.OrdereddRows(columns); long rowCount = rowList.Count; long previousRow = -1; for (int i = 0; i < rowCount; ++i) { long rowIndex = rowList[i]; if (previousRow != -1) { bool equal = true; // Compare cell in column in this row with previous row. for (int n = 0; n < columns.Length && equal; ++n) { DataObject c1 = table.GetValue(columns[n], rowIndex); DataObject c2 = table.GetValue(columns[n], previousRow); equal = (c1.CompareTo(c2) == 0); } if (!equal) { resultList.Add(rowIndex); } } else { resultList.Add(rowIndex); } previousRow = rowIndex; } // Return the new table with distinct rows only. VirtualTable vt = new VirtualTable(theTable); vt.Set(theTable, resultList); return(vt); }
private int InternalCompare(long index, DataObject value) { DataObject cell = scheme.GetCellContents(index); return(cell.CompareTo(value)); }
/// <summary> /// Creates a grouping matrix for the given columns. /// </summary> /// <param name="columns"></param> /// <remarks> /// The grouping matrix is arranged so that each row of the refering /// table that is in the group is given a number that refers to the top /// group entry in the group list. The group list is a linked integer /// list that chains through each row item in the list. /// </remarks> public void CreateGroupMatrix(ObjectName[] columns) { // If we have zero rows, then don't bother creating the matrix. if (RowCount <= 0 || columns.Length <= 0) { return; } Table rootTable = ReferenceTable; long rowCount = rootTable.RowCount; int[] colLookup = new int[columns.Length]; for (int i = columns.Length - 1; i >= 0; --i) { colLookup[i] = rootTable.FindFieldName(columns[i]); } IList <long> rowList = rootTable.OrdereddRows(colLookup); // 'row_list' now contains rows in this table sorted by the columns to // group by. // This algorithm will generate two lists. The group_lookup list maps // from rows in this table to the group number the row belongs in. The // group number can be used as an index to the 'group_links' list that // contains consequtive links to each row in the group until -1 is reached // indicating the end of the group; groupLookup = new List <long>((int)rowCount); groupLinks = new List <long>((int)rowCount); int current_group = 0; long previous_row = -1; for (int i = 0; i < rowCount; ++i) { long rowIndex = rowList[i]; if (previous_row != -1) { bool equal = true; // Compare cell in column in this row with previous row. for (int n = 0; n < colLookup.Length && equal; ++n) { DataObject c1 = rootTable.GetValue(colLookup[n], rowIndex); DataObject c2 = rootTable.GetValue(colLookup[n], previous_row); equal = (c1.CompareTo(c2) == 0); } if (!equal) { // If end of group, set bit 15 groupLinks.Add(previous_row | 0x040000000); current_group = groupLinks.Count; } else { groupLinks.Add(previous_row); } } // groupLookup.Insert(row_index, current_group); PlaceAt(groupLookup, rowIndex, current_group); previous_row = rowIndex; } // Add the final row. groupLinks.Add(previous_row | 0x040000000); // Set up a group resolver for this method. groupResolver = new TableGroupResolver(this); }
/// <summary> /// Searches for a given <see cref="DataObject"/> (<paramref name="ob"/>) in the /// row list between the two bounds. /// </summary> /// <param name="ob"></param> /// <param name="list"></param> /// <param name="lower"></param> /// <param name="higher"></param> /// <remarks> /// This returns the place to insert ob into the vector, it should not be used to /// determine if <paramref name="ob"/> is in the list or not. /// </remarks> /// <returns> /// This will return the highest row of the set of values that are equal to <paramref name="ob"/>. /// </returns> private long HighestSearch(DataObject ob, IList<long> list, long lower, long higher) { if ((higher - lower) <= 5) { // Start from the bottom up until we find the highest val for (long i = higher; i >= lower; --i) { int res = ob.CompareTo(GetCellContents(list[(int)i])); if (res >= 0) return i + 1; } // Didn't find return lowest return lower; } long mid = (lower + higher) / 2; int compResult = ob.CompareTo(GetCellContents(list[(int)mid])); if (compResult == 0) // We know the bottom is between 'mid' and 'higher' return HighestSearch(ob, list, mid, higher); if (compResult < 0) return HighestSearch(ob, list, lower, mid - 1); return HighestSearch(ob, list, mid + 1, higher); }
private static IndexRange IntersectOn(IndexRange range, SqlExpressionType op, DataObject value, bool nullCheck) { var start = range.StartValue; var startPosition = range.StartOffset; var end = range.EndValue; var endPosition = range.EndOffset; bool inclusive = op == SqlExpressionType.Is || op == SqlExpressionType.Equal || op == SqlExpressionType.GreaterOrEqualThan || op == SqlExpressionType.SmallerOrEqualThan; if (op == SqlExpressionType.Is || op == SqlExpressionType.Equal || op == SqlExpressionType.GreaterThan || op == SqlExpressionType.GreaterOrEqualThan) { // With this operator, NULL values must return null. if (nullCheck && value.IsNull) { return IndexRange.Null; } if (start.Equals(IndexRange.FirstInSet)) { start = value; startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue; } else { int c = value.CompareTo(start); if ((c == 0 && startPosition == RangeFieldOffset.FirstValue) || c > 0) { start = value; startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue; } } } if (op == SqlExpressionType.Is || op == SqlExpressionType.Equal || op == SqlExpressionType.SmallerThan || op == SqlExpressionType.SmallerOrEqualThan) { // With this operator, NULL values must return null. if (nullCheck && value.IsNull) { return IndexRange.Null; } // If start is first in set, then we have to change it to after NULL if (nullCheck && start.Equals(IndexRange.FirstInSet)) { start = DataObject.Null(); startPosition = RangeFieldOffset.AfterLastValue; } if (end.Equals(IndexRange.LastInSet)) { end = value; endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue; } else { int c = value.CompareTo(end); if ((c == 0 && endPosition == RangeFieldOffset.LastValue) || c < 0) { end = value; endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue; } } } // If start and end are not null types (if either are, then it means it // is a placeholder value meaning start or end of set). if (!start.Equals(IndexRange.FirstInSet) && !end.Equals(IndexRange.LastInSet)) { // If start is higher than end, return null int c = start.CompareTo(end); if ((c == 0 && (startPosition == RangeFieldOffset.AfterLastValue || endPosition == RangeFieldOffset.BeforeFirstValue)) || c > 0) { return IndexRange.Null; } } // The new intersected range return new IndexRange(startPosition, start, endPosition, end); }
private int HighestSearch(DataObject ob, IList<int> list, int lower, int higher) { if ((higher - lower) <= 5) { // Start from the bottom up until we find the highest val for (var i = higher; i >= lower; --i) { int res = ob.CompareTo(GetValue(list[i])); if (res >= 0) return i + 1; } // Didn't find return lowest return lower; } var mid = (lower + higher)/2; int compResult = ob.CompareTo(GetValue(list[mid])); if (compResult == 0) // We know the bottom is between 'mid' and 'higher' return HighestSearch(ob, list, mid, higher); if (compResult < 0) return HighestSearch(ob, list, lower, mid - 1); return HighestSearch(ob, list, mid + 1, higher); }
/// <summary> /// If this node represents the given entity this method should return true. /// </summary> /// <param name="entity">The entity to check.</param> /// <returns>true if this node represents the given entity.</returns> public override bool RepresentsEntity(object entity) { return (DataObject.CompareTo(entity) == 0); }
/// <summary> /// Intersects the given SelectableRange object with the given operator and /// value constraint. /// </summary> /// <remarks> /// <b>Note</b>: This does not work with the <c><></c> operator /// which must be handled another way. /// </remarks> private static SelectableRange IntersectRange(SelectableRange range, Operator op, DataObject val, bool nullCheck) { DataObject start = range.Start; RangePosition startPosition = range.StartPosition; DataObject end = range.End; RangePosition endPosition = range.EndPosition; bool inclusive = op.IsEquivalent(Operator.Is) || op.IsEquivalent(Operator.Equal) || op.IsEquivalent(Operator.GreaterOrEqual) || op.IsEquivalent(Operator.SmallerOrEqual); if (op.IsEquivalent(Operator.Is) || op.IsEquivalent(Operator.Equal) || op.IsEquivalent(Operator.Greater) || op.IsEquivalent(Operator.GreaterOrEqual)) { // With this operator, NULL values must return null. if (nullCheck && val.IsNull) { return(null); } if (start == SelectableRange.FirstInSet) { start = val; startPosition = inclusive ? RangePosition.FirstValue : RangePosition.AfterLastValue; } else { int c = val.CompareTo(start); if ((c == 0 && startPosition == RangePosition.FirstValue) || c > 0) { start = val; startPosition = inclusive ? RangePosition.FirstValue : RangePosition.AfterLastValue; } } } if (op.IsEquivalent(Operator.Is) || op.IsEquivalent(Operator.Equal) || op.IsEquivalent(Operator.Smaller) || op.IsEquivalent(Operator.SmallerOrEqual)) { // With this operator, NULL values must return null. if (nullCheck && val.IsNull) { return(null); } // If start is first in set, then we have to change it to after NULL if (nullCheck && start == SelectableRange.FirstInSet) { start = DataObject.Null; startPosition = RangePosition.AfterLastValue; } if (end == SelectableRange.LastInSet) { end = val; endPosition = inclusive ? RangePosition.LastValue : RangePosition.BeforeFirstValue; } else { int c = val.CompareTo(end); if ((c == 0 && endPosition == RangePosition.LastValue) || c < 0) { end = val; endPosition = inclusive ? RangePosition.LastValue : RangePosition.BeforeFirstValue; } } } // If start and end are not null types (if either are, then it means it // is a placeholder value meaning start or end of set). if (start != SelectableRange.FirstInSet && end != SelectableRange.LastInSet) { // If start is higher than end, return null int c = start.CompareTo(end); if ((c == 0 && (startPosition == RangePosition.AfterLastValue || endPosition == RangePosition.BeforeFirstValue)) || c > 0) { return(null); } } // The new intersected range return(new SelectableRange(startPosition, start, endPosition, end)); }
public int CompareValue(long index, DataObject val) { DataObject cell = scheme.GetCellContents(rowSet[(int)index]); return(cell.CompareTo(val)); }
public int CompareValue(long index, DataObject val) { DataObject cell = subsetList[index]; return(cell.CompareTo(val)); }
private static IndexRange IntersectOn(IndexRange range, SqlExpressionType op, DataObject value, bool nullCheck) { var start = range.StartValue; var startPosition = range.StartOffset; var end = range.EndValue; var endPosition = range.EndOffset; bool inclusive = op == SqlExpressionType.Is || op == SqlExpressionType.Equal || op == SqlExpressionType.GreaterOrEqualThan || op == SqlExpressionType.SmallerOrEqualThan; if (op == SqlExpressionType.Is || op == SqlExpressionType.Equal || op == SqlExpressionType.GreaterThan || op == SqlExpressionType.GreaterOrEqualThan) { // With this operator, NULL values must return null. if (nullCheck && value.IsNull) { return(IndexRange.Null); } if (start.Equals(IndexRange.FirstInSet)) { start = value; startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue; } else { int c = value.CompareTo(start); if ((c == 0 && startPosition == RangeFieldOffset.FirstValue) || c > 0) { start = value; startPosition = inclusive ? RangeFieldOffset.FirstValue : RangeFieldOffset.AfterLastValue; } } } if (op == SqlExpressionType.Is || op == SqlExpressionType.Equal || op == SqlExpressionType.SmallerThan || op == SqlExpressionType.SmallerOrEqualThan) { // With this operator, NULL values must return null. if (nullCheck && value.IsNull) { return(IndexRange.Null); } // If start is first in set, then we have to change it to after NULL if (nullCheck && start.Equals(IndexRange.FirstInSet)) { start = DataObject.Null(); startPosition = RangeFieldOffset.AfterLastValue; } if (end.Equals(IndexRange.LastInSet)) { end = value; endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue; } else { int c = value.CompareTo(end); if ((c == 0 && endPosition == RangeFieldOffset.LastValue) || c < 0) { end = value; endPosition = inclusive ? RangeFieldOffset.LastValue : RangeFieldOffset.BeforeFirstValue; } } } // If start and end are not null types (if either are, then it means it // is a placeholder value meaning start or end of set). if (!start.Equals(IndexRange.FirstInSet) && !end.Equals(IndexRange.LastInSet)) { // If start is higher than end, return null int c = start.CompareTo(end); if ((c == 0 && (startPosition == RangeFieldOffset.AfterLastValue || endPosition == RangeFieldOffset.BeforeFirstValue)) || c > 0) { return(IndexRange.Null); } } // The new intersected range return(new IndexRange(startPosition, start, endPosition, end)); }
/// <summary> /// Intersects the given SelectableRange object with the given operator and /// value constraint. /// </summary> /// <remarks> /// <b>Note</b>: This does not work with the <c><></c> operator /// which must be handled another way. /// </remarks> private static SelectableRange IntersectRange(SelectableRange range, Operator op, DataObject val, bool nullCheck) { DataObject start = range.Start; RangePosition startPosition = range.StartPosition; DataObject end = range.End; RangePosition endPosition = range.EndPosition; bool inclusive = op.IsEquivalent(Operator.Is) || op.IsEquivalent(Operator.Equal) || op.IsEquivalent(Operator.GreaterOrEqual) || op.IsEquivalent(Operator.SmallerOrEqual); if (op.IsEquivalent(Operator.Is) || op.IsEquivalent(Operator.Equal) || op.IsEquivalent(Operator.Greater) || op.IsEquivalent(Operator.GreaterOrEqual)) { // With this operator, NULL values must return null. if (nullCheck && val.IsNull) { return null; } if (start == SelectableRange.FirstInSet) { start = val; startPosition = inclusive ? RangePosition.FirstValue : RangePosition.AfterLastValue; } else { int c = val.CompareTo(start); if ((c == 0 && startPosition == RangePosition.FirstValue) || c > 0) { start = val; startPosition = inclusive ? RangePosition.FirstValue : RangePosition.AfterLastValue; } } } if (op.IsEquivalent(Operator.Is) || op.IsEquivalent(Operator.Equal) || op.IsEquivalent(Operator.Smaller) || op.IsEquivalent(Operator.SmallerOrEqual)) { // With this operator, NULL values must return null. if (nullCheck && val.IsNull) { return null; } // If start is first in set, then we have to change it to after NULL if (nullCheck && start == SelectableRange.FirstInSet) { start = DataObject.Null; startPosition = RangePosition.AfterLastValue; } if (end == SelectableRange.LastInSet) { end = val; endPosition = inclusive ? RangePosition.LastValue : RangePosition.BeforeFirstValue; } else { int c = val.CompareTo(end); if ((c == 0 && endPosition == RangePosition.LastValue) || c < 0) { end = val; endPosition = inclusive ? RangePosition.LastValue : RangePosition.BeforeFirstValue; } } } // If start and end are not null types (if either are, then it means it // is a placeholder value meaning start or end of set). if (start != SelectableRange.FirstInSet && end != SelectableRange.LastInSet) { // If start is higher than end, return null int c = start.CompareTo(end); if ((c == 0 && (startPosition == RangePosition.AfterLastValue || endPosition == RangePosition.BeforeFirstValue)) || c > 0) { return null; } } // The new intersected range return new SelectableRange(startPosition, start, endPosition, end); }