### Question:
JoinOptimizer { public double estimateJoinCost(LogicalJoinNode j, int card1, int card2, double cost1, double cost2) { if (j instanceof LogicalSubplanJoinNode) { return card1 + cost1 + cost2; } else { double cost=-1.0; if(j.p== Predicate.Op.EQUALS){ cost=cost1+cost2+card1*card2; }else { int blockSize=10; cost = cost1 + cost1/(blockSize-1) * cost2 + (double) card1 * (double) card2; } return cost; } } JoinOptimizer(LogicalPlan p, Vector<LogicalJoinNode> joins); static DbIterator instantiateJoin(LogicalJoinNode lj,
            DbIterator plan1, DbIterator plan2); double estimateJoinCost(LogicalJoinNode j, int card1, int card2,
            double cost1, double cost2); int estimateJoinCardinality(LogicalJoinNode j, int card1, int card2,
            boolean t1pkey, boolean t2pkey, Map<String, TableStats> stats); static int estimateTableJoinCardinality(Predicate.Op joinOp,
            String table1Alias, String table2Alias, String field1PureName,
            String field2PureName, int card1, int card2, boolean t1pkey,
            boolean t2pkey, Map<String, TableStats> stats,
            Map<String, Integer> tableAliasToId); @SuppressWarnings("unchecked") Set<Set<T>> enumerateSubsets(Vector<T> v, int size); Vector<LogicalJoinNode> orderJoins(
            HashMap<String, TableStats> stats,
            HashMap<String, Double> filterSelectivities, boolean explain);  }### Answer:
@Test public void estimateJoinCostTest() throws ParsingException { TransactionId tid = new TransactionId(); JoinOptimizer jo; Parser p = new Parser(); jo = new JoinOptimizer(p.generateLogicalPlan(tid, "SELECT * FROM " + tableName1 + " t1, " + tableName2 + " t2 WHERE t1.c1 = t2.c2;"), new Vector<LogicalJoinNode>()); LogicalJoinNode equalsJoinNode = new LogicalJoinNode(tableName1, tableName2, Integer.toString(1), Integer.toString(2), Predicate.Op.EQUALS); checkJoinEstimateCosts(jo, equalsJoinNode); jo = new JoinOptimizer(p.generateLogicalPlan(tid, "SELECT * FROM " + tableName1 + " t1, " + tableName2 + " t2 WHERE t1.c1 = t2.c2;"), new Vector<LogicalJoinNode>()); equalsJoinNode = new LogicalJoinNode(tableName2, tableName1, Integer.toString(2), Integer.toString(1), Predicate.Op.EQUALS); checkJoinEstimateCosts(jo, equalsJoinNode); jo = new JoinOptimizer(p.generateLogicalPlan(tid, "SELECT * FROM " + tableName1 + " t1, " + tableName1 + " t2 WHERE t1.c3 = t2.c4;"), new Vector<LogicalJoinNode>()); equalsJoinNode = new LogicalJoinNode(tableName1, tableName1, Integer.toString(3), Integer.toString(4), Predicate.Op.EQUALS); checkJoinEstimateCosts(jo, equalsJoinNode); jo = new JoinOptimizer(p.generateLogicalPlan(tid, "SELECT * FROM " + tableName2 + " t1, " + tableName2 + " t2 WHERE t1.c8 = t2.c7;"), new Vector<LogicalJoinNode>()); equalsJoinNode = new LogicalJoinNode(tableName2, tableName2, Integer.toString(8), Integer.toString(7), Predicate.Op.EQUALS); checkJoinEstimateCosts(jo, equalsJoinNode); }