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

From: Andres Freund <andres(at)anarazel(dot)de>
To: andres(at)anarazel(dot)de, pgsql-hackers(at)postgresql(dot)org
Subject: [PATCH 2/3] Support a 'geqo_seed' GUC to make planning via GEQO repeatable.
Date: 2009-07-14 22:34:49
Message-ID: 1247610890-8922-3-git-send-email-andres@anarazel.de
Views: Raw Message | Whole Thread | Download mbox | Resend email
Thread:
Lists: 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 +-
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

In response to

Browse pgsql-hackers by date

  From Date Subject
Next Message Andres Freund 2009-07-14 22:34:50 [PATCH 3/3] Document geqo_seed variable.
Previous Message Andres Freund 2009-07-14 22:34:48 [PATCH 1/3] Add erand48() implementation for non-unixoid systems.