1
0
mirror of https://github.com/postgres/postgres.git synced 2025-08-27 07:42:10 +03:00

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;