PostgreSQL Source Code git master
Loading...
Searching...
No Matches
geqo.h File Reference
Include dependency graph for geqo.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  GeqoPrivateData
 

Macros

#define ERX
 
#define DEFAULT_GEQO_EFFORT   5
 
#define MIN_GEQO_EFFORT   1
 
#define MAX_GEQO_EFFORT   10
 
#define DEFAULT_GEQO_SELECTION_BIAS   2.0
 
#define MIN_GEQO_SELECTION_BIAS   1.5
 
#define MAX_GEQO_SELECTION_BIAS   2.0
 

Functions

static GeqoPrivateDataGetGeqoPrivateData (PlannerInfo *root)
 
RelOptInfogeqo (PlannerInfo *root, int number_of_rels, List *initial_rels)
 
Cost geqo_eval (PlannerInfo *root, Gene *tour, int num_gene)
 
RelOptInfogimme_tree (PlannerInfo *root, Gene *tour, int num_gene)
 

Variables

PGDLLIMPORT int Geqo_effort
 
PGDLLIMPORT int Geqo_pool_size
 
PGDLLIMPORT int Geqo_generations
 
PGDLLIMPORT double Geqo_selection_bias
 
PGDLLIMPORT int Geqo_planner_extension_id
 
PGDLLIMPORT double Geqo_seed
 

Macro Definition Documentation

◆ DEFAULT_GEQO_EFFORT

#define DEFAULT_GEQO_EFFORT   5

Definition at line 56 of file geqo.h.

◆ DEFAULT_GEQO_SELECTION_BIAS

#define DEFAULT_GEQO_SELECTION_BIAS   2.0

Definition at line 68 of file geqo.h.

◆ ERX

#define ERX

Definition at line 45 of file geqo.h.

◆ MAX_GEQO_EFFORT

#define MAX_GEQO_EFFORT   10

Definition at line 58 of file geqo.h.

◆ MAX_GEQO_SELECTION_BIAS

#define MAX_GEQO_SELECTION_BIAS   2.0

Definition at line 70 of file geqo.h.

◆ MIN_GEQO_EFFORT

#define MIN_GEQO_EFFORT   1

Definition at line 57 of file geqo.h.

◆ MIN_GEQO_SELECTION_BIAS

#define MIN_GEQO_SELECTION_BIAS   1.5

Definition at line 69 of file geqo.h.

Function Documentation

◆ geqo()

RelOptInfo * geqo ( PlannerInfo root,
int  number_of_rels,
List initial_rels 
)
extern

Definition at line 74 of file geqo_main.c.

