--- src/backend/optimizer/geqo/Makefile | 1 + src/backend/optimizer/geqo/geqo_copy.c | 4 +- src/backend/optimizer/geqo/geqo_cx.c | 6 +- src/backend/optimizer/geqo/geqo_erx.c | 47 ++++++------ src/backend/optimizer/geqo/geqo_eval.c | 28 ++++---- src/backend/optimizer/geqo/geqo_main.c | 90 ++++++++++++----------- src/backend/optimizer/geqo/geqo_mutation.c | 10 +- src/backend/optimizer/geqo/geqo_ox1.c | 8 +- src/backend/optimizer/geqo/geqo_ox2.c | 7 +- src/backend/optimizer/geqo/geqo_pmx.c | 7 +- src/backend/optimizer/geqo/geqo_pool.c | 23 +++--- src/backend/optimizer/geqo/geqo_px.c | 8 +- src/backend/optimizer/geqo/geqo_random.c | 42 +++++++++++ src/backend/optimizer/geqo/geqo_recombination.c | 9 +- src/backend/optimizer/geqo/geqo_selection.c | 19 +++-- src/backend/optimizer/path/allpaths.c | 2 + src/backend/utils/misc/guc.c | 9 ++ src/include/nodes/relation.h | 3 + src/include/optimizer/geqo.h | 17 ++--- src/include/optimizer/geqo_copy.h | 3 +- src/include/optimizer/geqo_mutation.h | 3 +- src/include/optimizer/geqo_pool.h | 14 ++-- src/include/optimizer/geqo_random.h | 9 +- src/include/optimizer/geqo_recombination.h | 33 +++++--- src/include/optimizer/geqo_selection.h | 4 +- 25 files changed, 244 insertions(+), 162 deletions(-) create mode 100644 src/backend/optimizer/geqo/geqo_random.c
diff --git a/src/backend/optimizer/geqo/Makefile b/src/backend/optimizer/geqo/Makefile index dbc6c28..e5a01d7 100644 *** a/src/backend/optimizer/geqo/Makefile --- b/src/backend/optimizer/geqo/Makefile *************** top_builddir = ../../../.. *** 14,19 **** --- 14,20 ---- include $(top_builddir)/src/Makefile.global OBJS = geqo_copy.o geqo_eval.o geqo_main.o geqo_misc.o \ + geqo_random.o \ geqo_mutation.o geqo_pool.o geqo_recombination.o \ geqo_selection.o \ geqo_erx.o geqo_pmx.o geqo_cx.o geqo_px.o geqo_ox1.o geqo_ox2.o diff --git a/src/backend/optimizer/geqo/geqo_copy.c b/src/backend/optimizer/geqo/geqo_copy.c index 83af33a..373a924 100644 *** a/src/backend/optimizer/geqo/geqo_copy.c --- b/src/backend/optimizer/geqo/geqo_copy.c *************** *** 35,40 **** --- 35,41 ---- #include "postgres.h" #include "optimizer/geqo_copy.h" + #include "optimizer/geqo_copy.h" /* geqo_copy * *************** *** 42,48 **** * */ void ! geqo_copy(Chromosome *chromo1, Chromosome *chromo2, int string_length) { int i; --- 43,50 ---- * */ void ! geqo_copy(PlannerInfo *root, Chromosome *chromo1, Chromosome *chromo2, ! int string_length) { int i; diff --git a/src/backend/optimizer/geqo/geqo_cx.c b/src/backend/optimizer/geqo/geqo_cx.c index 3d5102f..ad861ce 100644 *** a/src/backend/optimizer/geqo/geqo_cx.c --- b/src/backend/optimizer/geqo/geqo_cx.c *************** *** 35,40 **** --- 35,41 ---- #include "postgres.h" + #include "optimizer/geqo.h" #include "optimizer/geqo_recombination.h" #include "optimizer/geqo_random.h" *************** *** 44,50 **** * cycle crossover */ int ! cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int i, --- 45,52 ---- * cycle crossover */ int ! cx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, ! int num_gene, City *city_table) { int i, *************** cx(Gene *tour1, Gene *tour2, Gene *offsp *** 62,68 **** } /* choose random cycle starting position */ ! start_pos = geqo_randint(num_gene - 1, 0); /* child inherits first city */ offspring[start_pos] = tour1[start_pos]; --- 64,70 ---- } /* choose random cycle starting position */ ! start_pos = geqo_randint(root, num_gene - 1, 0); /* child inherits first city */ offspring[start_pos] = tour1[start_pos]; diff --git a/src/backend/optimizer/geqo/geqo_erx.c b/src/backend/optimizer/geqo/geqo_erx.c index 35e1a28..5bae059 100644 *** a/src/backend/optimizer/geqo/geqo_erx.c --- b/src/backend/optimizer/geqo/geqo_erx.c *************** *** 36,46 **** #include "optimizer/geqo_random.h" ! static int gimme_edge(Gene gene1, Gene gene2, Edge *edge_table); ! static void remove_gene(Gene gene, Edge edge, Edge *edge_table); ! static Gene gimme_gene(Edge edge, Edge *edge_table); ! static Gene edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene); /* alloc_edge_table --- 36,46 ---- #include "optimizer/geqo_random.h" ! static int gimme_edge(PlannerInfo *root, Gene gene1, Gene gene2, Edge *edge_table); ! static void remove_gene(PlannerInfo *root, Gene gene, Edge edge, Edge *edge_table); ! static Gene gimme_gene(PlannerInfo *root, Edge edge, Edge *edge_table); ! static Gene edge_failure(PlannerInfo *root, Gene *gene, int index, Edge *edge_table, int num_gene); /* alloc_edge_table *************** static Gene edge_failure(Gene *gene, int *** 50,56 **** */ Edge * ! alloc_edge_table(int num_gene) { Edge *edge_table; --- 50,56 ---- */ Edge * ! alloc_edge_table(PlannerInfo *root, int num_gene) { Edge *edge_table; *************** alloc_edge_table(int num_gene) *** 70,76 **** * */ void ! free_edge_table(Edge *edge_table) { pfree(edge_table); } --- 70,76 ---- * */ void ! free_edge_table(PlannerInfo *root, Edge *edge_table) { pfree(edge_table); } *************** free_edge_table(Edge *edge_table) *** 89,95 **** * */ float ! gimme_edge_table(Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table) { int i, index1, --- 89,96 ---- * */ float ! gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2, ! int num_gene, Edge *edge_table) { int i, index1, *************** gimme_edge_table(Gene *tour1, Gene *tour *** 121,131 **** * twice per edge */ ! edge_total += gimme_edge(tour1[index1], tour1[index2], edge_table); ! gimme_edge(tour1[index2], tour1[index1], edge_table); ! edge_total += gimme_edge(tour2[index1], tour2[index2], edge_table); ! gimme_edge(tour2[index2], tour2[index1], edge_table); } /* return average number of edges per index */ --- 122,132 ---- * twice per edge */ ! edge_total += gimme_edge(root, tour1[index1], tour1[index2], edge_table); ! gimme_edge(root, tour1[index2], tour1[index1], edge_table); ! edge_total += gimme_edge(root, tour2[index1], tour2[index2], edge_table); ! gimme_edge(root, tour2[index2], tour2[index1], edge_table); } /* return average number of edges per index */ *************** gimme_edge_table(Gene *tour1, Gene *tour *** 147,153 **** * 0 if edge was already registered and edge_table is unchanged */ static int ! gimme_edge(Gene gene1, Gene gene2, Edge *edge_table) { int i; int edges; --- 148,154 ---- * 0 if edge was already registered and edge_table is unchanged */ static int ! gimme_edge(PlannerInfo *root, Gene gene1, Gene gene2, Edge *edge_table) { int i; int edges; *************** gimme_edge(Gene gene1, Gene gene2, Edge *** 189,200 **** * */ int ! gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene) { int i; int edge_failures = 0; ! new_gene[0] = (Gene) geqo_randint(num_gene, 1); /* choose int between 1 * and num_gene */ for (i = 1; i < num_gene; i++) --- 190,201 ---- * */ int ! gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, int num_gene) { int i; int edge_failures = 0; ! new_gene[0] = (Gene) geqo_randint(root, num_gene, 1); /* choose int between 1 * and num_gene */ for (i = 1; i < num_gene; i++) *************** gimme_tour(Edge *edge_table, Gene *new_g *** 204,221 **** * table */ ! remove_gene(new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table); /* find destination for the newly entered point */ if (edge_table[new_gene[i - 1]].unused_edges > 0) ! new_gene[i] = gimme_gene(edge_table[(int) new_gene[i - 1]], edge_table); else { /* cope with fault */ edge_failures++; ! new_gene[i] = edge_failure(new_gene, i - 1, edge_table, num_gene); } /* mark this node as incorporated */ --- 205,222 ---- * table */ ! remove_gene(root, new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table); /* find destination for the newly entered point */ if (edge_table[new_gene[i - 1]].unused_edges > 0) ! new_gene[i] = gimme_gene(root, edge_table[(int) new_gene[i - 1]], edge_table); else { /* cope with fault */ edge_failures++; ! new_gene[i] = edge_failure(root, new_gene, i - 1, edge_table, num_gene); } /* mark this node as incorporated */ *************** gimme_tour(Edge *edge_table, Gene *new_g *** 235,241 **** * */ static void ! remove_gene(Gene gene, Edge edge, Edge *edge_table) { int i, j; --- 236,242 ---- * */ static void ! remove_gene(PlannerInfo *root, Gene gene, Edge edge, Edge *edge_table) { int i, j; *************** remove_gene(Gene gene, Edge edge, Edge * *** 277,283 **** * */ static Gene ! gimme_gene(Edge edge, Edge *edge_table) { int i; Gene friend; --- 278,284 ---- * */ static Gene ! gimme_gene(PlannerInfo *root, Edge edge, Edge *edge_table) { int i; Gene friend; *************** gimme_gene(Edge edge, Edge *edge_table) *** 340,346 **** /* random decision of the possible candidates to use */ ! rand_decision = (int) geqo_randint(minimum_count - 1, 0); for (i = 0; i < edge.unused_edges; i++) --- 341,347 ---- /* random decision of the possible candidates to use */ ! rand_decision = geqo_randint(root, minimum_count - 1, 0); for (i = 0; i < edge.unused_edges; i++) *************** gimme_gene(Edge edge, Edge *edge_table) *** 368,374 **** * */ static Gene ! edge_failure(Gene *gene, int index, Edge *edge_table, int num_gene) { int i; Gene fail_gene = gene[index]; --- 369,375 ---- * */ static Gene ! edge_failure(PlannerInfo *root, Gene *gene, int index, Edge *edge_table, int num_gene) { int i; Gene fail_gene = gene[index]; *************** edge_failure(Gene *gene, int index, Edge *** 401,407 **** if (four_count != 0) { ! rand_decision = (int) geqo_randint(four_count - 1, 0); for (i = 1; i <= num_gene; i++) { --- 402,408 ---- if (four_count != 0) { ! rand_decision = geqo_randint(root, four_count - 1, 0); for (i = 1; i <= num_gene; i++) { *************** edge_failure(Gene *gene, int index, Edge *** 423,429 **** else if (remaining_edges != 0) { /* random decision of the gene with remaining edges */ ! rand_decision = (int) geqo_randint(remaining_edges - 1, 0); for (i = 1; i <= num_gene; i++) { --- 424,430 ---- else if (remaining_edges != 0) { /* random decision of the gene with remaining edges */ ! rand_decision = geqo_randint(root, remaining_edges - 1, 0); for (i = 1; i <= num_gene; i++) { diff --git a/src/backend/optimizer/geqo/geqo_eval.c b/src/backend/optimizer/geqo/geqo_eval.c index 04b3bfe..11903a5 100644 *** a/src/backend/optimizer/geqo/geqo_eval.c --- b/src/backend/optimizer/geqo/geqo_eval.c *************** static bool desirable_join(PlannerInfo * *** 42,48 **** * Returns cost of a query tree as an individual of the population. */ Cost ! geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata) { MemoryContext mycontext; MemoryContext oldcxt; --- 42,48 ---- * Returns cost of a query tree as an individual of the population. */ Cost ! geqo_eval(PlannerInfo *root, Gene *tour, int num_gene) { MemoryContext mycontext; MemoryContext oldcxt; *************** geqo_eval(Gene *tour, int num_gene, Geqo *** 94,106 **** * (If we are dealing with enough join rels, which we very likely are, a * new hash table will get built and used locally.) */ ! savelength = list_length(evaldata->root->join_rel_list); ! savehash = evaldata->root->join_rel_hash; ! evaldata->root->join_rel_hash = NULL; /* construct the best path for the given combination of relations */ ! joinrel = gimme_tree(tour, num_gene, evaldata); /* * compute fitness --- 94,106 ---- * (If we are dealing with enough join rels, which we very likely are, a * new hash table will get built and used locally.) */ ! savelength = list_length(root->join_rel_list); ! savehash = root->join_rel_hash; ! root->join_rel_hash = NULL; /* construct the best path for the given combination of relations */ ! joinrel = gimme_tree(root, tour, num_gene); /* * compute fitness *************** geqo_eval(Gene *tour, int num_gene, Geqo *** 117,125 **** * Restore join_rel_list to its former state, and put back original * hashtable if any. */ ! evaldata->root->join_rel_list = list_truncate(evaldata->root->join_rel_list, ! savelength); ! evaldata->root->join_rel_hash = savehash; /* release all the memory acquired within gimme_tree */ MemoryContextSwitchTo(oldcxt); --- 117,125 ---- * Restore join_rel_list to its former state, and put back original * hashtable if any. */ ! root->join_rel_list = list_truncate(root->join_rel_list, ! savelength); ! root->join_rel_hash = savehash; /* release all the memory acquired within gimme_tree */ MemoryContextSwitchTo(oldcxt); *************** geqo_eval(Gene *tour, int num_gene, Geqo *** 134,140 **** * order. * * 'tour' is the proposed join order, of length 'num_gene' - * 'evaldata' contains the context we need * * Returns a new join relation whose cheapest path is the best plan for * this join order. NB: will return NULL if join order is invalid. --- 134,139 ---- *************** geqo_eval(Gene *tour, int num_gene, Geqo *** 153,159 **** * plans. */ RelOptInfo * ! gimme_tree(Gene *tour, int num_gene, GeqoEvalData *evaldata) { RelOptInfo **stack; int stack_depth; --- 152,158 ---- * plans. */ RelOptInfo * ! gimme_tree(PlannerInfo *root, Gene *tour, int num_gene) { RelOptInfo **stack; int stack_depth; *************** gimme_tree(Gene *tour, int num_gene, Geq *** 193,200 **** /* Get the next input relation and push it */ cur_rel_index = (int) tour[rel_count]; ! stack[stack_depth] = (RelOptInfo *) list_nth(evaldata->initial_rels, ! cur_rel_index - 1); stack_depth++; /* --- 192,200 ---- /* Get the next input relation and push it */ cur_rel_index = (int) tour[rel_count]; ! stack[stack_depth] = (RelOptInfo *) list_nth( ! ((GeqoPrivateData*)root->join_search_private)->initial_rels, ! cur_rel_index - 1); stack_depth++; /* *************** gimme_tree(Gene *tour, int num_gene, Geq *** 211,217 **** * have exhausted the input, the heuristics can't prevent popping. */ if (rel_count < num_gene - 1 && ! !desirable_join(evaldata->root, outer_rel, inner_rel)) break; /* --- 211,217 ---- * have exhausted the input, the heuristics can't prevent popping. */ if (rel_count < num_gene - 1 && ! !desirable_join(root, outer_rel, inner_rel)) break; /* *************** gimme_tree(Gene *tour, int num_gene, Geq *** 220,226 **** * root->join_rel_list yet, and so the paths constructed for it * will only include the ones we want. */ ! joinrel = make_join_rel(evaldata->root, outer_rel, inner_rel); /* Can't pop stack here if join order is not valid */ if (!joinrel) --- 220,226 ---- * root->join_rel_list yet, and so the paths constructed for it * will only include the ones we want. */ ! joinrel = make_join_rel(root, outer_rel, inner_rel); /* Can't pop stack here if join order is not valid */ if (!joinrel) diff --git a/src/backend/optimizer/geqo/geqo_main.c b/src/backend/optimizer/geqo/geqo_main.c index 72b0b57..10f64f4 100644 *** a/src/backend/optimizer/geqo/geqo_main.c --- b/src/backend/optimizer/geqo/geqo_main.c *************** *** 29,34 **** --- 29,35 ---- #include "optimizer/geqo_misc.h" #include "optimizer/geqo_pool.h" #include "optimizer/geqo_selection.h" + #include "optimizer/geqo_random.h" /* *************** int Geqo_effort; *** 38,43 **** --- 39,45 ---- int Geqo_pool_size; int Geqo_generations; double Geqo_selection_bias; + double Geqo_seed; static int gimme_pool_size(int nr_rel); *************** static int gimme_number_generations(int *** 63,69 **** RelOptInfo * geqo(PlannerInfo *root, int number_of_rels, List *initial_rels) { - GeqoEvalData evaldata; int generation; Chromosome *momma; Chromosome *daddy; --- 65,70 ---- *************** geqo(PlannerInfo *root, int number_of_re *** 88,96 **** int mutations = 0; #endif ! /* set up evaldata */ ! evaldata.root = root; ! evaldata.initial_rels = initial_rels; /* set GA parameters */ pool_size = gimme_pool_size(number_of_rels); --- 89,102 ---- int mutations = 0; #endif ! /* setup private information */ ! root->join_search_private = (GeqoPrivateData*)palloc0(sizeof(GeqoPrivateData)); ! ((GeqoPrivateData*)root->join_search_private)->initial_rels = initial_rels; ! ! /* initialize private number generator */ ! if(Geqo_seed != 0){ ! geqo_seed(root, Geqo_seed); ! } /* set GA parameters */ pool_size = gimme_pool_size(number_of_rels); *************** geqo(PlannerInfo *root, int number_of_re *** 98,110 **** status_interval = 10; /* allocate genetic pool memory */ ! pool = alloc_pool(pool_size, number_of_rels); /* random initialization of the pool */ ! random_init_pool(pool, &evaldata); /* sort the pool according to cheapest path as fitness */ ! sort_pool(pool); /* we have to do it only one time, since all * kids replace the worst individuals in * future (-> geqo_pool.c:spread_chromo ) */ --- 104,116 ---- status_interval = 10; /* allocate genetic pool memory */ ! pool = alloc_pool(root, pool_size, number_of_rels); /* random initialization of the pool */ ! random_init_pool(root, pool); /* sort the pool according to cheapest path as fitness */ ! sort_pool(root, pool); /* we have to do it only one time, since all * kids replace the worst individuals in * future (-> geqo_pool.c:spread_chromo ) */ *************** geqo(PlannerInfo *root, int number_of_re *** 116,164 **** #endif /* allocate chromosome momma and daddy memory */ ! momma = alloc_chromo(pool->string_length); ! daddy = alloc_chromo(pool->string_length); #if defined (ERX) #ifdef GEQO_DEBUG elog(DEBUG2, "using edge recombination crossover [ERX]"); #endif /* allocate edge table memory */ ! edge_table = alloc_edge_table(pool->string_length); #elif defined(PMX) #ifdef GEQO_DEBUG elog(DEBUG2, "using partially matched crossover [PMX]"); #endif /* allocate chromosome kid memory */ ! kid = alloc_chromo(pool->string_length); #elif defined(CX) #ifdef GEQO_DEBUG elog(DEBUG2, "using cycle crossover [CX]"); #endif /* allocate city table memory */ ! kid = alloc_chromo(pool->string_length); ! city_table = alloc_city_table(pool->string_length); #elif defined(PX) #ifdef GEQO_DEBUG elog(DEBUG2, "using position crossover [PX]"); #endif /* allocate city table memory */ ! kid = alloc_chromo(pool->string_length); ! city_table = alloc_city_table(pool->string_length); #elif defined(OX1) #ifdef GEQO_DEBUG elog(DEBUG2, "using order crossover [OX1]"); #endif /* allocate city table memory */ kid = alloc_chromo(pool->string_length); ! city_table = alloc_city_table(pool->string_length); #elif defined(OX2) #ifdef GEQO_DEBUG elog(DEBUG2, "using order crossover [OX2]"); #endif /* allocate city table memory */ kid = alloc_chromo(pool->string_length); ! city_table = alloc_city_table(pool->string_length); #endif --- 122,170 ---- #endif /* allocate chromosome momma and daddy memory */ ! momma = alloc_chromo(root, pool->string_length); ! daddy = alloc_chromo(root, pool->string_length); #if defined (ERX) #ifdef GEQO_DEBUG elog(DEBUG2, "using edge recombination crossover [ERX]"); #endif /* allocate edge table memory */ ! edge_table = alloc_edge_table(root, pool->string_length); #elif defined(PMX) #ifdef GEQO_DEBUG elog(DEBUG2, "using partially matched crossover [PMX]"); #endif /* allocate chromosome kid memory */ ! kid = alloc_chromo(root, pool->string_length); #elif defined(CX) #ifdef GEQO_DEBUG elog(DEBUG2, "using cycle crossover [CX]"); #endif /* allocate city table memory */ ! kid = alloc_chromo(root, pool->string_length); ! city_table = alloc_city_table(root, pool->string_length); #elif defined(PX) #ifdef GEQO_DEBUG elog(DEBUG2, "using position crossover [PX]"); #endif /* allocate city table memory */ ! kid = alloc_chromo(root, pool->string_length); ! city_table = alloc_city_table(root, pool->string_length); #elif defined(OX1) #ifdef GEQO_DEBUG elog(DEBUG2, "using order crossover [OX1]"); #endif /* allocate city table memory */ kid = alloc_chromo(pool->string_length); ! city_table = alloc_city_table(root, pool->string_length); #elif defined(OX2) #ifdef GEQO_DEBUG elog(DEBUG2, "using order crossover [OX2]"); #endif /* allocate city table memory */ kid = alloc_chromo(pool->string_length); ! city_table = alloc_city_table(root, pool->string_length); #endif *************** geqo(PlannerInfo *root, int number_of_re *** 168,212 **** for (generation = 0; generation < number_generations; generation++) { /* SELECTION: using linear bias function */ ! geqo_selection(momma, daddy, pool, Geqo_selection_bias); #if defined (ERX) /* EDGE RECOMBINATION CROSSOVER */ ! difference = gimme_edge_table(momma->string, daddy->string, pool->string_length, edge_table); kid = momma; /* are there any edge failures ? */ ! edge_failures += gimme_tour(edge_table, kid->string, pool->string_length); #elif defined(PMX) /* PARTIALLY MATCHED CROSSOVER */ ! pmx(momma->string, daddy->string, kid->string, pool->string_length); #elif defined(CX) /* CYCLE CROSSOVER */ ! cycle_diffs = cx(momma->string, daddy->string, kid->string, pool->string_length, city_table); /* mutate the child */ if (cycle_diffs == 0) { mutations++; ! geqo_mutation(kid->string, pool->string_length); } #elif defined(PX) /* POSITION CROSSOVER */ ! px(momma->string, daddy->string, kid->string, pool->string_length, city_table); #elif defined(OX1) /* ORDER CROSSOVER */ ! ox1(momma->string, daddy->string, kid->string, pool->string_length, city_table); #elif defined(OX2) /* ORDER CROSSOVER */ ! ox2(momma->string, daddy->string, kid->string, pool->string_length, city_table); #endif /* EVALUATE FITNESS */ ! kid->worth = geqo_eval(kid->string, pool->string_length, &evaldata); /* push the kid into the wilderness of life according to its worth */ ! spread_chromo(kid, pool); #ifdef GEQO_DEBUG --- 174,218 ---- for (generation = 0; generation < number_generations; generation++) { /* SELECTION: using linear bias function */ ! geqo_selection(root, momma, daddy, pool, Geqo_selection_bias); #if defined (ERX) /* EDGE RECOMBINATION CROSSOVER */ ! difference = gimme_edge_table(root, momma->string, daddy->string, pool->string_length, edge_table); kid = momma; /* are there any edge failures ? */ ! edge_failures += gimme_tour(root, edge_table, kid->string, pool->string_length); #elif defined(PMX) /* PARTIALLY MATCHED CROSSOVER */ ! pmx(root, momma->string, daddy->string, kid->string, pool->string_length); #elif defined(CX) /* CYCLE CROSSOVER */ ! cycle_diffs = cx(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); /* mutate the child */ if (cycle_diffs == 0) { mutations++; ! geqo_mutation(root, kid->string, pool->string_length); } #elif defined(PX) /* POSITION CROSSOVER */ ! px(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); #elif defined(OX1) /* ORDER CROSSOVER */ ! ox1(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); #elif defined(OX2) /* ORDER CROSSOVER */ ! ox2(root, momma->string, daddy->string, kid->string, pool->string_length, city_table); #endif /* EVALUATE FITNESS */ ! kid->worth = geqo_eval(root, kid->string, pool->string_length); /* push the kid into the wilderness of life according to its worth */ ! spread_chromo(root, kid, pool); #ifdef GEQO_DEBUG *************** geqo(PlannerInfo *root, int number_of_re *** 249,255 **** */ best_tour = (Gene *) pool->data[0].string; ! best_rel = gimme_tree(best_tour, pool->string_length, &evaldata); if (best_rel == NULL) elog(ERROR, "failed to make a valid plan"); --- 255,261 ---- */ best_tour = (Gene *) pool->data[0].string; ! best_rel = gimme_tree(root, best_tour, pool->string_length); if (best_rel == NULL) elog(ERROR, "failed to make a valid plan"); *************** geqo(PlannerInfo *root, int number_of_re *** 260,287 **** #endif /* ... free memory stuff */ ! free_chromo(momma); ! free_chromo(daddy); #if defined (ERX) ! free_edge_table(edge_table); #elif defined(PMX) ! free_chromo(kid); #elif defined(CX) ! free_chromo(kid); ! free_city_table(city_table); #elif defined(PX) ! free_chromo(kid); ! free_city_table(city_table); #elif defined(OX1) ! free_chromo(kid); ! free_city_table(city_table); #elif defined(OX2) ! free_chromo(kid); ! free_city_table(city_table); #endif ! free_pool(pool); return best_rel; } --- 266,293 ---- #endif /* ... free memory stuff */ ! free_chromo(root, momma); ! free_chromo(root, daddy); #if defined (ERX) ! free_edge_table(root, edge_table); #elif defined(PMX) ! free_chromo(root, kid); #elif defined(CX) ! free_chromo(root, kid); ! free_city_table(root, city_table); #elif defined(PX) ! free_chromo(root, kid); ! free_city_table(root, city_table); #elif defined(OX1) ! free_chromo(root, kid); ! free_city_table(root, city_table); #elif defined(OX2) ! free_chromo(root, kid); ! free_city_table(root, city_table); #endif ! free_pool(root, pool); return best_rel; } diff --git a/src/backend/optimizer/geqo/geqo_mutation.c b/src/backend/optimizer/geqo/geqo_mutation.c index 899410c..acf3b34 100644 *** a/src/backend/optimizer/geqo/geqo_mutation.c --- b/src/backend/optimizer/geqo/geqo_mutation.c *************** *** 36,56 **** #include "optimizer/geqo_random.h" void ! geqo_mutation(Gene *tour, int num_gene) { int swap1; int swap2; ! int num_swaps = geqo_randint(num_gene / 3, 0); Gene temp; while (num_swaps > 0) { ! swap1 = geqo_randint(num_gene - 1, 0); ! swap2 = geqo_randint(num_gene - 1, 0); while (swap1 == swap2) ! swap2 = geqo_randint(num_gene - 1, 0); temp = tour[swap1]; tour[swap1] = tour[swap2]; --- 36,56 ---- #include "optimizer/geqo_random.h" void ! geqo_mutation(PlannerInfo *root, Gene *tour, int num_gene) { int swap1; int swap2; ! int num_swaps = geqo_randint(root, num_gene / 3, 0); Gene temp; while (num_swaps > 0) { ! swap1 = geqo_randint(root, num_gene - 1, 0); ! swap2 = geqo_randint(root, num_gene - 1, 0); while (swap1 == swap2) ! swap2 = geqo_randint(root, num_gene - 1, 0); temp = tour[swap1]; tour[swap1] = tour[swap2]; diff --git a/src/backend/optimizer/geqo/geqo_ox1.c b/src/backend/optimizer/geqo/geqo_ox1.c index cd979df..d292e98 100644 *** a/src/backend/optimizer/geqo/geqo_ox1.c --- b/src/backend/optimizer/geqo/geqo_ox1.c *************** *** 34,39 **** --- 34,40 ---- /*************************************************************/ #include "postgres.h" + #include "optimizer/geqo.h" #include "optimizer/geqo_random.h" #include "optimizer/geqo_recombination.h" *************** *** 43,49 **** * position crossover */ void ! ox1(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int left, right, --- 44,51 ---- * position crossover */ void ! ox1(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, ! City *city_table) { int left, right, *************** ox1(Gene *tour1, Gene *tour2, Gene *offs *** 56,63 **** city_table[k].used = 0; /* select portion to copy from tour1 */ ! left = geqo_randint(num_gene - 1, 0); ! right = geqo_randint(num_gene - 1, 0); if (left > right) { --- 58,65 ---- city_table[k].used = 0; /* select portion to copy from tour1 */ ! left = geqo_randint(root, num_gene - 1, 0); ! right = geqo_randint(root, num_gene - 1, 0); if (left > right) { diff --git a/src/backend/optimizer/geqo/geqo_ox2.c b/src/backend/optimizer/geqo/geqo_ox2.c index 0d2e0de..a2fdfe8 100644 *** a/src/backend/optimizer/geqo/geqo_ox2.c --- b/src/backend/optimizer/geqo/geqo_ox2.c *************** *** 34,39 **** --- 34,40 ---- /*************************************************************/ #include "postgres.h" + #include "optimizer/geqo.h" #include "optimizer/geqo_random.h" #include "optimizer/geqo_recombination.h" *************** *** 43,49 **** * position crossover */ void ! ox2(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int k, j, --- 44,50 ---- * position crossover */ void ! ox2(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int k, j, *************** ox2(Gene *tour1, Gene *tour2, Gene *offs *** 60,71 **** } /* determine the number of positions to be inherited from tour1 */ ! num_positions = geqo_randint(2 * num_gene / 3, num_gene / 3); /* make a list of selected cities */ for (k = 0; k < num_positions; k++) { ! pos = geqo_randint(num_gene - 1, 0); city_table[pos].select_list = (int) tour1[pos]; city_table[(int) tour1[pos]].used = 1; /* mark used */ } --- 61,72 ---- } /* determine the number of positions to be inherited from tour1 */ ! num_positions = geqo_randint(root, 2 * num_gene / 3, num_gene / 3); /* make a list of selected cities */ for (k = 0; k < num_positions; k++) { ! pos = geqo_randint(root, num_gene - 1, 0); city_table[pos].select_list = (int) tour1[pos]; city_table[(int) tour1[pos]].used = 1; /* mark used */ } diff --git a/src/backend/optimizer/geqo/geqo_pmx.c b/src/backend/optimizer/geqo/geqo_pmx.c index fe9d4b4..a8d18c5 100644 *** a/src/backend/optimizer/geqo/geqo_pmx.c --- b/src/backend/optimizer/geqo/geqo_pmx.c *************** *** 34,39 **** --- 34,40 ---- /*************************************************************/ #include "postgres.h" + #include "optimizer/geqo.h" #include "optimizer/geqo_random.h" #include "optimizer/geqo_recombination.h" *************** *** 43,49 **** * partially matched crossover */ void ! pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene) { int *failed = (int *) palloc((num_gene + 1) * sizeof(int)); int *from = (int *) palloc((num_gene + 1) * sizeof(int)); --- 44,50 ---- * partially matched crossover */ void ! pmx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene) { int *failed = (int *) palloc((num_gene + 1) * sizeof(int)); int *from = (int *) palloc((num_gene + 1) * sizeof(int)); *************** pmx(Gene *tour1, Gene *tour2, Gene *offs *** 71,78 **** } /* locate crossover points */ ! left = geqo_randint(num_gene - 1, 0); ! right = geqo_randint(num_gene - 1, 0); if (left > right) { --- 72,79 ---- } /* locate crossover points */ ! left = geqo_randint(root, num_gene - 1, 0); ! right = geqo_randint(root, num_gene - 1, 0); if (left > right) { diff --git a/src/backend/optimizer/geqo/geqo_pool.c b/src/backend/optimizer/geqo/geqo_pool.c index 72eb34f..64e23ba 100644 *** a/src/backend/optimizer/geqo/geqo_pool.c --- b/src/backend/optimizer/geqo/geqo_pool.c *************** static int compare(const void *arg1, con *** 39,45 **** * allocates memory for GA pool */ Pool * ! alloc_pool(int pool_size, int string_length) { Pool *new_pool; Chromosome *chromo; --- 39,45 ---- * allocates memory for GA pool */ Pool * ! alloc_pool(PlannerInfo *root, int pool_size, int string_length) { Pool *new_pool; Chromosome *chromo; *************** alloc_pool(int pool_size, int string_len *** 66,72 **** * deallocates memory for GA pool */ void ! free_pool(Pool *pool) { Chromosome *chromo; int i; --- 66,72 ---- * deallocates memory for GA pool */ void ! free_pool(PlannerInfo *root, Pool *pool) { Chromosome *chromo; int i; *************** free_pool(Pool *pool) *** 88,94 **** * initialize genetic pool */ void ! random_init_pool(Pool *pool, GeqoEvalData *evaldata) { Chromosome *chromo = (Chromosome *) pool->data; int i; --- 88,94 ---- * initialize genetic pool */ void ! random_init_pool(PlannerInfo *root, Pool *pool) { Chromosome *chromo = (Chromosome *) pool->data; int i; *************** random_init_pool(Pool *pool, GeqoEvalDat *** 105,114 **** i = 0; while (i < pool->size) { ! init_tour(chromo[i].string, pool->string_length); ! pool->data[i].worth = geqo_eval(chromo[i].string, ! pool->string_length, ! evaldata); if (pool->data[i].worth < DBL_MAX) i++; else --- 105,113 ---- i = 0; while (i < pool->size) { ! init_tour(root, chromo[i].string, pool->string_length); ! pool->data[i].worth = geqo_eval(root, chromo[i].string, ! pool->string_length); if (pool->data[i].worth < DBL_MAX) i++; else *************** random_init_pool(Pool *pool, GeqoEvalDat *** 133,139 **** * maybe you have to change compare() for different ordering ... */ void ! sort_pool(Pool *pool) { qsort(pool->data, pool->size, sizeof(Chromosome), compare); } --- 132,138 ---- * maybe you have to change compare() for different ordering ... */ void ! sort_pool(PlannerInfo *root, Pool *pool) { qsort(pool->data, pool->size, sizeof(Chromosome), compare); } *************** compare(const void *arg1, const void *ar *** 160,166 **** * allocates a chromosome and string space */ Chromosome * ! alloc_chromo(int string_length) { Chromosome *chromo; --- 159,165 ---- * allocates a chromosome and string space */ Chromosome * ! alloc_chromo(PlannerInfo *root, int string_length) { Chromosome *chromo; *************** alloc_chromo(int string_length) *** 174,180 **** * deallocates a chromosome and string space */ void ! free_chromo(Chromosome *chromo) { pfree(chromo->string); pfree(chromo); --- 173,179 ---- * deallocates a chromosome and string space */ void ! free_chromo(PlannerInfo *root, Chromosome *chromo) { pfree(chromo->string); pfree(chromo); *************** free_chromo(Chromosome *chromo) *** 185,191 **** * assumes best->worst = smallest->largest */ void ! spread_chromo(Chromosome *chromo, Pool *pool) { int top, mid, --- 184,190 ---- * assumes best->worst = smallest->largest */ void ! spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool) { int top, mid, *************** spread_chromo(Chromosome *chromo, Pool * *** 247,253 **** * copy new gene into pool storage; always replace worst gene in pool */ ! geqo_copy(&pool->data[pool->size - 1], chromo, pool->string_length); swap_chromo.string = pool->data[pool->size - 1].string; swap_chromo.worth = pool->data[pool->size - 1].worth; --- 246,252 ---- * copy new gene into pool storage; always replace worst gene in pool */ ! geqo_copy(root, &pool->data[pool->size - 1], chromo, pool->string_length); swap_chromo.string = pool->data[pool->size - 1].string; swap_chromo.worth = pool->data[pool->size - 1].worth; diff --git a/src/backend/optimizer/geqo/geqo_px.c b/src/backend/optimizer/geqo/geqo_px.c index 07f41cd..9e9cee2 100644 *** a/src/backend/optimizer/geqo/geqo_px.c --- b/src/backend/optimizer/geqo/geqo_px.c *************** *** 34,39 **** --- 34,40 ---- /*************************************************************/ #include "postgres.h" + #include "optimizer/geqo.h" #include "optimizer/geqo_random.h" #include "optimizer/geqo_recombination.h" *************** *** 43,49 **** * position crossover */ void ! px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table) { int num_positions; --- 44,51 ---- * position crossover */ void ! px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, ! City *city_table) { int num_positions; *************** px(Gene *tour1, Gene *tour2, Gene *offsp *** 57,68 **** city_table[i].used = 0; /* choose random positions that will be inherited directly from parent */ ! num_positions = geqo_randint(2 * num_gene / 3, num_gene / 3); /* choose random position */ for (i = 0; i < num_positions; i++) { ! pos = geqo_randint(num_gene - 1, 0); offspring[pos] = tour1[pos]; /* transfer cities to child */ city_table[(int) tour1[pos]].used = 1; /* mark city used */ --- 59,70 ---- city_table[i].used = 0; /* choose random positions that will be inherited directly from parent */ ! num_positions = geqo_randint(root, 2 * num_gene / 3, num_gene / 3); /* choose random position */ for (i = 0; i < num_positions; i++) { ! pos = geqo_randint(root, num_gene - 1, 0); offspring[pos] = tour1[pos]; /* transfer cities to child */ city_table[(int) tour1[pos]].used = 1; /* mark city used */ diff --git a/src/backend/optimizer/geqo/geqo_random.c b/src/backend/optimizer/geqo/geqo_random.c index ...59d5e42 . *** a/src/backend/optimizer/geqo/geqo_random.c --- b/src/backend/optimizer/geqo/geqo_random.c *************** *** 0 **** --- 1,42 ---- + /*------------------------------------------------------------------------ + * + * geqo_misc.c + * misc. printout and debug stuff + * + * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group + * Portions Copyright (c) 1994, Regents of the University of California + * + * $PostgreSQL$ + * + *------------------------------------------------------------------------- + */ + + #include "postgres.h" + + #include "optimizer/geqo.h" + #include "optimizer/geqo_random.h" + + + static unsigned short global_random_state[3]; + + void geqo_seed(PlannerInfo *root, double seed){ + GeqoPrivateData *private = (GeqoPrivateData*)root->join_search_private; + + private->random_state = palloc(sizeof(global_random_state)); + + /* + * XXX. This seeding algorithm could certainly be improved - but + * it is not critical to do so. + */ + memcpy(private->random_state, + &seed, + Min(sizeof(global_random_state), + sizeof(seed)) + ); + } + + double geqo_rand(PlannerInfo *root){ + if(!((GeqoPrivateData*)root->join_search_private)->random_state) + return erand48(global_random_state); + return erand48(((GeqoPrivateData*)root->join_search_private)->random_state); + }; diff --git a/src/backend/optimizer/geqo/geqo_recombination.c b/src/backend/optimizer/geqo/geqo_recombination.c index 3972fb1..e2b69a3 100644 *** a/src/backend/optimizer/geqo/geqo_recombination.c --- b/src/backend/optimizer/geqo/geqo_recombination.c *************** *** 20,25 **** --- 20,26 ---- #include "postgres.h" + #include "optimizer/geqo.h" #include "optimizer/geqo_random.h" #include "optimizer/geqo_recombination.h" *************** *** 35,41 **** * and the procedure repeated. */ void ! init_tour(Gene *tour, int num_gene) { Gene *tmp; int remainder; --- 36,42 ---- * and the procedure repeated. */ void ! init_tour(PlannerInfo *root, Gene *tour, int num_gene) { Gene *tmp; int remainder; *************** init_tour(Gene *tour, int num_gene) *** 53,59 **** for (i = 0; i < num_gene; i++) { /* choose value between 0 and remainder inclusive */ ! next = (int) geqo_randint(remainder, 0); /* output that element of the tmp array */ tour[i] = tmp[next]; /* and delete it */ --- 54,60 ---- for (i = 0; i < num_gene; i++) { /* choose value between 0 and remainder inclusive */ ! next = (int) geqo_randint(root, remainder, 0); /* output that element of the tmp array */ tour[i] = tmp[next]; /* and delete it */ *************** init_tour(Gene *tour, int num_gene) *** 81,87 **** * allocate memory for city table */ City * ! alloc_city_table(int num_gene) { City *city_table; --- 82,88 ---- * allocate memory for city table */ City * ! alloc_city_table(PlannerInfo *root, int num_gene) { City *city_table; *************** alloc_city_table(int num_gene) *** 99,105 **** * deallocate memory of city table */ void ! free_city_table(City *city_table) { pfree(city_table); } --- 100,106 ---- * deallocate memory of city table */ void ! free_city_table(PlannerInfo *root, City *city_table) { pfree(city_table); } diff --git a/src/backend/optimizer/geqo/geqo_selection.c b/src/backend/optimizer/geqo/geqo_selection.c index d4f2c4d..2cd7402 100644 *** a/src/backend/optimizer/geqo/geqo_selection.c --- b/src/backend/optimizer/geqo/geqo_selection.c *************** *** 42,48 **** #include "optimizer/geqo_random.h" #include "optimizer/geqo_selection.h" ! static int linear(int max, double bias); /* --- 42,48 ---- #include "optimizer/geqo_random.h" #include "optimizer/geqo_selection.h" ! static int linear(PlannerInfo *root, int max, double bias); /* *************** static int linear(int max, double bias); *** 51,72 **** * first and second genes are selected from the pool */ void ! geqo_selection(Chromosome *momma, Chromosome *daddy, Pool *pool, double bias) { int first, second; ! first = linear(pool->size, bias); ! second = linear(pool->size, bias); if (pool->size > 1) { while (first == second) ! second = linear(pool->size, bias); } ! geqo_copy(momma, &pool->data[first], pool->string_length); ! geqo_copy(daddy, &pool->data[second], pool->string_length); } /* --- 51,73 ---- * first and second genes are selected from the pool */ void ! geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy, ! Pool *pool, double bias) { int first, second; ! first = linear(root, pool->size, bias); ! second = linear(root, pool->size, bias); if (pool->size > 1) { while (first == second) ! second = linear(root, pool->size, bias); } ! geqo_copy(root, momma, &pool->data[first], pool->string_length); ! geqo_copy(root, daddy, &pool->data[second], pool->string_length); } /* *************** geqo_selection(Chromosome *momma, Chromo *** 78,84 **** * bias = (prob of first rule) / (prob of middle rule) */ static int ! linear(int pool_size, double bias) /* bias is y-intercept of linear * distribution */ { double index; /* index between 0 and pop_size */ --- 79,85 ---- * bias = (prob of first rule) / (prob of middle rule) */ static int ! linear(PlannerInfo *root, int pool_size, double bias) /* bias is y-intercept of linear * distribution */ { double index; /* index between 0 and pop_size */ *************** linear(int pool_size, double bias) /* b *** 95,101 **** { double sqrtval; ! sqrtval = (bias * bias) - 4.0 * (bias - 1.0) * geqo_rand(); if (sqrtval > 0.0) sqrtval = sqrt(sqrtval); index = max * (bias - sqrtval) / 2.0 / (bias - 1.0); --- 96,102 ---- { double sqrtval; ! sqrtval = (bias * bias) - 4.0 * (bias - 1.0) * geqo_rand(root); if (sqrtval > 0.0) sqrtval = sqrt(sqrtval); index = max * (bias - sqrtval) / 2.0 / (bias - 1.0); diff --git a/src/backend/optimizer/path/allpaths.c b/src/backend/optimizer/path/allpaths.c index b375902..777d75d 100644 *** a/src/backend/optimizer/path/allpaths.c --- b/src/backend/optimizer/path/allpaths.c *************** standard_join_search(PlannerInfo *root, *** 901,906 **** --- 901,908 ---- int lev; RelOptInfo *rel; + Assert(root->join_search_private == 0); + /* * We employ a simple "dynamic programming" algorithm: we first find all * ways to build joins of two jointree items, then all ways to build joins diff --git a/src/backend/utils/misc/guc.c b/src/backend/utils/misc/guc.c index 2430185..4126516 100644 *** a/src/backend/utils/misc/guc.c --- b/src/backend/utils/misc/guc.c *************** static struct config_real ConfigureNames *** 2026,2031 **** --- 2026,2040 ---- DEFAULT_GEQO_SELECTION_BIAS, MIN_GEQO_SELECTION_BIAS, MAX_GEQO_SELECTION_BIAS, NULL, NULL }, + { + {"geqo_seed", PGC_USERSET, QUERY_TUNING_GEQO, + gettext_noop("GEQO: seed for random path selection for repeatable plan generation."), + gettext_noop("If zero planning will not be repeatable"), + GUC_NOT_IN_SAMPLE + }, + &Geqo_seed, + 0, 0, 1, NULL, NULL + }, { {"bgwriter_lru_multiplier", PGC_SIGHUP, RESOURCES, diff --git a/src/include/nodes/relation.h b/src/include/nodes/relation.h index ea48889..8f82d71 100644 *** a/src/include/nodes/relation.h --- b/src/include/nodes/relation.h *************** typedef struct PlannerInfo *** 192,197 **** --- 192,200 ---- /* These fields are used only when hasRecursion is true: */ int wt_param_id; /* PARAM_EXEC ID for the work table */ struct Plan *non_recursive_plan; /* plan for non-recursive term */ + + /* private data for join-order implementation, i.e. GEQO */ + void *join_search_private; } PlannerInfo; diff --git a/src/include/optimizer/geqo.h b/src/include/optimizer/geqo.h index ea4c812..7a9b6a4 100644 *** a/src/include/optimizer/geqo.h --- b/src/include/optimizer/geqo.h *************** extern int Geqo_pool_size; /* 2 .. inf, *** 59,88 **** extern int Geqo_generations; /* 1 .. inf, or 0 to use default */ extern double Geqo_selection_bias; #define DEFAULT_GEQO_SELECTION_BIAS 2.0 #define MIN_GEQO_SELECTION_BIAS 1.5 #define MAX_GEQO_SELECTION_BIAS 2.0 - /* - * Data structure to encapsulate information needed for building plan trees - * (i.e., geqo_eval and gimme_tree). - */ typedef struct { ! PlannerInfo *root; /* the query we are planning */ ! List *initial_rels; /* the base relations */ ! } GeqoEvalData; ! /* routines in geqo_main.c */ extern RelOptInfo *geqo(PlannerInfo *root, int number_of_rels, List *initial_rels); /* routines in geqo_eval.c */ ! extern Cost geqo_eval(Gene *tour, int num_gene, GeqoEvalData *evaldata); ! extern RelOptInfo *gimme_tree(Gene *tour, int num_gene, ! GeqoEvalData *evaldata); #endif /* GEQO_H */ --- 59,83 ---- extern int Geqo_generations; /* 1 .. inf, or 0 to use default */ extern double Geqo_selection_bias; + extern double Geqo_seed; #define DEFAULT_GEQO_SELECTION_BIAS 2.0 #define MIN_GEQO_SELECTION_BIAS 1.5 #define MAX_GEQO_SELECTION_BIAS 2.0 typedef struct { ! List *initial_rels; ! unsigned short *random_state; ! } GeqoPrivateData; /* routines in geqo_main.c */ extern RelOptInfo *geqo(PlannerInfo *root, int number_of_rels, List *initial_rels); /* routines in geqo_eval.c */ ! extern Cost geqo_eval(PlannerInfo *root, Gene *tour, int num_geneo); ! extern RelOptInfo *gimme_tree(PlannerInfo *root, Gene *tour, int num_gene); #endif /* GEQO_H */ diff --git a/src/include/optimizer/geqo_copy.h b/src/include/optimizer/geqo_copy.h index ae13059..63b7c83 100644 *** a/src/include/optimizer/geqo_copy.h --- b/src/include/optimizer/geqo_copy.h *************** *** 22,29 **** #ifndef GEQO_COPY_H #define GEQO_COPY_H #include "optimizer/geqo_gene.h" ! extern void geqo_copy(Chromosome *chromo1, Chromosome *chromo2, int string_length); #endif /* GEQO_COPY_H */ --- 22,30 ---- #ifndef GEQO_COPY_H #define GEQO_COPY_H + #include "optimizer/geqo.h" #include "optimizer/geqo_gene.h" ! extern void geqo_copy(PlannerInfo *root, Chromosome *chromo1, Chromosome *chromo2, int string_length); #endif /* GEQO_COPY_H */ diff --git a/src/include/optimizer/geqo_mutation.h b/src/include/optimizer/geqo_mutation.h index 0384de8..3ada430 100644 *** a/src/include/optimizer/geqo_mutation.h --- b/src/include/optimizer/geqo_mutation.h *************** *** 22,29 **** #ifndef GEQO_MUTATION_H #define GEQO_MUTATION_H #include "optimizer/geqo_gene.h" ! extern void geqo_mutation(Gene *tour, int num_gene); #endif /* GEQO_MUTATION_H */ --- 22,30 ---- #ifndef GEQO_MUTATION_H #define GEQO_MUTATION_H + #include "optimizer/geqo.h" #include "optimizer/geqo_gene.h" ! extern void geqo_mutation(PlannerInfo *root, Gene *tour, int num_gene); #endif /* GEQO_MUTATION_H */ diff --git a/src/include/optimizer/geqo_pool.h b/src/include/optimizer/geqo_pool.h index 950e667..dbc6a01 100644 *** a/src/include/optimizer/geqo_pool.h --- b/src/include/optimizer/geqo_pool.h *************** *** 26,40 **** #include "optimizer/geqo.h" ! extern Pool *alloc_pool(int pool_size, int string_length); ! extern void free_pool(Pool *pool); ! extern void random_init_pool(Pool *pool, GeqoEvalData *evaldata); ! extern Chromosome *alloc_chromo(int string_length); ! extern void free_chromo(Chromosome *chromo); ! extern void spread_chromo(Chromosome *chromo, Pool *pool); ! extern void sort_pool(Pool *pool); #endif /* GEQO_POOL_H */ --- 26,40 ---- #include "optimizer/geqo.h" ! extern Pool *alloc_pool(PlannerInfo *root, int pool_size, int string_length); ! extern void free_pool(PlannerInfo *root, Pool *pool); ! extern void random_init_pool(PlannerInfo *root, Pool *pool); ! extern Chromosome *alloc_chromo(PlannerInfo *root, int string_length); ! extern void free_chromo(PlannerInfo *root, Chromosome *chromo); ! extern void spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool); ! extern void sort_pool(PlannerInfo *root, Pool *pool); #endif /* GEQO_POOL_H */ diff --git a/src/include/optimizer/geqo_random.h b/src/include/optimizer/geqo_random.h index fab0728..6fcfa7f 100644 *** a/src/include/optimizer/geqo_random.h --- b/src/include/optimizer/geqo_random.h *************** *** 27,38 **** #include <math.h> /* geqo_rand returns a random float value between 0 and 1 inclusive */ ! ! #define geqo_rand() ((double) random() / (double) MAX_RANDOM_VALUE) /* geqo_randint returns integer value between lower and upper inclusive */ ! ! #define geqo_randint(upper,lower) \ ! ( (int) floor( geqo_rand()*(((upper)-(lower))+0.999999) ) + (lower) ) #endif /* GEQO_RANDOM_H */ --- 27,37 ---- #include <math.h> /* geqo_rand returns a random float value between 0 and 1 inclusive */ ! double geqo_rand(PlannerInfo *root); ! void geqo_seed(PlannerInfo *root, double); /* geqo_randint returns integer value between lower and upper inclusive */ ! #define geqo_randint(root, upper,lower) \ ! ( (int) floor( geqo_rand(root)*(((upper)-(lower))+0.999999) ) + (lower) ) #endif /* GEQO_RANDOM_H */ diff --git a/src/include/optimizer/geqo_recombination.h b/src/include/optimizer/geqo_recombination.h index 2c4a338..2484259 100644 *** a/src/include/optimizer/geqo_recombination.h --- b/src/include/optimizer/geqo_recombination.h *************** *** 24,32 **** #ifndef GEQO_RECOMBINATION_H #define GEQO_RECOMBINATION_H #include "optimizer/geqo_gene.h" ! extern void init_tour(Gene *tour, int num_gene); /* edge recombination crossover [ERX] */ --- 24,33 ---- #ifndef GEQO_RECOMBINATION_H #define GEQO_RECOMBINATION_H + #include "optimizer/geqo.h" #include "optimizer/geqo_gene.h" ! extern void init_tour(PlannerInfo *root, Gene *tour, int num_gene); /* edge recombination crossover [ERX] */ *************** typedef struct Edge *** 38,49 **** int unused_edges; } Edge; ! extern Edge *alloc_edge_table(int num_gene); ! extern void free_edge_table(Edge *edge_table); ! extern float gimme_edge_table(Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table); ! extern int gimme_tour(Edge *edge_table, Gene *new_gene, int num_gene); /* partially matched crossover [PMX] */ --- 39,52 ---- int unused_edges; } Edge; ! extern Edge *alloc_edge_table(PlannerInfo *root, int num_gene); ! extern void free_edge_table(PlannerInfo *root, Edge *edge_table); ! extern float gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2, ! int num_gene, Edge *edge_table); ! extern int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, ! int num_gene); /* partially matched crossover [PMX] */ *************** extern int gimme_tour(Edge *edge_table, *** 51,57 **** #define DAD 1 /* indicator for gene from dad */ #define MOM 0 /* indicator for gene from mom */ ! extern void pmx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene); typedef struct City --- 54,62 ---- #define DAD 1 /* indicator for gene from dad */ #define MOM 0 /* indicator for gene from mom */ ! extern void pmx(PlannerInfo *root, ! Gene *tour1, Gene *tour2, ! Gene *offspring, int num_gene); typedef struct City *************** typedef struct City *** 62,80 **** int select_list; } City; ! extern City *alloc_city_table(int num_gene); ! extern void free_city_table(City *city_table); /* cycle crossover [CX] */ ! extern int cx(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table); /* position crossover [PX] */ ! extern void px(Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table); /* order crossover [OX1] according to Davis */ ! extern void ox1(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table); /* order crossover [OX2] according to Syswerda */ ! extern void ox2(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table); #endif /* GEQO_RECOMBINATION_H */ --- 67,89 ---- int select_list; } City; ! extern City *alloc_city_table(PlannerInfo *root, int num_gene); ! extern void free_city_table(PlannerInfo *root, City *city_table); /* cycle crossover [CX] */ ! extern int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, ! Gene *offspring, int num_gene, City *city_table); /* position crossover [PX] */ ! extern void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, ! int num_gene, City *city_table); /* order crossover [OX1] according to Davis */ ! extern void ox1(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring, ! int num_gene, City *city_table); /* order crossover [OX2] according to Syswerda */ ! extern void ox2(PlannerInfo *root, Gene *mom, Gene *dad, Gene *offspring, ! int num_gene, City *city_table); #endif /* GEQO_RECOMBINATION_H */ diff --git a/src/include/optimizer/geqo_selection.h b/src/include/optimizer/geqo_selection.h index 4b336d1..7e93cb4 100644 *** a/src/include/optimizer/geqo_selection.h --- b/src/include/optimizer/geqo_selection.h *************** *** 25,30 **** #include "optimizer/geqo_gene.h" ! extern void geqo_selection(Chromosome *momma, Chromosome *daddy, Pool *pool, double bias); #endif /* GEQO_SELECTION_H */ --- 25,32 ---- #include "optimizer/geqo_gene.h" ! extern void geqo_selection(PlannerInfo *root, ! Chromosome *momma, Chromosome *daddy, ! Pool *pool, double bias); #endif /* GEQO_SELECTION_H */ -- 1.6.3.3.335.ge09a8 -- Sent via pgsql-hackers mailing list (pgsql-hackers@postgresql.org) To make changes to your subscription: http://www.postgresql.org/mailpref/pgsql-hackers