IEnumerable <BitVector> enumerateCmp(JoinGraph graph, BitVector S1) { int ntables = graph.vertices_.Count; Debug.Assert(S1 != SetOp.EmptySet); // min(S1) := min({i|v_i \in S1}) int minS1 = SetOp.MinTableIndex(S1); // B_i(W) := {vj |v_j \in W, j <= i} // X = union (B_min(S1), S) BitVector BminS1 = SetOp.OrderBeforeSet(minS1); BitVector X = SetOp.Union(BminS1, S1); // N = neighbour(S1) \ X BitVector N = SetOp.Substract(graph.NeighboursExcluding(S1), X); // for all(vi 2 N by descending i) foreach (int vi in SetOp.TablesDescending(N)) { // emit {v_i} BitVector VI = SetOp.SingletonSet(vi); yield return(VI); // recursively invoke enumerateCmp(graph, {v_i}, X union (B_i intersect N)) BitVector Bi = SetOp.OrderBeforeSet(vi); BitVector BiN = SetOp.Intersect(Bi, N); foreach (var csg in enumerateCsgRecursive(graph, VI, SetOp.Union(X, BiN))) { yield return(csg); } } }
// read through join exprs and mark the contain join bits // say T2.a = T5.a // T2 is at tables_[3] and T5 is at tables_[7] // then // joinbits_[3].bits_.Set(7) // joinbits_[7].bits_.Set(3) // void markJoinBitsFromJoinPred(List <Expr> preds) { var npreds = preds.Count; predContained_ = new List <BitVector>(npreds); for (int i = 0; i < npreds; i++) { var p = preds[i]; var i12 = ParseJoinPredExpr(p); int i1 = i12[0], i2 = i12[1]; // there could be multiple join predicates between two relations // so no need to verify duplicates here (!joinbits_[i1][i2]) joinbits_[i1][i2] = true; joinbits_[i2][i1] = true; // mark predicate containage as well predContained_.Add(SetOp.SingletonSet(i1) | SetOp.SingletonSet(i2)); } }
IEnumerable <BitVector> enumerateCsg(JoinGraph graph) { int ntables = graph.vertices_.Count; for (int i = ntables - 1; i >= 0; i--) { // emit S // S: {vi} BitVector VI = SetOp.SingletonSet(i); // Console.WriteLine("S: {0}", i); yield return(VI); // EnumerateCsgRec (G, S, X) // X: {vj|j<=i} BitVector X = SetOp.OrderBeforeSet(i); foreach (var csg in enumerateCsgRecursive(graph, VI, X)) { yield return(csg); } } }