75{
76 GeqoPrivateData private;
77 int generation;
81 Pool *pool;
82 int pool_size,
84
85#ifdef GEQO_DEBUG
87#endif
90
91#if defined(ERX)
92 Edge *edge_table; /* list of edges */
93 int edge_failures = 0;
94#endif
95#if defined(CX) || defined(PX) || defined(OX1) || defined(OX2)
96 City *city_table; /* list of cities */
97#endif
98#if defined(CX)
99 int cycle_diffs = 0;
100 int mutations = 0;
101#endif
102
105
106/* set up private information */
108 private.initial_rels = initial_rels;
109
110/* inform core planner that we may replan */
111 root->assumeReplanning = true;
112
113/* initialize private number generator */
115
116/* set GA parameters */
119#ifdef GEQO_DEBUG
120 status_interval = 10;
121#endif
122
123/* allocate genetic pool memory */
125
126/* random initialization of the pool */
127 random_init_pool(root, pool);
128
129/* sort the pool according to cheapest path as fitness */
130 sort_pool(root, pool); /* we have to do it only one time, since all
131 * kids replace the worst individuals in
132 * future (-> geqo_pool.c:spread_chromo ) */
133
134#ifdef GEQO_DEBUG
135 elog(DEBUG1, "GEQO selected %d pool entries, best %.2f, worst %.2f",
136 pool_size,
137 pool->data[0].worth,
138 pool->data[pool_size - 1].worth);
139#endif
140
141/* allocate chromosome momma and daddy memory */
144
145#if defined (ERX)
146#ifdef GEQO_DEBUG
147 elog(DEBUG2, "using edge recombination crossover [ERX]");
148#endif
149/* allocate edge table memory */
151#elif defined(PMX)
152#ifdef GEQO_DEBUG
153 elog(DEBUG2, "using partially matched crossover [PMX]");
154#endif
155/* allocate chromosome kid memory */
157#elif defined(CX)
158#ifdef GEQO_DEBUG
159 elog(DEBUG2, "using cycle crossover [CX]");
160#endif
161/* allocate city table memory */
164#elif defined(PX)
165#ifdef GEQO_DEBUG
166 elog(DEBUG2, "using position crossover [PX]");
167#endif
168/* allocate city table memory */
171#elif defined(OX1)
172#ifdef GEQO_DEBUG
173 elog(DEBUG2, "using order crossover [OX1]");
174#endif
175/* allocate city table memory */
178#elif defined(OX2)
179#ifdef GEQO_DEBUG
180 elog(DEBUG2, "using order crossover [OX2]");
181#endif
182/* allocate city table memory */
185#endif
186
187
188/* my pain main part: */
189/* iterative optimization */
190
191 for (generation = 0; generation < number_generations; generation++)
192 {
193 /* SELECTION: using linear bias function */
195
196#if defined (ERX)
197 /* EDGE RECOMBINATION CROSSOVER */
198 gimme_edge_table(root, momma->string, daddy->string, pool->string_length, edge_table);
199
200 kid = momma;
201
202 /* are there any edge failures ? */
204#elif defined(PMX)
205 /* PARTIALLY MATCHED CROSSOVER */
206 pmx(root, momma->string, daddy->string, kid->string, pool->string_length);
207#elif defined(CX)
208 /* CYCLE CROSSOVER */
209 cycle_diffs = cx(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
210 /* mutate the child */
211 if (cycle_diffs == 0)
212 {
213 mutations++;
214 geqo_mutation(root, kid->string, pool->string_length);
215 }
216#elif defined(PX)
217 /* POSITION CROSSOVER */
218 px(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
219#elif defined(OX1)
220 /* ORDER CROSSOVER */
221 ox1(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
222#elif defined(OX2)
223 /* ORDER CROSSOVER */
224 ox2(root, momma->string, daddy->string, kid->string, pool->string_length, city_table);
225#endif
226
227
228 /* EVALUATE FITNESS */
229 kid->worth = geqo_eval(root, kid->string, pool->string_length);
230
231 /* push the kid into the wilderness of life according to its worth */
232 spread_chromo(root, kid, pool);
233
234
235#ifdef GEQO_DEBUG
236 if (status_interval && !(generation % status_interval))
237 print_gen(stdout, pool, generation);
238#endif
239
240 }
241
242
243#if defined(ERX)
244#if defined(GEQO_DEBUG)
245 if (edge_failures != 0)
246 elog(LOG, "[GEQO] failures: %d, average: %d",
248 else
249 elog(LOG, "[GEQO] no edge failures detected");
250#else
251 /* suppress variable-set-but-not-used warnings from some compilers */
253#endif
254#endif
255
256#if defined(CX) && defined(GEQO_DEBUG)
257 if (mutations != 0)
258 elog(LOG, "[GEQO] mutations: %d, generations: %d",
260 else
261 elog(LOG, "[GEQO] no mutations processed");
262#endif
263
264#ifdef GEQO_DEBUG
265 print_pool(stdout, pool, 0, pool_size - 1);
266#endif
267
268#ifdef GEQO_DEBUG
269 elog(DEBUG1, "GEQO best is %.2f after %d generations",
270 pool->data[0].worth, number_generations);
271#endif
272
273
274 /*
275 * got the cheapest query tree processed by geqo; first element of the
276 * population indicates the best query tree
277 */
278 best_tour = (Gene *) pool->data[0].string;
279
281
282 if (best_rel == NULL)
283 elog(ERROR, "geqo failed to make a valid plan");
284
285 /* DBG: show the query plan */
286#ifdef NOT_USED
288#endif
289
290 /* ... free memory stuff */
293
294#if defined (ERX)
296#elif defined(PMX)
298#elif defined(CX)
301#elif defined(PX)
304#elif defined(OX1)
307#elif defined(OX2)
310#endif
311
312 free_pool(root, pool);
313
314 /* ... clear root pointer to our private storage */
316
317 return best_rel;
318}
#define LOG
Definition elog.h:31
#define DEBUG2
Definition elog.h:29
#define DEBUG1
Definition elog.h:30
#define ERROR
Definition elog.h:39
#define elog(elevel,...)
Definition elog.h:226
void SetPlannerInfoExtensionState(PlannerInfo *root, int extension_id, void *opaque)
Definition extendplan.c:113
int GetPlannerExtensionId(const char *extension_name)
Definition extendplan.c:41
Edge * alloc_edge_table(PlannerInfo *root, int num_gene)
Definition geqo_erx.c:56
float gimme_edge_table(PlannerInfo *root, Gene *tour1, Gene *tour2, int num_gene, Edge *edge_table)
Definition geqo_erx.c:95
void free_edge_table(PlannerInfo *root, Edge *edge_table)
Definition geqo_erx.c:76
int gimme_tour(PlannerInfo *root, Edge *edge_table, Gene *new_gene, int num_gene)
Definition geqo_erx.c:196
Cost geqo_eval(PlannerInfo *root, Gene *tour, int num_gene)
Definition geqo_eval.c:56
RelOptInfo * gimme_tree(PlannerInfo *root, Gene *tour, int num_gene)
Definition geqo_eval.c:162
int Gene
Definition geqo_gene.h:30
double Geqo_seed
Definition geqo_main.c:48
int Geqo_planner_extension_id
Definition geqo_main.c:51
static int gimme_number_generations(int pool_size)
Definition geqo_main.c:360
static int gimme_pool_size(int nr_rel)
Definition geqo_main.c:328
double Geqo_selection_bias
Definition geqo_main.c:47
void geqo_mutation(PlannerInfo *root, Gene *tour, int num_gene)
Pool * alloc_pool(PlannerInfo *root, int pool_size, int string_length)
Definition geqo_pool.c:41
void sort_pool(PlannerInfo *root, Pool *pool)
Definition geqo_pool.c:134
void free_chromo(PlannerInfo *root, Chromosome *chromo)
Definition geqo_pool.c:175
void free_pool(PlannerInfo *root, Pool *pool)
Definition geqo_pool.c:68
void random_init_pool(PlannerInfo *root, Pool *pool)
Definition geqo_pool.c:90
void spread_chromo(PlannerInfo *root, Chromosome *chromo, Pool *pool)
Definition geqo_pool.c:186
Chromosome * alloc_chromo(PlannerInfo *root, int string_length)
Definition geqo_pool.c:161
void geqo_set_seed(PlannerInfo *root, double seed)
Definition geqo_random.c:19
void free_city_table(PlannerInfo *root, City *city_table)
void pmx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene)
City * alloc_city_table(PlannerInfo *root, int num_gene)
void ox1(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
int cx(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
void px(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
void ox2(PlannerInfo *root, Gene *tour1, Gene *tour2, Gene *offspring, int num_gene, City *city_table)
void geqo_selection(PlannerInfo *root, Chromosome *momma, Chromosome *daddy, Pool *pool, double bias)
static int fb(int x)
tree ctl root
Definition radixtree.h:1857
Cost worth
Definition geqo_gene.h:35
Gene * string
Definition geqo_gene.h:34
int string_length
Definition geqo_gene.h:42
Chromosome * data
Definition geqo_gene.h:40

References alloc_chromo(), alloc_city_table(), alloc_edge_table(), alloc_pool(), cx(), Pool::data, DEBUG1, DEBUG2, elog, ERROR, fb(), free_chromo(), free_city_table(), free_edge_table(), free_pool(), geqo_eval(), geqo_mutation(), Geqo_planner_extension_id, Geqo_seed, geqo_selection(), Geqo_selection_bias, geqo_set_seed(), GetPlannerExtensionId(), gimme_edge_table(), gimme_number_generations(), gimme_pool_size(), gimme_tour(), gimme_tree(), LOG, ox1(), ox2(), pmx(), px(), random_init_pool(), root, SetPlannerInfoExtensionState(), sort_pool(), spread_chromo(), Chromosome::string, Pool::string_length, and Chromosome::worth.

Referenced by make_rel_from_joinlist().

◆ geqo_eval()

Cost geqo_eval ( PlannerInfo root,
Gene tour,
int  num_gene 
)
extern

Definition at line 56 of file geqo_eval.c.

57{
60 RelOptInfo *joinrel;
62 int savelength;
63 struct HTAB *savehash;
64
65 /*
66 * Create a private memory context that will hold all temp storage
67 * allocated inside gimme_tree().
68 *
69 * Since geqo_eval() will be called many times, we can't afford to let all
70 * that memory go unreclaimed until end of statement. Note we make the
71 * temp context a child of the planner's normal context, so that it will
72 * be freed even if we abort via ereport(ERROR).
73 */
75 "GEQO",
78
79 /*
80 * gimme_tree will add entries to root->join_rel_list, which may or may
81 * not already contain some entries. The newly added entries will be
82 * recycled by the MemoryContextDelete below, so we must ensure that the
83 * list is restored to its former state before exiting. We can do this by
84 * truncating the list to its original length. NOTE this assumes that any
85 * added entries are appended at the end!
86 *
87 * We also must take care not to mess up the outer join_rel_hash, if there
88 * is one. We can do this by just temporarily setting the link to NULL.
89 * (If we are dealing with enough join rels, which we very likely are, a
90 * new hash table will get built and used locally.)
91 *
92 * join_rel_level[] shouldn't be in use, so just Assert it isn't.
93 */
94 savelength = list_length(root->join_rel_list);
95 savehash = root->join_rel_hash;
96 Assert(root->join_rel_level == NULL);
97
98 root->join_rel_hash = NULL;
99
100 /* construct the best path for the given combination of relations */
101 joinrel = gimme_tree(root, tour, num_gene);
102
103 /*
104 * compute fitness, if we found a valid join
105 *
106 * XXX geqo does not currently support optimization for partial result
107 * retrieval, nor do we take any cognizance of possible use of
108 * parameterized paths --- how to fix?
109 */
110 if (joinrel)
111 {
113
115 }
116 else
118
119 /*
120 * Restore join_rel_list to its former state, and put back original
121 * hashtable if any.
122 */
123 root->join_rel_list = list_truncate(root->join_rel_list,
124 savelength);
125 root->join_rel_hash = savehash;
126
127 /* release all the memory acquired within gimme_tree */
130
131 return fitness;
132}
#define Assert(condition)
Definition c.h:873
List * list_truncate(List *list, int new_size)
Definition list.c:631
MemoryContext CurrentMemoryContext
Definition mcxt.c:160
void MemoryContextDelete(MemoryContext context)
Definition mcxt.c:472
#define AllocSetContextCreate
Definition memutils.h:129
#define ALLOCSET_DEFAULT_SIZES
Definition memutils.h:160
double Cost
Definition nodes.h:261
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124
static int list_length(const List *l)
Definition pg_list.h:152
Cost total_cost
Definition pathnodes.h:1988
struct Path * cheapest_total_path
Definition pathnodes.h:1036

References ALLOCSET_DEFAULT_SIZES, AllocSetContextCreate, Assert, RelOptInfo::cheapest_total_path, CurrentMemoryContext, fb(), gimme_tree(), list_length(), list_truncate(), MemoryContextDelete(), MemoryContextSwitchTo(), root, and Path::total_cost.

Referenced by geqo(), and random_init_pool().

◆ GetGeqoPrivateData()

static GeqoPrivateData * GetGeqoPrivateData ( PlannerInfo root)
inlinestatic

Definition at line 85 of file geqo.h.

86{
87 /* headers must be C++-compliant, so the cast is required here */
88 return (GeqoPrivateData *)
90}
static void * GetPlannerInfoExtensionState(PlannerInfo *root, int extension_id)
Definition extendplan.h:39
PGDLLIMPORT int Geqo_planner_extension_id
Definition geqo_main.c:51

References Geqo_planner_extension_id, GetPlannerInfoExtensionState(), and root.

Referenced by geqo_rand(), geqo_randint(), geqo_set_seed(), and gimme_tree().

◆ gimme_tree()

RelOptInfo * gimme_tree ( PlannerInfo root,
Gene tour,
int  num_gene 
)
extern

Definition at line 162 of file geqo_eval.c.

163{
165 List *clumps;
166 int rel_count;
167
168 /*
169 * Sometimes, a relation can't yet be joined to others due to heuristics
170 * or actual semantic restrictions. We maintain a list of "clumps" of
171 * successfully joined relations, with larger clumps at the front. Each
172 * new relation from the tour is added to the first clump it can be joined
173 * to; if there is none then it becomes a new clump of its own. When we
174 * enlarge an existing clump we check to see if it can now be merged with
175 * any other clumps. After the tour is all scanned, we forget about the
176 * heuristics and try to forcibly join any remaining clumps. If we are
177 * unable to merge all the clumps into one, fail.
178 */
179 clumps = NIL;
180
181 for (rel_count = 0; rel_count < num_gene; rel_count++)
182 {
183 int cur_rel_index;
186
187 /* Get the next input relation */
189 cur_rel = (RelOptInfo *) list_nth(private->initial_rels,
190 cur_rel_index - 1);
191
192 /* Make it into a single-rel clump */
194 cur_clump->joinrel = cur_rel;
195 cur_clump->size = 1;
196
197 /* Merge it into the clumps list, using only desirable joins */
199 }
200
201 if (list_length(clumps) > 1)
202 {
203 /* Force-join the remaining clumps in some legal order */
204 List *fclumps;
205 ListCell *lc;
206
207 fclumps = NIL;
208 foreach(lc, clumps)
209 {
210 Clump *clump = (Clump *) lfirst(lc);
211
213 }
214 clumps = fclumps;
215 }
216
217 /* Did we succeed in forming a single join relation? */
218 if (list_length(clumps) != 1)
219 return NULL;
220
221 return ((Clump *) linitial(clumps))->joinrel;
222}
#define palloc_object(type)
Definition fe_memutils.h:74
static GeqoPrivateData * GetGeqoPrivateData(PlannerInfo *root)
Definition geqo.h:85
static List * merge_clump(PlannerInfo *root, List *clumps, Clump *new_clump, int num_gene, bool force)
Definition geqo_eval.c:237
#define lfirst(lc)
Definition pg_list.h:172
#define NIL
Definition pg_list.h:68
static void * list_nth(const List *list, int n)
Definition pg_list.h:299
#define linitial(l)
Definition pg_list.h:178
Definition pg_list.h:54

References fb(), GetGeqoPrivateData(), lfirst, linitial, list_length(), list_nth(), merge_clump(), NIL, palloc_object, and root.

Referenced by geqo(), and geqo_eval().

Variable Documentation

◆ Geqo_effort

PGDLLIMPORT int Geqo_effort
extern

Definition at line 44 of file geqo_main.c.

Referenced by gimme_pool_size().

◆ Geqo_generations

PGDLLIMPORT int Geqo_generations
extern

Definition at line 46 of file geqo_main.c.

Referenced by gimme_number_generations().

◆ Geqo_planner_extension_id

PGDLLIMPORT int Geqo_planner_extension_id
extern

Definition at line 51 of file geqo_main.c.

Referenced by geqo(), and GetGeqoPrivateData().

◆ Geqo_pool_size

PGDLLIMPORT int Geqo_pool_size
extern

Definition at line 45 of file geqo_main.c.

Referenced by gimme_pool_size().

◆ Geqo_seed

PGDLLIMPORT double Geqo_seed
extern

Definition at line 48 of file geqo_main.c.

Referenced by geqo().

◆ Geqo_selection_bias

PGDLLIMPORT double Geqo_selection_bias
extern

Definition at line 47 of file geqo_main.c.

Referenced by geqo().