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.
This commit is contained in:
Tom Lane 1999-05-17 00:25:34 +00:00
parent c686be8d56
commit 1332c1e144
4 changed files with 89 additions and 54 deletions

View File

@ -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;
/* remember root->join_rel_list ... */
/* because root->join_rel_list will be changed during the following */
temp = listCopy(root->join_rel_list);
/* preserve root->join_rel_list, which gimme_tree changes */
savelist = root->join_rel_list;
/* joinrel is readily processed query tree -- left-sided ! */
/* create a temporary allocation context for the path construction work */
oldcxt = MemoryContextSwitchTo(geqo_eval_context);
StartPortalAllocMode(DefaultAllocMode, 0);
/* 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;
}

View File

@ -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;
#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; */
#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
/* 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);

View File

@ -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;

View File

@ -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 */