[PATCH 2/3] Support a 'geqo_seed' GUC to make planning via GEQO repeatable.

Поиск
Список
Период
Сортировка
От Andres Freund
Тема [PATCH 2/3] Support a 'geqo_seed' GUC to make planning via GEQO repeatable.
Дата
Msg-id 1247610890-8922-3-git-send-email-andres@anarazel.de
обсуждение исходный текст
Ответ на Make planning via GEQO repeatable  (Andres Freund <andres@anarazel.de>)
Список pgsql-hackers
---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
+-25files 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.ogeqo_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
thenewly 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
asincorporated */
 
--- 205,222 ----          * table          */ 
!         remove_gene(root, new_gene[i - 1], edge_table[(int) new_gene[i - 1]], edge_table);          /* find
destinationfor 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
nodeas 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
getbuilt 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
getbuilt 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
includethe ones we want.              */
 
!             joinrel = make_join_rel(evaldata->root, outer_rel, inner_rel);              /* Can't pop stack here if
joinorder is not valid */             if (!joinrel)
 
--- 220,226 ----              * root->join_rel_list yet, and so the paths constructed for it              * will only
includethe ones we want.              */
 
!             joinrel = make_join_rel(root, outer_rel, inner_rel);              /* Can't pop stack here if join order
isnot 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
replacethe 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                                  *
kidsreplace 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
recombinationcrossover [ERX]"); #endif /* allocate edge table memory */
 
!     edge_table = alloc_edge_table(pool->string_length); #elif defined(PMX) #ifdef GEQO_DEBUG     elog(DEBUG2, "using
partiallymatched 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
positioncrossover [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
ordercrossover [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
ordercrossover [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
edgerecombination crossover [ERX]"); #endif /* allocate edge table memory */
 
!     edge_table = alloc_edge_table(root, pool->string_length); #elif defined(PMX) #ifdef GEQO_DEBUG     elog(DEBUG2,
"usingpartially 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,
"usingposition 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,
"usingorder 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,
"usingorder 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:
usinglinear 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)         /*
PARTIALLYMATCHED 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);         /*
mutatethe 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)         /*
ORDERCROSSOVER */
 
!         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
wildernessof life according to its worth */
 
!         spread_chromo(kid, pool);   #ifdef GEQO_DEBUG
--- 174,218 ----     for (generation = 0; generation < number_generations; generation++)     {         /* SELECTION:
usinglinear bias function */
 
!         geqo_selection(root, momma, daddy, pool, Geqo_selection_bias);  #if defined (ERX)         /* EDGE
RECOMBINATIONCROSSOVER */ 
!         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           /*
EVALUATEFITNESS */
 
!         kid->worth = geqo_eval(root, kid->string, pool->string_length);          /* push the kid into the wilderness
oflife 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,
"failedto 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,
"failedto 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
twojointree 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_EXECID 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_BIAS2.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_BIAS2.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
lowerand 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                    /*
indicatorfor 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                    /*
indicatorfor 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]
accordingto Davis */
 
! extern void ox1(Gene *mom, Gene *dad, Gene *offspring, int num_gene, City *city_table);  /* order crossover [OX2]
accordingto 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



В списке pgsql-hackers по дате отправления:

Предыдущее
От: Andres Freund
Дата:
Сообщение: [PATCH 3/3] Document geqo_seed variable.
Следующее
От: Dimitri Fontaine
Дата:
Сообщение: Re: navigation menu for documents