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:
parent
c686be8d56
commit
1332c1e144
@ -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;
|
||||
}
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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 */
|
||||
|
Loading…
x
Reference in New Issue
Block a user