// Return value of attribute with tuple indexing // FIX: needs to get from this row to some other row via parent table to use as lookup public TypedValue ValueOffset(ExpressionEval expr, int index, OffsetModes mode) { var parent = Parent as DataTableLocal; Logger.Assert(parent != null); var ord = OrderedIndex.Offset(this, index, mode); var value = (ord == -1) ? expr.ReturnType.DefaultValue() : expr.EvalOpen(parent.GetRow(ord)); return(value); }
// Create from seginfo public static OrderedIndex Create(SegmentInfo[] seginfo) { var ordi = new OrderedIndex { _seginfo = seginfo, _slist = new SortedList <SortKey, int>(new ArrayComparer { _seginfo = seginfo }), }; ordi._groupseg = Enumerable.Range(1, seginfo.Length).LastOrDefault(x => seginfo[x - 1].grouped) - 1; return(ordi); }
// Transform with ordered calculations - different algorithm // 1. Build index // 2. Read input file using index // 3. Transform and write output file public override DataTable TransformOrdered(DataHeading newheading, ExpressionEval[] exprs, ExpressionEval[] orderexps) { Logger.WriteLine(4, "TransformOrdered {0} exprs={1},{2}", newheading, exprs.Count(), orderexps.Count()); var numacc = exprs.Where(e => e.HasFold).Sum(e => e.AccumCount); var newtable = DataTableLocal.Create(newheading); var newexprs = newtable.Heading.Reorder(exprs); var ordidx = OrderedIndex.Create(orderexps, Heading); // list of indexes of not-folded columns var notfold = exprs.Where(e => !e.HasFold) .Select(e => newheading.FindIndex(e.Name)).ToArray(); // Build index for (var ord = 0; ord < Cardinality; ++ord) //TODO:Enumerable { ordidx.Add(GetRow(ord), ord); } AccumulatorBlock accblk = null; // Read in index order, with access to ordering info DataRow lastrow = null; foreach (var ord in ordidx.RowOrdinals) { var oldrow = _rows[ord]; oldrow.OrderedIndex = ordidx; // so row functions can access it // if there is a group break, reset the accumulators if (ordidx.IsBreak) { accblk = AccumulatorBlock.Create(numacc); } DataRow newrow = oldrow.TransformAggregate(newheading, accblk, newexprs); // save the current row, output it on group break or when any non-fold column has changed // any rows not output will have identical non-fold cols so only running sums are lost var nfchg = (lastrow != null && !notfold.All(x => newrow.Values[x].Equals(lastrow.Values[x]))); if (nfchg || (lastrow != null && ordidx.IsBreak)) { newtable.AddRaw(lastrow); } lastrow = newrow; // guaranteed to be different! } if (lastrow != null) { newtable.AddRaw(lastrow); } Logger.WriteLine(4, "[{0}]", newtable); return(newtable); }
// Return ordinal value for row, optionally within group public NumberValue Ordinal(bool isgroup) { var ret = isgroup ? OrderedIndex.Offset(this, 0, OffsetModes.Absolute) : Order; return(NumberValue.Create(ret)); }