// initialization: enqueue all vertex nodes protected void InitByInsertBasicTables(JoinGraph graph) { graph_ = graph; foreach (var logic in graph.vertices_) { BitVector contained = 1 << graph.vertices_.IndexOf(logic); logic.tableContained_ = contained; if (graph.memo_ is null) { bestTree_[contained] = new PhysicScanTable(logic); } else { // vertices are already inserted into memo var cgroup = graph.memo_.LookupCGroup(logic); var logicref = new LogicMemoRef(cgroup); bestTree_[contained] = new PhysicMemoRef(logicref); } } }
override internal PhysicNode Run(JoinGraph graph, BigInteger expectC1) { int ntables = graph.vertices_.Count; var Trees = new List <PhysicNode>(); Console.WriteLine("GOO #tables: " + ntables); // Treees = {R1, R2, ..., Rn} graph_ = graph; foreach (var logic in graph.vertices_) { BitVector contained = 1 << graph.vertices_.IndexOf(logic); logic.tableContained_ = contained; if (graph.memo_ is null) { Trees.Add(new PhysicScanTable(logic)); } else { // vertices are already inserted into memo var cgroup = graph.memo_.LookupCGroup(logic); var logicref = new LogicMemoRef(cgroup); Trees.Add(new PhysicMemoRef(logicref)); } } while (Trees.Count != 1) { PhysicNode Ti = null, Tj = null; PhysicNode bestJoin = null; // find Ti, Tj in Trees s.t. i < j (avoid duplicates) and TixTj is minimal for (int i = 0; i < Trees.Count; i++) { for (int j = i + 1; j < Trees.Count; j++) { var join = CreateMinimalJoinTree(Trees[i], Trees[j], true); if (bestJoin == null || join.Cost() < bestJoin.Cost()) { bestJoin = join; Ti = Trees[i]; Tj = Trees[j]; } } } Debug.Assert(Ti != null && Tj != null); Trees.Remove(Ti); Trees.Remove(Tj); Trees.Add(bestJoin); } // compare with DPccp solver // ideally, DPccp shall always generate better plans since GOO is heuristic - but DPccp does not consider // CP, so in some cases where CP is beneficial, GOO can win // var result = Trees[0]; var dpccp = new DPccp().Run(graph, expectC1); Console.WriteLine(result); if (dpccp.InclusiveCost() < result.InclusiveCost()) { Console.WriteLine("warning: GOO non optimal plan: {0} vs. {1}", dpccp.InclusiveCost(), result.InclusiveCost()); } if (dpccp.Cost() > result.Cost()) { Console.WriteLine("warning: DPCC shall consider CP in the case: {0} vs. {1}", dpccp.InclusiveCost(), result.InclusiveCost()); } return(result); }