Commit 1332c1e1 authored by Tom Lane's avatar Tom Lane

Change GEQO optimizer to release memory after each gene

is evaluated.  This bounds memory usage to something reasonable even
when many tables are being joined.
parent c686be8d
......@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_eval.c,v 1.36 1999/05/16 19:45:00 tgl Exp $
* $Id: geqo_eval.c,v 1.37 1999/05/17 00:25:34 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -36,6 +36,7 @@
#include "utils/palloc.h"
#include "utils/elog.h"
#include "utils/portal.h"
#include "optimizer/internal.h"
#include "optimizer/paths.h"
......@@ -48,6 +49,38 @@
#include "optimizer/geqo_gene.h"
#include "optimizer/geqo.h"
/*
* Variables set by geqo_eval_startup for use within a single GEQO run
*/
static MemoryContext geqo_eval_context;
/*
* geqo_eval_startup:
* Must be called during geqo_main startup (before geqo_eval may be called)
*
* The main thing we need to do here is prepare a private memory context for
* allocation of temp storage used while constructing a path in geqo_eval().
* Since geqo_eval() will be called many times, we can't afford to let all
* that memory go unreclaimed until end of statement. We use a special
* named portal to hold the context, so that it will be freed even if
* we abort via elog(ERROR). The working data is allocated in the portal's
* heap memory context.
*/
void
geqo_eval_startup(void)
{
#define GEQO_PORTAL_NAME "<geqo workspace>"
Portal geqo_portal = GetPortalByName(GEQO_PORTAL_NAME);
if (!PortalIsValid(geqo_portal)) {
/* First time through (within current transaction, that is) */
geqo_portal = CreatePortal(GEQO_PORTAL_NAME);
Assert(PortalIsValid(geqo_portal));
}
geqo_eval_context = (MemoryContext) PortalGetHeapMemory(geqo_portal);
}
/*
* geqo_eval
*
......@@ -56,23 +89,30 @@
Cost
geqo_eval(Query *root, Gene *tour, int num_gene)
{
RelOptInfo *joinrel;
Cost fitness;
List *temp;
MemoryContext oldcxt;
RelOptInfo *joinrel;
Cost fitness;
List *savelist;
/* preserve root->join_rel_list, which gimme_tree changes */
savelist = root->join_rel_list;
/* remember root->join_rel_list ... */
/* because root->join_rel_list will be changed during the following */
temp = listCopy(root->join_rel_list);
/* create a temporary allocation context for the path construction work */
oldcxt = MemoryContextSwitchTo(geqo_eval_context);
StartPortalAllocMode(DefaultAllocMode, 0);
/* joinrel is readily processed query tree -- left-sided ! */
/* construct the best path for the given combination of relations */
joinrel = gimme_tree(root, tour, 0, num_gene, NULL);
/* compute fitness */
fitness = (Cost) joinrel->cheapestpath->path_cost;
root->join_rel_list = temp;
/* restore join_rel_list */
root->join_rel_list = savelist;
pfree(joinrel);
/* release all the memory acquired within gimme_tree */
EndPortalAllocMode();
MemoryContextSwitchTo(oldcxt);
return fitness;
}
......
......@@ -6,7 +6,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_main.c,v 1.14 1999/02/18 04:55:54 momjian Exp $
* $Id: geqo_main.c,v 1.15 1999/05/17 00:25:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -70,44 +70,31 @@ geqo(Query *root)
Chromosome *momma;
Chromosome *daddy;
Chromosome *kid;
int number_of_rels;
Pool *pool;
int pool_size,
number_generations,
status_interval;
Gene *best_tour;
RelOptInfo *best_rel;
#if defined(ERX)
Edge *edge_table; /* list of edges */
int edge_failures = 0;
float difference;
#endif
#if defined(CX) || defined(PX) || defined(OX1) || defined(OX2)
City *city_table; /* list of cities */
#endif
#if defined(CX)
int cycle_diffs = 0;
int mutations = 0;
#endif
int number_of_rels;
Pool *pool;
int pool_size,
number_generations,
status_interval;
Gene *best_tour;
RelOptInfo *best_rel;
/* Plan *best_plan; */
/* set tour size */
number_of_rels = length(root->base_rel_list);
/* set GA parameters */
geqo_params(number_of_rels);/* out of "$PGDATA/pg_geqo" file */
geqo_params(number_of_rels); /* read "$PGDATA/pg_geqo" file */
pool_size = PoolSize;
number_generations = Generations;
status_interval = 10;
......@@ -115,6 +102,9 @@ geqo(Query *root)
/* seed random number generator */
srandom(RandomSeed);
/* initialize plan evaluator */
geqo_eval_startup();
/* allocate genetic pool memory */
pool = alloc_pool(pool_size, number_of_rels);
......
......@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo_params.c,v 1.14 1999/02/15 03:22:01 momjian Exp $
* $Id: geqo_params.c,v 1.15 1999/05/17 00:25:33 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -45,6 +45,16 @@
#include "storage/fd.h"
/*
* Parameter values read from the config file (or defaulted) are stored here
* by geqo_params().
*/
int PoolSize;
int Generations;
long RandomSeed;
double SelectionBias;
#define POOL_TAG "Pool_Size"
#define TRIAL_TAG "Generations"
#define RAND_TAG "Random_Seed"
......@@ -77,7 +87,7 @@ geqo_params(int string_length)
char *conf_file;
/* these static variables are used to signal that a value has been set */
/* these flag variables signal that a value has been set from the file */
int pool_size = 0;
int number_trials = 0;
int random_seed = 0;
......
......@@ -5,7 +5,7 @@
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: geqo.h,v 1.13 1999/02/18 04:55:54 momjian Exp $
* $Id: geqo.h,v 1.14 1999/05/17 00:25:32 tgl Exp $
*
*-------------------------------------------------------------------------
*/
......@@ -56,27 +56,22 @@
#define SELECTION_BIAS 2.0 /* selective pressure within population */
/* should be 1.5 <= SELECTION_BIAS <= 2.0 */
int PoolSize;
int Generations;
/* parameter values set in geqo_params.c */
extern int PoolSize;
extern int Generations;
extern long RandomSeed;
extern double SelectionBias;
long RandomSeed; /* defaults to (long) time(NULL) in
* geqo_params.c */
double SelectionBias;
/* logarithmic base for rel->size decrease in case of long
queries that cause an integer overflow; used in geqo_eval.c */
#define GEQO_LOG_BASE 1.5 /* should be 1.0 < GEQO_LOG_BASE <= 2.0 */
/* ^^^ */
/* geqo prototypes */
/* routines in geqo_main.c */
extern RelOptInfo *geqo(Query *root);
/* routines in geqo_params.c */
extern void geqo_params(int string_length);
/* routines in geqo_eval.c */
extern void geqo_eval_startup(void);
extern Cost geqo_eval(Query *root, Gene *tour, int num_gene);
extern RelOptInfo *gimme_tree(Query *root, Gene *tour, int rel_count,
int num_gene, RelOptInfo *old_rel);
#endif /* GEQO_H */
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment