public void Populate() { if (DefinitionType == TableDefinitionType.FREE) { return; // Nothing to do } Length = 0; if (DefinitionType == TableDefinitionType.PROJECTION) // There are import dimensions so copy data from another set (projection of another set) { List<DcColumn> inColumns = InputColumns.Where(d => d.GetData().IsAppendData).ToList(); foreach(DcColumn inColumn in inColumns) { inColumn.GetData().Translate(); inColumn.GetData().Evaluate(); // Delegate to column evaluation - it will add records from column expression } } else if (DefinitionType == TableDefinitionType.PRODUCT) // Product of local sets (no project/de-project from another set) { // Input variable for where formula DcVariable thisVariable = new Variable(this.Schema.Name, this.Name, "this"); thisVariable.TypeSchema = this.Schema; thisVariable.TypeTable = this; // Evaluator expression for where formula ExprNode outputExpr = this.WhereExpr; if(outputExpr != null) { outputExpr.OutputVariable.SchemaName = this.Schema.Name; outputExpr.OutputVariable.TypeName = "Boolean"; outputExpr.OutputVariable.TypeSchema = this.Schema; outputExpr.OutputVariable.TypeTable = this.Schema.GetPrimitiveType("Boolean"); outputExpr.Resolve(this.Space, new List<DcVariable>() { thisVariable }); outputExpr.EvaluateBegin(); } DcTableWriter tableWriter = this.GetTableWriter(); tableWriter.Open(); // // Find all local greater dimensions to be varied (including the super-dim) // DcColumn[] cols = Columns.Where(x => x.IsKey && !x.IsPrimitive).ToArray(); int colCount = cols.Length; // Dimensionality - how many free dimensions object[] vals = new object[colCount]; // A record with values for each free dimension being varied // Prepare columns foreach (DcColumn col in cols) { col.GetData().AutoIndex = true; // We need true to correctly evaluate where condition and correctly remove last element if it is wrong //col.GetData().Nullify(); } // // The current state of the search procedure // Rowid[] lengths = new Rowid[colCount]; // Size of each dimension being varied (how many offsets in each dimension) for (int i = 0; i < colCount; i++) lengths[i] = cols[i].Output.GetData().Length; Rowid[] offsets = new Rowid[colCount]; // The current point/offset for each dimensions during search for (int i = 0; i < colCount; i++) offsets[i] = -1; int top = -1; // The current level/top where we change the offset. Depth of recursion. do ++top; while (top < colCount && lengths[top] == 0); // Alternative recursive iteration: http://stackoverflow.com/questions/13655299/c-sharp-most-efficient-way-to-iterate-through-multiple-arrays-list while (top >= 0) { if (top == colCount) // New element is ready. Process it. { // Initialize a record and append it for (int i = 0; i < colCount; i++) { vals[i] = offsets[i]; } Rowid input = tableWriter.Append(cols, vals); // // Now check if this appended element satisfies the where expression and if not then remove it // if (outputExpr != null) { // Set 'this' variable to the last elements (that has been just appended) which will be read by the expression thisVariable.SetValue(this.GetData().Length - 1); // Evaluate expression outputExpr.Evaluate(); bool satisfies = (bool)outputExpr.OutputVariable.GetValue(); if (!satisfies) { Length = Length - 1; // Remove elements } } top--; while (top >= 0 && lengths[top] == 0) // Go up by skipping empty dimensions and reseting { offsets[top--] = -1; } } else { // Find the next valid offset offsets[top]++; if (offsets[top] < lengths[top]) // Offset chosen { do ++top; while (top < colCount && lengths[top] == 0); // Go up (forward) by skipping empty dimensions } else // Level is finished. Go back. { do { offsets[top--] = -1; } while (top >= 0 && lengths[top] == 0); // Go down (backward) by skipping empty dimensions and reseting } } } // Prepare columns foreach (DcColumn col in cols) { col.GetData().Reindex(); col.GetData().AutoIndex = true; } if (tableWriter != null) { tableWriter.Close(); } if (outputExpr != null) { outputExpr.EvaluateEnd(); } } else { throw new NotImplementedException("This table definition type is not implemented and cannot be populated."); } }