]> granicus.if.org Git - postgresql/commitdiff
New alloc set code using a memory block pool for small allocations.
authorJan Wieck <JanWieck@Yahoo.com>
Sat, 6 Feb 1999 16:50:34 +0000 (16:50 +0000)
committerJan Wieck <JanWieck@Yahoo.com>
Sat, 6 Feb 1999 16:50:34 +0000 (16:50 +0000)
Jan

13 files changed:
src/backend/catalog/pg_type.c
src/backend/executor/execMain.c
src/backend/nodes/Makefile
src/backend/nodes/freefuncs.c [new file with mode: 0644]
src/backend/utils/mmgr/aset.c
src/backend/utils/mmgr/mcxt.c
src/backend/utils/mmgr/palloc.c
src/backend/utils/mmgr/portalmem.c
src/include/nodes/memnodes.h
src/include/nodes/nodes.h
src/include/utils/memutils.h
src/include/utils/palloc.h
src/include/utils/portal.h

index 17b9574001bbb9f5a45ee291e0a5fa548f996b8e..7336de88969d43fbce0187cb73649871f3aaa1f5 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.33 1999/02/03 21:15:56 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/catalog/pg_type.c,v 1.34 1999/02/06 16:50:22 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -53,6 +53,7 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
 {
        HeapScanDesc scan;
        HeapTuple       tup;
+       Oid                     typoid;
 
        static ScanKeyData typeKey[1] = {
                {0, Anum_pg_type_typname, F_NAMEEQ}
@@ -96,10 +97,12 @@ TypeGetWithOpenRelation(Relation pg_type_desc,
         *      oid, which is the oid of the type.
         * ----------------
         */
-       heap_endscan(scan);
        *defined = (bool) ((Form_pg_type) GETSTRUCT(tup))->typisdefined;
+       typoid = tup->t_data->t_oid;
 
-       return tup->t_data->t_oid;
+       heap_endscan(scan);
+
+       return typoid;
 }
 
 /* ----------------------------------------------------------------
index 60aec3e488537710ed6414868769c2132a72dff0..51478f0625332bbe9bd41cfbbfeb7a07d7e277eb 100644 (file)
@@ -26,7 +26,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.70 1999/02/02 03:44:23 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/executor/execMain.c,v 1.71 1999/02/06 16:50:23 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -1492,7 +1492,7 @@ ExecRelCheck(Relation rel, HeapTuple tuple)
 
                res = ExecQual(qual, econtext);
 
-               pfree(qual);
+               freeObject(qual);
 
                if (!res)
                        return check[i].ccname;
index 7e34521f6bdc5c6d2b5b69c78278b5ed926c30ed..0e50980c289c971935d9de28b8a417a46764317f 100644 (file)
@@ -4,7 +4,7 @@
 #    Makefile for nodes
 #
 # IDENTIFICATION
-#    $Header: /cvsroot/pgsql/src/backend/nodes/Makefile,v 1.6 1998/04/06 00:23:00 momjian Exp $
+#    $Header: /cvsroot/pgsql/src/backend/nodes/Makefile,v 1.7 1999/02/06 16:50:24 wieck Exp $
 #
 #-------------------------------------------------------------------------
 
@@ -14,8 +14,8 @@ include ../../Makefile.global
 CFLAGS += -I..
 
 OBJS = nodeFuncs.o nodes.o list.o \
-       copyfuncs.o equalfuncs.o makefuncs.o outfuncs.o readfuncs.o \
-       print.o read.o
+       copyfuncs.o equalfuncs.o freefuncs.o makefuncs.o outfuncs.o \
+       readfuncs.o print.o read.o
 
 all: SUBSYS.o
 
diff --git a/src/backend/nodes/freefuncs.c b/src/backend/nodes/freefuncs.c
new file mode 100644 (file)
index 0000000..e07573c
--- /dev/null
@@ -0,0 +1,1381 @@
+ /*-------------------------------------------------------------------------
+ *
+ * freefuncs.c--
+ *       Free functions for Postgres tree nodes.
+ *
+ * Copyright (c) 1994, Regents of the University of California
+ *
+ *
+ * IDENTIFICATION
+ *       $Header: /cvsroot/pgsql/src/backend/nodes/Attic/freefuncs.c,v 1.1 1999/02/06 16:50:25 wieck Exp $
+ *
+ *-------------------------------------------------------------------------
+ */
+#include <stdio.h>
+#include <string.h>
+
+#include "postgres.h"
+
+#include "nodes/pg_list.h"
+#include "nodes/execnodes.h"
+#include "nodes/plannodes.h"
+#include "nodes/parsenodes.h"
+#include "nodes/primnodes.h"
+#include "nodes/relation.h"
+
+#include "utils/syscache.h"
+#include "utils/builtins.h"            /* for namecpy */
+#include "utils/elog.h"
+#include "utils/palloc.h"
+#include "catalog/pg_type.h"
+#include "storage/lmgr.h"
+#include "optimizer/planmain.h"
+
+/* ****************************************************************
+ *                                      plannodes.h free functions
+ * ****************************************************************
+ */
+
+/* ----------------
+ *             FreePlanFields
+ *
+ *             This function frees the fields of the Plan node.  It is used by
+ *             all the free functions for classes which inherit node Plan.
+ * ----------------
+ */
+static void
+FreePlanFields(Plan *node)
+{
+       freeObject(node->targetlist);
+       freeObject(node->qual);
+       freeObject(node->lefttree);
+       freeObject(node->righttree);
+       freeList(node->extParam);
+       freeList(node->locParam);
+       freeList(node->chgParam);
+       freeObject(node->initPlan);
+       freeList(node->subPlan);
+}
+
+/* ----------------
+ *             _freePlan
+ * ----------------
+ */
+static void
+_freePlan(Plan *node)
+{
+       /* ----------------
+        *      free the node superclass fields
+        * ----------------
+        */
+       FreePlanFields(node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeResult
+ * ----------------
+ */
+static void
+_freeResult(Result *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->resconstantqual);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeAppend
+ * ----------------
+ */
+static void
+_freeAppend(Append *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->appendplans);
+       freeObject(node->unionrtables);
+       freeObject(node->inheritrtable);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             FreeScanFields
+ *
+ *             This function frees the fields of the Scan node.  It is used by
+ *             all the free functions for classes which inherit node Scan.
+ * ----------------
+ */
+static void
+FreeScanFields(Scan *node)
+{
+}
+
+/* ----------------
+ *             _freeScan
+ * ----------------
+ */
+static void
+_freeScan(Scan *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeScanFields((Scan *) node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeSeqScan
+ * ----------------
+ */
+static void
+_freeSeqScan(SeqScan *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeScanFields((Scan *) node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeIndexScan
+ * ----------------
+ */
+static void
+_freeIndexScan(IndexScan *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeScanFields((Scan *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeList(node->indxid);
+       freeObject(node->indxqual);
+       freeObject(node->indxqualorig);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             FreeJoinFields
+ *
+ *             This function frees the fields of the Join node.  It is used by
+ *             all the free functions for classes which inherit node Join.
+ * ----------------
+ */
+static void
+FreeJoinFields(Join *node)
+{
+       /* nothing extra */
+       return;
+}
+
+
+/* ----------------
+ *             _freeJoin
+ * ----------------
+ */
+static void
+_freeJoin(Join *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeJoinFields(node);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeNestLoop
+ * ----------------
+ */
+static void
+_freeNestLoop(NestLoop *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeJoinFields((Join *) node);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeMergeJoin
+ * ----------------
+ */
+static void
+_freeMergeJoin(MergeJoin *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeJoinFields((Join *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->mergeclauses);
+
+       pfree(node->mergerightorder);
+       pfree(node->mergeleftorder);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeHashJoin
+ * ----------------
+ */
+static void
+_freeHashJoin(HashJoin *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeJoinFields((Join *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->hashclauses);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             FreeTempFields
+ *
+ *             This function frees the fields of the Temp node.  It is used by
+ *             all the free functions for classes which inherit node Temp.
+ * ----------------
+ */
+static void
+FreeTempFields(Temp *node)
+{
+       return;
+}
+
+
+/* ----------------
+ *             _freeTemp
+ * ----------------
+ */
+static void
+_freeTemp(Temp *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeTempFields(node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeMaterial
+ * ----------------
+ */
+static void
+_freeMaterial(Material *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeTempFields((Temp *) node);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeSort
+ * ----------------
+ */
+static void
+_freeSort(Sort *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeTempFields((Temp *) node);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeGroup
+ * ----------------
+ */
+static void
+_freeGroup(Group *node)
+{
+       FreePlanFields((Plan *) node);
+
+       pfree(node->grpColIdx);
+
+       pfree(node);
+}
+
+/* ---------------
+ *     _freeAgg
+ * --------------
+ */
+static void
+_freeAgg(Agg *node)
+{
+       FreePlanFields((Plan *) node);
+
+       freeList(node->aggs);
+
+       pfree(node);
+}
+
+/* ---------------
+ *     _freeGroupClause
+ * --------------
+ */
+static void
+_freeGroupClause(GroupClause *node)
+{
+       freeObject(node->entry);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeUnique
+ * ----------------
+ */
+static void
+_freeUnique(Unique *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+       FreeTempFields((Temp *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       if (node->uniqueAttr)
+               pfree(node->uniqueAttr);
+
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeHash
+ * ----------------
+ */
+static void
+_freeHash(Hash *node)
+{
+       /* ----------------
+        *      free node superclass fields
+        * ----------------
+        */
+       FreePlanFields((Plan *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->hashkey);
+
+       pfree(node);
+}
+
+static void
+_freeSubPlan(SubPlan *node)
+{
+       freeObject(node->plan);
+       freeObject(node->rtable);
+       freeList(node->setParam);
+       freeList(node->parParam);
+       freeObject(node->sublink);
+
+       pfree(node);
+}
+
+/* ****************************************************************
+ *                                        primnodes.h free functions
+ * ****************************************************************
+ */
+
+/* ----------------
+ *             _freeResdom
+ * ----------------
+ */
+static void
+_freeResdom(Resdom *node)
+{
+       if (node->resname != NULL)
+               pfree(node->resname);
+
+       pfree(node);
+}
+
+static void
+_freeFjoin(Fjoin *node)
+{
+       freeObject(node->fj_innerNode);
+       pfree(node->fj_results);
+       pfree(node->fj_alwaysDone);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeExpr
+ * ----------------
+ */
+static void
+_freeExpr(Expr *node)
+{
+       freeObject(node->oper);
+       freeObject(node->args);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeVar
+ * ----------------
+ */
+static void
+_freeVar(Var *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       pfree(node);
+}
+
+static void
+_freeFcache(FunctionCachePtr ptr)
+{
+       if (ptr->argOidVect)
+               pfree(ptr->argOidVect);
+       if (ptr->nullVect)
+               pfree(ptr->nullVect);
+       if (ptr->src)
+               pfree(ptr->src);
+       if (ptr->bin)
+               pfree(ptr->bin);
+       if (ptr->func_state)
+               pfree(ptr->func_state);
+       if (ptr->setArg)
+               pfree(ptr->setArg);
+
+       pfree(ptr);
+}
+
+/* ----------------
+ *             _freeOper
+ * ----------------
+ */
+static void
+_freeOper(Oper *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       if (node->op_fcache)
+               _freeFcache(node->op_fcache);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeConst
+ * ----------------
+ */
+static void
+_freeConst(Const *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       if (!node->constbyval)
+               pfree((void *)node->constvalue);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeParam
+ * ----------------
+ */
+static void
+_freeParam(Param *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       if (node->paramname != NULL)
+               pfree(node->paramname);
+       freeObject(node->param_tlist);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeFunc
+ * ----------------
+ */
+static void
+_freeFunc(Func *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->func_tlist);
+       freeObject(node->func_planlist);
+       if (node->func_fcache)
+               _freeFcache(node->func_fcache);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeAggref
+ * ----------------
+ */
+static void
+_freeAggref(Aggref *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       pfree(node->aggname);
+       freeObject(node->target);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeSubLink
+ * ----------------
+ */
+static void
+_freeSubLink(SubLink *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->lefthand);
+       freeObject(node->oper);
+       freeObject(node->subselect);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeCaseExpr
+ * ----------------
+ */
+static void
+_freeCaseExpr(CaseExpr *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->arg);
+       freeObject(node->args);
+       freeObject(node->defresult);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeCaseWhen
+ * ----------------
+ */
+static void
+_freeCaseWhen(CaseWhen *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->expr);
+       freeObject(node->result);
+
+       pfree(node);
+}
+
+static void
+_freeArray(Array *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       pfree(node);
+}
+
+static void
+_freeArrayRef(ArrayRef *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->refupperindexpr);
+       freeObject(node->reflowerindexpr);
+       freeObject(node->refexpr);
+       freeObject(node->refassgnexpr);
+
+       pfree(node);
+}
+
+/* ****************************************************************
+ *                                             relation.h free functions
+ * ****************************************************************
+ */
+
+/* ----------------
+ *             _freeRelOptInfo
+ * ----------------
+ */
+static void
+_freeRelOptInfo(RelOptInfo * node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeList(node->relids);
+
+       freeObject(node->targetlist);
+       freeObject(node->pathlist);
+       freeObject(node->unorderedpath);
+       freeObject(node->cheapestpath);
+
+       if (node->classlist)
+               pfree(node->classlist);
+
+       if (node->indexkeys)
+               pfree(node->indexkeys);
+
+       freeObject(node->indpred);
+
+       if (node->ordering)
+               pfree(node->ordering);
+
+       freeObject(node->restrictinfo);
+       freeObject(node->joininfo);
+       freeObject(node->innerjoin);
+       freeObject(node->superrels);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             FreePathFields
+ *
+ *             This function frees the fields of the Path node.  It is used by
+ *             all the free functions for classes which inherit node Path.
+ * ----------------
+ */
+static void
+FreePathFields(Path *node)
+{
+       if (node->p_ordering.ordtype == SORTOP_ORDER)
+       {
+               if (node->p_ordering.ord.sortop)
+                       pfree(node->p_ordering.ord.sortop);
+       }
+       else
+               freeObject(node->p_ordering.ord.merge);
+
+       freeObject(node->keys);
+
+       freeList(node->joinid);
+       freeObject(node->loc_restrictinfo);
+}
+
+/* ----------------
+ *             _freePath
+ * ----------------
+ */
+static void
+_freePath(Path *node)
+{
+       FreePathFields(node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeIndexPath
+ * ----------------
+ */
+static void
+_freeIndexPath(IndexPath *node)
+{
+       /* ----------------
+        *      free the node superclass fields
+        * ----------------
+        */
+       FreePathFields((Path *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeList(node->indexid);
+       freeObject(node->indexqual);
+
+       if (node->indexkeys)
+               pfree(node->indexkeys);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             FreeJoinPathFields
+ *
+ *             This function frees the fields of the JoinPath node.  It is used by
+ *             all the free functions for classes which inherit node JoinPath.
+ * ----------------
+ */
+static void
+FreeJoinPathFields(JoinPath *node)
+{
+       freeObject(node->pathinfo);
+       freeObject(node->outerjoinpath);
+       freeObject(node->innerjoinpath);
+}
+
+/* ----------------
+ *             _freeJoinPath
+ * ----------------
+ */
+static void
+_freeJoinPath(JoinPath *node)
+{
+       /* ----------------
+        *      free the node superclass fields
+        * ----------------
+        */
+       FreePathFields((Path *) node);
+       FreeJoinPathFields(node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeMergePath
+ * ----------------
+ */
+static void
+_freeMergePath(MergePath *node)
+{
+       /* ----------------
+        *      free the node superclass fields
+        * ----------------
+        */
+       FreePathFields((Path *) node);
+       FreeJoinPathFields((JoinPath *) node);
+
+       /* ----------------
+        *      free the remainder of the node
+        * ----------------
+        */
+       freeObject(node->path_mergeclauses);
+       freeObject(node->outersortkeys);
+       freeObject(node->innersortkeys);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeHashPath
+ * ----------------
+ */
+static void
+_freeHashPath(HashPath *node)
+{
+       /* ----------------
+        *      free the node superclass fields
+        * ----------------
+        */
+       FreePathFields((Path *) node);
+       FreeJoinPathFields((JoinPath *) node);
+
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->path_hashclauses);
+       freeObject(node->outerhashkeys);
+       freeObject(node->innerhashkeys);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeOrderKey
+ * ----------------
+ */
+static void
+_freeOrderKey(OrderKey *node)
+{
+       pfree(node);
+}
+
+
+/* ----------------
+ *             _freeJoinKey
+ * ----------------
+ */
+static void
+_freeJoinKey(JoinKey *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->outer);
+       freeObject(node->inner);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeMergeOrder
+ * ----------------
+ */
+static void
+_freeMergeOrder(MergeOrder *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeRestrictInfo
+ * ----------------
+ */
+static void
+_freeRestrictInfo(RestrictInfo * node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeObject(node->clause);
+       freeObject(node->indexids);
+       freeObject(node->mergejoinorder);
+       freeList(node->restrictinfojoinid);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             FreeJoinMethodFields
+ *
+ *             This function frees the fields of the JoinMethod node.  It is used by
+ *             all the free functions for classes which inherit node JoinMethod.
+ * ----------------
+ */
+static void
+FreeJoinMethodFields(JoinMethod *node)
+{
+       freeObject(node->jmkeys);
+       freeObject(node->clauses);
+       return;
+}
+
+/* ----------------
+ *             _freeJoinMethod
+ * ----------------
+ */
+static void
+_freeJoinMethod(JoinMethod *node)
+{
+       FreeJoinMethodFields(node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeHInfo
+ * ----------------
+ */
+static void
+_freeHashInfo(HashInfo *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       FreeJoinMethodFields((JoinMethod *) node);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeMInfo
+ * ----------------
+ */
+static void
+_freeMergeInfo(MergeInfo *node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       FreeJoinMethodFields((JoinMethod *) node);
+       freeObject(node->m_ordering);
+
+       pfree(node);
+}
+
+/* ----------------
+ *             _freeJoinInfo
+ * ----------------
+ */
+static void
+_freeJoinInfo(JoinInfo * node)
+{
+       /* ----------------
+        *      free remainder of node
+        * ----------------
+        */
+       freeList(node->otherrels);
+       freeObject(node->jinfo_restrictinfo);
+
+       pfree(node);
+}
+
+static void
+_freeIter(Iter *node)
+{
+       freeObject(node->iterexpr);
+
+       pfree(node);
+}
+
+static void
+_freeStream(Stream *node)
+{
+       freeObject(node->downstream);
+
+       pfree(node);
+}
+
+/* ****************
+ *                       parsenodes.h routines have no free functions
+ * ****************
+ */
+
+static void
+_freeTargetEntry(TargetEntry *node)
+{
+       freeObject(node->resdom);
+       freeObject(node->fjoin);
+       freeObject(node->expr);
+
+       pfree(node);
+}
+
+static void
+_freeRangeTblEntry(RangeTblEntry *node)
+{
+       if (node->relname)
+               pfree(node->relname);
+       if (node->refname)
+               pfree(node->refname);
+
+       pfree(node);
+}
+
+static void
+_freeRowMark(RowMark *node)
+{
+       pfree(node);
+}
+
+static void
+_freeSortClause(SortClause *node)
+{
+       freeObject(node->resdom);
+
+       pfree(node);
+}
+
+static void
+_freeAConst(A_Const *node)
+{
+       freeObject(&(node->val));
+       freeObject(node->typename);
+
+       pfree(node);
+}
+
+static void
+_freeTypeName(TypeName *node)
+{
+       if (node->name)
+               pfree(node->name);
+       freeObject(node->arrayBounds);
+
+       pfree(node);
+}
+
+static void
+_freeQuery(Query *node)
+{
+       if (node->utilityStmt && nodeTag(node->utilityStmt) == T_NotifyStmt)
+       {
+               NotifyStmt *node_notify = (NotifyStmt *) node->utilityStmt;
+
+               pfree(node_notify->relname);
+               pfree(node_notify);
+       }
+       if (node->into)
+               pfree(node->into);
+       if (node->uniqueFlag)
+               pfree(node->uniqueFlag);
+
+       freeObject(node->sortClause);
+       freeObject(node->rtable);
+       freeObject(node->targetList);
+       freeObject(node->qual);
+       freeObject(node->groupClause);
+       freeObject(node->havingQual);
+       freeObject(node->unionClause);
+       freeObject(node->limitOffset);
+       freeObject(node->limitCount);
+       freeObject(node->rowMark);
+
+       pfree(node);
+}
+
+
+/* ****************
+ *                       mnodes.h routines have no free functions
+ * ****************
+ */
+
+/* ****************************************************************
+ *                                     pg_list.h free functions
+ * ****************************************************************
+ */
+
+static void
+_freeValue(Value *node)
+{
+       switch (node->type)
+       {
+               case T_String:
+                       pfree(node->val.str);
+                       break;
+               default:
+                       break;
+       }
+
+       pfree(node);
+}
+
+/* ----------------
+ *             freeObject free's the node or list. If it is a list, it
+ *             recursively frees its items.
+ * ----------------
+ */
+void
+freeObject(void *node)
+{
+       if (node == NULL)
+               return;
+
+       switch (nodeTag(node))
+       {
+
+                       /*
+                        * PLAN NODES
+                        */
+               case T_Plan:
+                       _freePlan(node);
+                       break;
+               case T_Result:
+                       _freeResult(node);
+                       break;
+               case T_Append:
+                       _freeAppend(node);
+                       break;
+               case T_Scan:
+                       _freeScan(node);
+                       break;
+               case T_SeqScan:
+                       _freeSeqScan(node);
+                       break;
+               case T_IndexScan:
+                       _freeIndexScan(node);
+                       break;
+               case T_Join:
+                       _freeJoin(node);
+                       break;
+               case T_NestLoop:
+                       _freeNestLoop(node);
+                       break;
+               case T_MergeJoin:
+                       _freeMergeJoin(node);
+                       break;
+               case T_HashJoin:
+                       _freeHashJoin(node);
+                       break;
+               case T_Temp:
+                       _freeTemp(node);
+                       break;
+               case T_Material:
+                       _freeMaterial(node);
+                       break;
+               case T_Sort:
+                       _freeSort(node);
+                       break;
+               case T_Group:
+                       _freeGroup(node);
+                       break;
+               case T_Agg:
+                       _freeAgg(node);
+                       break;
+               case T_GroupClause:
+                       _freeGroupClause(node);
+                       break;
+               case T_Unique:
+                       _freeUnique(node);
+                       break;
+               case T_Hash:
+                       _freeHash(node);
+                       break;
+               case T_SubPlan:
+                       _freeSubPlan(node);
+                       break;
+
+                       /*
+                        * PRIMITIVE NODES
+                        */
+               case T_Resdom:
+                       _freeResdom(node);
+                       break;
+               case T_Fjoin:
+                       _freeFjoin(node);
+                       break;
+               case T_Expr:
+                       _freeExpr(node);
+                       break;
+               case T_Var:
+                       _freeVar(node);
+                       break;
+               case T_Oper:
+                       _freeOper(node);
+                       break;
+               case T_Const:
+                       _freeConst(node);
+                       break;
+               case T_Param:
+                       _freeParam(node);
+                       break;
+               case T_Func:
+                       _freeFunc(node);
+                       break;
+               case T_Array:
+                       _freeArray(node);
+                       break;
+               case T_ArrayRef:
+                       _freeArrayRef(node);
+                       break;
+               case T_Aggref:
+                       _freeAggref(node);
+                       break;
+               case T_SubLink:
+                       _freeSubLink(node);
+                       break;
+               case T_CaseExpr:
+                       _freeCaseExpr(node);
+                       break;
+               case T_CaseWhen:
+                       _freeCaseWhen(node);
+                       break;
+
+                       /*
+                        * RELATION NODES
+                        */
+               case T_RelOptInfo:
+                       _freeRelOptInfo(node);
+                       break;
+               case T_Path:
+                       _freePath(node);
+                       break;
+               case T_IndexPath:
+                       _freeIndexPath(node);
+                       break;
+               case T_JoinPath:
+                       _freeJoinPath(node);
+                       break;
+               case T_MergePath:
+                       _freeMergePath(node);
+                       break;
+               case T_HashPath:
+                       _freeHashPath(node);
+                       break;
+               case T_OrderKey:
+                       _freeOrderKey(node);
+                       break;
+               case T_JoinKey:
+                       _freeJoinKey(node);
+                       break;
+               case T_MergeOrder:
+                       _freeMergeOrder(node);
+                       break;
+               case T_RestrictInfo:
+                       _freeRestrictInfo(node);
+                       break;
+               case T_JoinMethod:
+                       _freeJoinMethod(node);
+                       break;
+               case T_HashInfo:
+                       _freeHashInfo(node);
+                       break;
+               case T_MergeInfo:
+                       _freeMergeInfo(node);
+                       break;
+               case T_JoinInfo:
+                       _freeJoinInfo(node);
+                       break;
+               case T_Iter:
+                       _freeIter(node);
+                       break;
+               case T_Stream:
+                       _freeStream(node);
+                       break;
+
+                       /*
+                        * PARSE NODES
+                        */
+               case T_Query:
+                       _freeQuery(node);
+                       break;
+               case T_TargetEntry:
+                       _freeTargetEntry(node);
+                       break;
+               case T_RangeTblEntry:
+                       _freeRangeTblEntry(node);
+                       break;
+               case T_RowMark:
+                       _freeRowMark(node);
+                       break;
+               case T_SortClause:
+                       _freeSortClause(node);
+                       break;
+               case T_A_Const:
+                       _freeAConst(node);
+                       break;
+               case T_TypeName:
+                       _freeTypeName(node);
+                       break;
+
+                       /*
+                        * VALUE NODES
+                        */
+               case T_Integer:
+               case T_String:
+               case T_Float:
+                       _freeValue(node);
+                       break;
+               case T_List:
+                       {
+                               List       *list = node,
+                                                  *l;
+
+                               foreach(l, list)
+                                       freeObject(lfirst(l));
+                               freeList(list);
+                       }
+                       break;
+               default:
+                       elog(ERROR, "freeObject: don't know how to free %d", nodeTag(node));
+                       break;
+       }
+}
index 008c629e5c6abfd10aacaefc39b16abbb8882e95..15b5094881e94bc7b0603848e84248087e694012 100644 (file)
@@ -7,12 +7,18 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.11 1998/09/01 04:33:34 momjian Exp $
- *
- * NOTE
- *       XXX This is a preliminary implementation which lacks fail-fast
- *       XXX validity checking of arguments.
+ *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/aset.c,v 1.12 1999/02/06 16:50:25 wieck Exp $
  *
+ * NOTE:
+ *     This is a new (Feb. 05, 1999) implementation of the allocation set
+ *     routines. AllocSet...() does not use OrderedSet...() any more.
+ *     Instead it manages allocations in a block pool by itself, combining
+ *     many small allocations in a few bigger blocks. AllocSetFree() does
+ *     never free() memory really. It just add's the free'd area to some
+ *     list for later reuse by AllocSetAlloc(). All memory blocks are free()'d
+ *     on AllocSetReset() at once, what happens when the memory context gets
+ *     destroyed.
+ *                             Jan Wieck
  *-------------------------------------------------------------------------
  */
 #include <stdio.h>
 #include <string.h>
 #endif
 
-static void AllocPointerDump(AllocPointer pointer);
-static int AllocSetIterate(AllocSet set,
-                               void (*function) (AllocPointer pointer));
 
 #undef AllocSetReset
 #undef malloc
 #undef free
+#undef realloc
 
-/*
- * Internal type definitions
- */
 
 /*
- * AllocElem --
- *             Allocation element.
+#define        ALLOC_BLOCK_SIZE        8192
+#define        ALLOC_CHUNK_LIMIT       512
+ *
+ * The above settings for block size and chunk limit gain better
+ * performance. But the ones below force a bug that I didn't found
+ * up to now letting the portals_p2 regression test fail.
+ *
  */
-typedef struct AllocElemData
-{
-       OrderedElemData elemData;       /* elem in AllocSet */
-       Size            size;
-} AllocElemData;
+#define        ALLOC_BLOCK_SIZE        16384
+#define        ALLOC_CHUNK_LIMIT       256
 
-typedef AllocElemData *AllocElem;
+#define ALLOC_BLOCKHDRSZ       MAXALIGN(sizeof(AllocBlockData))
+#define ALLOC_CHUNKHDRSZ       MAXALIGN(sizeof(AllocChunkData))
 
+#define AllocPointerGetChunk(ptr)      \
+                                       ((AllocChunk)(((char *)(ptr)) - ALLOC_CHUNKHDRSZ))
+#define AllocChunkGetPointer(chk)      \
+                                       ((AllocPointer)(((char *)(chk)) + ALLOC_CHUNKHDRSZ))
+#define AllocPointerGetAset(ptr)       ((AllocSet)(AllocPointerGetChunk(ptr)->aset))
+#define AllocPointerGetSize(ptr)       (AllocPointerGetChunk(ptr)->size)
 
-/*
- * Private method definitions
- */
 
-/*
- * AllocPointerGetAllocElem --
- *             Returns allocation (internal) elem given (external) pointer.
- */
-#define AllocPointerGetAllocElem(pointer)              (&((AllocElem)(pointer))[-1])
 
-/*
- * AllocElemGetAllocPointer --
- *             Returns allocation (external) pointer given (internal) elem.
+/* ----------
+ * AllocSetFreeIndex -
+ *
+ *             Depending on the size of an allocation compute which freechunk
+ *             list of the alloc set it belongs to.
+ * ----------
  */
-#define AllocElemGetAllocPointer(alloc) ((AllocPointer)&(alloc)[1])
+static inline int
+AllocSetFreeIndex(Size size)
+{
+       int idx = 0;
 
-/*
- * AllocElemIsValid --
- *             True iff alloc is valid.
- */
-#define AllocElemIsValid(alloc) PointerIsValid(alloc)
+       size = (size - 1) >> 4;
+       while (size != 0 && idx < 7)
+       {
+               idx++;
+               size >>= 1;
+       }
 
-/* non-export function prototypes */
-static AllocPointer AllocSetGetFirst(AllocSet set);
-static AllocPointer AllocPointerGetNext(AllocPointer pointer);
+       return idx;
+}
+                       
 
 /*
  * Public routines
@@ -111,9 +120,10 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
         * limit is also ignored.  This affects this whole file.
         */
 
-       OrderedSetInit(&set->setData, offsetof(AllocElemData, elemData));
+       memset(set, 0, sizeof(AllocSetData));
 }
 
+
 /*
  * AllocSetReset --
  *             Frees memory which is allocated in the given set.
@@ -124,28 +134,21 @@ AllocSetInit(AllocSet set, AllocMode mode, Size limit)
 void
 AllocSetReset(AllocSet set)
 {
-       AllocPointer pointer;
+       AllocBlock              block = set->blocks;
+       AllocBlock              next;
 
        AssertArg(AllocSetIsValid(set));
 
-       while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
-               AllocSetFree(set, pointer);
-}
-
-#ifdef NOT_USED
-void
-AllocSetReset_debug(char *file, int line, AllocSet set)
-{
-       AllocPointer pointer;
-
-       AssertArg(AllocSetIsValid(set));
+       while (block != NULL)
+       {
+               next = block->next;
+               free(block);
+               block = next;
+       }
 
-       while (AllocPointerIsValid(pointer = AllocSetGetFirst(set)))
-               AllocSetFree(set, pointer);
+       memset(set, 0, sizeof(AllocSetData));
 }
 
-#endif
-
 /*
  * AllocSetContains --
  *             True iff allocation set contains given allocation element.
@@ -160,8 +163,7 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
        AssertArg(AllocSetIsValid(set));
        AssertArg(AllocPointerIsValid(pointer));
 
-       return (OrderedSetContains(&set->setData,
-                                                 &AllocPointerGetAllocElem(pointer)->elemData));
+       return (AllocPointerGetAset(pointer) == set);
 }
 
 /*
@@ -176,23 +178,107 @@ AllocSetContains(AllocSet set, AllocPointer pointer)
 AllocPointer
 AllocSetAlloc(AllocSet set, Size size)
 {
-       AllocElem       alloc;
+       AllocBlock              block;
+       AllocChunk              chunk;
+       AllocChunk              freeref = NULL;
+       int                             fidx;
+       Size                    chunk_size;
 
        AssertArg(AllocSetIsValid(set));
 
-       /* allocate */
-       alloc = (AllocElem) malloc(sizeof(*alloc) + size);
+       /*
+        * Lookup in the corresponding free list if there is a
+        * free chunk we could reuse
+        *
+        */
+       fidx = AllocSetFreeIndex(size);
+       for (chunk = set->freelist[fidx]; chunk; chunk = (AllocChunk)chunk->aset)
+       {
+               if (chunk->size >= size)
+                       break;
+               freeref = chunk;
+       }
+
+       /*
+        * If found, remove it from the free list, make it again
+        * a member of the alloc set and return it's data address.
+        *
+        */
+       if (chunk != NULL)
+       {
+               if (freeref == NULL)
+                       set->freelist[fidx] = (AllocChunk)chunk->aset;
+               else
+                       freeref->aset = chunk->aset;
 
-       if (!PointerIsValid(alloc))
-               elog(FATAL, "palloc failure: memory exhausted");
+               chunk->aset = (void *)set;
+               return AllocChunkGetPointer(chunk);
+       }
 
-       /* add to allocation list */
-       OrderedElemPushInto(&alloc->elemData, &set->setData);
+       /*
+        * If requested size exceeds smallchunk limit, allocate a separate,
+        * entire used block for this allocation
+        *
+        */
+       if (size > ALLOC_CHUNK_LIMIT)
+       {
+               Size    blksize;
+
+               chunk_size = MAXALIGN(size);
+               blksize = chunk_size + ALLOC_BLOCKHDRSZ + ALLOC_CHUNKHDRSZ;
+               block = (AllocBlock) malloc(blksize);
+               if (block == NULL)
+                       elog(FATAL, "Memory exhausted in AllocSetAlloc()");
+               block->aset = set;
+               block->freeptr = block->endptr = ((char *)block) + ALLOC_BLOCKHDRSZ;
+
+               chunk = (AllocChunk) (((char *)block) + ALLOC_BLOCKHDRSZ);
+               chunk->aset = set;
+               chunk->size = chunk_size;
+
+               if (set->blocks != NULL)
+               {
+                       block->next = set->blocks->next;
+                       set->blocks->next = block;
+               }
+               else
+               {
+                       block->next = NULL;
+                       set->blocks = block;
+               }
+
+               return AllocChunkGetPointer(chunk);
+       }
 
-       /* set size */
-       alloc->size = size;
+       chunk_size = 16 << fidx;
 
-       return AllocElemGetAllocPointer(alloc);
+       if ((block = set->blocks) != NULL)
+       {
+               Size            have_free = block->endptr - block->freeptr;
+
+               if (have_free < (chunk_size + ALLOC_CHUNKHDRSZ))
+                       block = NULL;
+       }
+
+       if (block == NULL)
+       {
+               block = (AllocBlock) malloc(ALLOC_BLOCK_SIZE);
+               if (block == NULL)
+                       elog(FATAL, "Memory exhausted in AllocSetAlloc()");
+               block->aset = set;
+               block->next = set->blocks;
+               block->freeptr = ((char *)block) + ALLOC_BLOCKHDRSZ;
+               block->endptr = ((char *)block) + ALLOC_BLOCK_SIZE;
+
+               set->blocks = block;
+       }
+
+       chunk = (AllocChunk)(block->freeptr);
+       chunk->aset = (void *)set;
+       chunk->size = chunk_size;
+       block->freeptr += (chunk_size + ALLOC_CHUNKHDRSZ);
+
+       return AllocChunkGetPointer(chunk);
 }
 
 /*
@@ -207,19 +293,18 @@ AllocSetAlloc(AllocSet set, Size size)
 void
 AllocSetFree(AllocSet set, AllocPointer pointer)
 {
-       AllocElem       alloc;
+       int                             fidx;
+       AllocChunk              chunk;
 
        /* AssertArg(AllocSetIsValid(set)); */
        /* AssertArg(AllocPointerIsValid(pointer)); */
        AssertArg(AllocSetContains(set, pointer));
 
-       alloc = AllocPointerGetAllocElem(pointer);
-
-       /* remove from allocation set */
-       OrderedElemPop(&alloc->elemData);
+       chunk = AllocPointerGetChunk(pointer);
+       fidx = AllocSetFreeIndex(chunk->size);
 
-       /* free storage */
-       free(alloc);
+       chunk->aset = (void *)set->freelist[fidx];
+       set->freelist[fidx] = chunk;
 }
 
 /*
@@ -238,25 +323,26 @@ AllocPointer
 AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
 {
        AllocPointer newPointer;
-       AllocElem       alloc;
+       Size            oldsize;
 
        /* AssertArg(AllocSetIsValid(set)); */
        /* AssertArg(AllocPointerIsValid(pointer)); */
        AssertArg(AllocSetContains(set, pointer));
 
        /*
-        * Calling realloc(3) directly is not be possible (unless we use our
-        * own hacked version of malloc) since we must keep the allocations in
-        * the allocation set.
+        * Chunk sizes are aligned to power of 2 on AllocSetAlloc().
+        * Maybe the allocated area already is >= the new size.
+        *
         */
-
-       alloc = AllocPointerGetAllocElem(pointer);
+       if (AllocPointerGetSize(pointer) >= size)
+               return pointer;
 
        /* allocate new pointer */
        newPointer = AllocSetAlloc(set, size);
 
        /* fill new memory */
-       memmove(newPointer, pointer, (alloc->size < size) ? alloc->size : size);
+       oldsize = AllocPointerGetSize(pointer);
+       memmove(newPointer, pointer, (oldsize < size) ? oldsize : size);
 
        /* free old pointer */
        AllocSetFree(set, pointer);
@@ -264,118 +350,6 @@ AllocSetRealloc(AllocSet set, AllocPointer pointer, Size size)
        return newPointer;
 }
 
-/*
- * AllocSetIterate --
- *             Returns size of set.  Iterates through set elements calling function
- *             (if valid) on each.
- *
- * Note:
- *             This was written as an aid to debugging.  It is intended for
- *             debugging use only.
- *
- * Exceptions:
- *             BadArg if set is invalid.
- */
-static int
-AllocSetIterate(AllocSet set,
-                               void (*function) (AllocPointer pointer))
-{
-       int                     count = 0;
-       AllocPointer pointer;
-
-       AssertArg(AllocSetIsValid(set));
-
-       for (pointer = AllocSetGetFirst(set);
-                AllocPointerIsValid(pointer);
-                pointer = AllocPointerGetNext(pointer))
-       {
-
-               if (PointerIsValid(function))
-                       (*function) (pointer);
-               count += 1;
-       }
-
-       return count;
-}
-
-#ifdef NOT_USED
-int
-AllocSetCount(AllocSet set)
-{
-       int                     count = 0;
-       AllocPointer pointer;
-
-       AssertArg(AllocSetIsValid(set));
-
-       for (pointer = AllocSetGetFirst(set);
-                AllocPointerIsValid(pointer);
-                pointer = AllocPointerGetNext(pointer))
-               count++;
-       return count;
-}
-
-#endif
-
-/*
- * Private routines
- */
-
-/*
- * AllocSetGetFirst --
- *             Returns "first" allocation pointer in a set.
- *
- * Note:
- *             Assumes set is valid.
- */
-static AllocPointer
-AllocSetGetFirst(AllocSet set)
-{
-       AllocElem       alloc;
-
-       alloc = (AllocElem) OrderedSetGetHead(&set->setData);
-
-       if (!AllocElemIsValid(alloc))
-               return NULL;
-
-       return AllocElemGetAllocPointer(alloc);
-}
-
-/*
- * AllocPointerGetNext --
- *             Returns "successor" allocation pointer.
- *
- * Note:
- *             Assumes pointer is valid.
- */
-static AllocPointer
-AllocPointerGetNext(AllocPointer pointer)
-{
-       AllocElem       alloc;
-
-       alloc = (AllocElem)
-               OrderedElemGetSuccessor(&AllocPointerGetAllocElem(pointer)->elemData);
-
-       if (!AllocElemIsValid(alloc))
-               return NULL;
-
-       return AllocElemGetAllocPointer(alloc);
-}
-
-
-/*
- * Debugging routines
- */
-
-/*
- * XXX AllocPointerDump --
- *             Displays allocated pointer.
- */
-static void
-AllocPointerDump(AllocPointer pointer)
-{
-       printf("\t%-10ld@ %0#lx\n", ((long *) pointer)[-1], (long) pointer);            /* XXX */
-}
-
 /*
  * AllocSetDump --
  *             Displays allocated set.
@@ -383,8 +357,5 @@ AllocPointerDump(AllocPointer pointer)
 void
 AllocSetDump(AllocSet set)
 {
-       int                     count;
-
-       count = AllocSetIterate(set, AllocPointerDump);
-       printf("\ttotal %d allocations\n", count);
+       elog(DEBUG, "Currently unable to dump AllocSet");
 }
index 46c38697858d1ada504c4ae4673dae9f1dc31ccc..f0e2ee06f7a5ea355e2a934c16275e7f9c2df16a 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.10 1998/09/01 04:33:36 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/mcxt.c,v 1.11 1999/02/06 16:50:26 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -103,10 +103,11 @@ static struct MemoryContextMethodsData GlobalContextMethodsData = {
  */
 /* extern bool EqualGlobalMemory(); */
 
-static struct GlobalMemory TopGlobalMemoryData = {
+static struct GlobalMemoryData TopGlobalMemoryData = {
        T_GlobalMemory,                         /* NodeTag                              tag               */
        &GlobalContextMethodsData,      /* ContextMethods               method    */
-       {{0}},                                          /* uninitialized OrderedSetData allocSetD */
+       { NULL, { NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL }},
+                                                               /* free AllocSet   */
        "TopGlobal",                            /* char* name      */
        {0}                                                     /* uninitialized OrderedElemData elemD */
 };
@@ -162,7 +163,7 @@ EnableMemoryContext(bool on)
 
                /* make TopGlobalMemoryData member of ActiveGlobalMemorySet */
                OrderedSetInit(ActiveGlobalMemorySet,
-                                          offsetof(struct GlobalMemory, elemData));
+                                          offsetof(struct GlobalMemoryData, elemData));
                OrderedElemPushInto(&TopGlobalMemoryData.elemData,
                                                        ActiveGlobalMemorySet);
 
@@ -371,7 +372,7 @@ CreateGlobalMemory(char *name)      /* XXX MemoryContextName */
 
        savecxt = MemoryContextSwitchTo(TopMemoryContext);
 
-       context = (GlobalMemory) newNode(sizeof(struct GlobalMemory), T_GlobalMemory);
+       context = (GlobalMemory) newNode(sizeof(struct GlobalMemoryData), T_GlobalMemory);
        context->method = &GlobalContextMethodsData;
        context->name = name;           /* assumes name is static */
        AllocSetInit(&context->setData, DynamicAllocMode, (Size) 0);
index 9c50c3a30236cee083f71fdbd82ef3f16178465b..ad4e506f2fa6ebb80097a039376ac452245d0b8c 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.9 1999/01/17 03:04:54 tgl Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/Attic/palloc.c,v 1.10 1999/02/06 16:50:27 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
 
 #include "nodes/memnodes.h"
 
-#include "utils/palloc.h"
 
 /* ----------------------------------------------------------------
  *             User library functions
  * ----------------------------------------------------------------
  */
 
-#undef palloc
-#undef pfree
-#undef MemoryContextAlloc
-#undef MemoryContextFree
-#undef malloc
-#undef free
-
-/* define PALLOC_IS_MALLOC if you want palloc to go straight to the
-   raw malloc, without concern for the extra bookkeeping needed to
-   ensure garbage is collected at the end of transactions - jolly 1/12/94 */
-
-
-/*
- * palloc --
- *             Returns pointer to aligned memory of specified size.
- *
- * Exceptions:
- *             BadArgument if size < 1 or size >= MaxAllocSize.
- *             ExhaustedMemory if allocation fails.
- *             NonallocatedPointer if pointer was not returned by palloc or repalloc
- *                             or may have been freed already.
- *
- * pfree --
- *             Frees memory associated with pointer returned from palloc or repalloc.
- *
- * Exceptions:
- *             BadArgument if pointer is invalid.
- *             FreeInWrongContext if pointer was allocated in a different "context."
- *             NonallocatedPointer if pointer was not returned by palloc or repalloc
- *                             or may have been subsequently freed.
+/* ----------
+ * palloc(), pfree() and repalloc() are now macros in palloc.h
+ * ----------
  */
-void *
-palloc(Size size)
-{
-#ifdef PALLOC_IS_MALLOC
-       return malloc(size);
-#else
-       return MemoryContextAlloc(CurrentMemoryContext, size);
-#endif  /* PALLOC_IS_MALLOC */
-}
 
-void
-pfree(void *pointer)
-{
-#ifdef PALLOC_IS_MALLOC
-       free(pointer);
-#else
-       MemoryContextFree(CurrentMemoryContext, pointer);
-#endif  /* PALLOC_IS_MALLOC */
-}
-
-/*
- * repalloc --
- *             Returns pointer to aligned memory of specified size.
- *
- * Side effects:
- *             The returned memory is first filled with the contents of *pointer
- *             up to the minimum of size and psize(pointer).  Pointer is freed.
- *
- * Exceptions:
- *             BadArgument if pointer is invalid or size < 1 or size >= MaxAllocSize.
- *             ExhaustedMemory if allocation fails.
- *             NonallocatedPointer if pointer was not returned by palloc or repalloc
- *                             or may have been freed already.
- */
-void *
-repalloc(void *pointer, Size size)
-{
-#ifdef PALLOC_IS_MALLOC
-       return realloc(pointer, size);
-#else
-       return MemoryContextRealloc(CurrentMemoryContext, pointer, size);
-#endif
-}
-
-/* pstrdup
-       allocates space for and copies a string
-       just like strdup except it uses palloc instead of malloc */
 char *
 pstrdup(char *string)
 {
-       char       *nstr;
+       char            *nstr;
+       int                     len;
 
-       nstr = (char *) palloc(strlen(string) + 1);
-       strcpy(nstr, string);
+       nstr = palloc(len = strlen(string) + 1);
+       MemoryCopy(nstr, string, len);
 
        return nstr;
 }
+
index c6c31bc18179d652daa6de344f707d32a18acbc2..1aa456b943b95b4baa3bc8f0d046557eb95e05f0 100644 (file)
@@ -7,7 +7,7 @@
  *
  *
  * IDENTIFICATION
- *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.16 1999/02/03 21:17:40 momjian Exp $
+ *       $Header: /cvsroot/pgsql/src/backend/utils/mmgr/portalmem.c,v 1.17 1999/02/06 16:50:28 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -812,6 +812,25 @@ PortalDestroy(Portal *portalP)
                                          (Pointer) portal->name);
        AllocSetReset(&portal->variable.setData);       /* XXX log */
 
+       /*
+        * In the case of a transaction abort it is possible that
+        * we get called while one of the memory contexts of the portal
+        * we're destroying is the current memory context.
+        * 
+        * Don't know how to handle that cleanly because it is required
+        * to be in that context right now. This portal struct remains
+        * allocated in the PortalMemory context until backend dies.
+        *
+        * Not happy with that, but it's better to loose some bytes of
+        * memory than to have the backend dump core.
+        *
+        * --- Feb. 04, 1999 Jan Wieck
+        */
+       if (CurrentMemoryContext == (MemoryContext)PortalGetHeapMemory(portal))
+               return;
+       if (CurrentMemoryContext == (MemoryContext)PortalGetVariableMemory(portal))
+               return;
+
        if (portal != BlankPortal)
                MemoryContextFree((MemoryContext) PortalMemory, (Pointer) portal);
 }
index accf6ed131d3cf938a7d621f25c8b3019618aa1a..4be4fe42620532a5cf8636b6287d5567001ec73f 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: memnodes.h,v 1.8 1998/09/01 04:36:39 momjian Exp $
+ * $Id: memnodes.h,v 1.9 1999/02/06 16:50:30 wieck Exp $
  *
  * XXX the typedefs in this file are different from the other ???nodes.h;
  *       they are pointers to structures instead of the structures themselves.
@@ -56,7 +56,7 @@ typedef struct MemoryContextMethodsData
        void            (*dump) ();
 }                 *MemoryContextMethods;
 
-typedef struct MemoryContext
+typedef struct MemoryContextData
 {
        NodeTag         type;
        MemoryContextMethods method;
@@ -64,7 +64,7 @@ typedef struct MemoryContext
 
 /* think about doing this right some time but we'll have explicit fields
    for now -ay 10/94 */
-typedef struct GlobalMemory
+typedef struct GlobalMemoryData
 {
        NodeTag         type;
        MemoryContextMethods method;
@@ -75,14 +75,14 @@ typedef struct GlobalMemory
 
 typedef MemoryContext *PortalMemoryContext;
 
-typedef struct PortalVariableMemory
+typedef struct PortalVariableMemoryData
 {
        NodeTag         type;
        MemoryContextMethods method;
        AllocSetData setData;
 }                 *PortalVariableMemory;
 
-typedef struct PortalHeapMemory
+typedef struct PortalHeapMemoryData
 {
        NodeTag         type;
        MemoryContextMethods method;
index d001c33c991b4f9a4d06762f2566b18abf3c6b42..2635f1d7603954d72ad319287e9c06910098f170 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: nodes.h,v 1.38 1999/02/04 03:19:10 momjian Exp $
+ * $Id: nodes.h,v 1.39 1999/02/06 16:50:31 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -282,6 +282,11 @@ extern void *stringToNode(char *str);
  */
 extern void *copyObject(void *obj);
 
+/*
+ * nodes/freefuncs.c
+ */
+extern void freeObject(void *obj);
+
 /*
  * nodes/equalfuncs.c
  */
index 9e1adb796f6ba0e756507615ec735fac435a8710..0bf4f6ef13bf7d4da3254ce7cef206a0647b8de4 100644 (file)
@@ -15,7 +15,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: memutils.h,v 1.19 1998/12/26 18:15:53 momjian Exp $
+ * $Id: memutils.h,v 1.20 1999/02/06 16:50:33 wieck Exp $
  *
  * NOTES
  *       some of the information in this file will be moved to
@@ -208,13 +208,41 @@ typedef enum AllocMode
 
 #define DefaultAllocMode               DynamicAllocMode
 
+/*
+ * AllocBlock --
+ *             Small pieces of memory are taken from bigger blocks of
+ *             memory with a size aligned to a power of two. These
+ *             pieces are not free's separately, instead they are reused
+ *             for the next allocation of a fitting size.
+ */
+typedef struct AllocBlockData {
+       struct AllocSetData                     *aset;
+       struct AllocBlockData           *next;
+       char                                            *freeptr;
+       char                                            *endptr;
+} AllocBlockData;
+
+typedef AllocBlockData *AllocBlock;
+
+/*
+ * AllocChunk --
+ *             The prefix of each piece of memory in an AllocBlock
+ */
+typedef struct AllocChunkData {
+       void                                            *aset;
+       Size                                            size;
+} AllocChunkData;
+
+typedef AllocChunkData *AllocChunk;
+
 /*
  * AllocSet --
  *             Allocation set.
  */
 typedef struct AllocSetData
 {
-       OrderedSetData setData;
+       struct AllocBlockData           *blocks;
+       struct AllocChunkData           *freelist[8];
        /* Note: this will change in the future to support other modes */
 } AllocSetData;
 
index 2c969df174c91c223ffc55738cac2357c9404acf..05fccc81a321b4ff1d19278d30fe902346ad9e6a 100644 (file)
@@ -6,18 +6,34 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: palloc.h,v 1.6 1998/09/01 04:39:24 momjian Exp $
+ * $Id: palloc.h,v 1.7 1999/02/06 16:50:34 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
 #ifndef PALLOC_H
 #define PALLOC_H
 
-#include <c.h>
+#include "c.h"
 
-extern void *palloc(Size size);
-extern void pfree(void *pointer);
-extern void *repalloc(void *pointer, Size size);
+#ifdef PALLOC_IS_MALLOC
+
+#  define palloc(s)            malloc(s)
+#  define pfree(p)             free(p)
+#  define repalloc(p,s)        realloc((p),(s))
+
+#else /* ! PALLOC_IS_MALLOC */
+
+/* ----------
+ * In the case we use memory contexts, use macro's for palloc() etc.
+ * ----------
+ */
+#  include "utils/mcxt.h"
+
+#  define palloc(s)            ((void *)MemoryContextAlloc(CurrentMemoryContext,(Size)(s)))
+#  define pfree(p)             MemoryContextFree(CurrentMemoryContext,(Pointer)(p))
+#  define repalloc(p,s)        ((void *)MemoryContextRealloc(CurrentMemoryContext,(Pointer)(p),(Size)(s)))
+
+#endif /* PALLOC_IS_MALLOC */
 
 /* like strdup except uses palloc */
 extern char *pstrdup(char *pointer);
index 2c739721214267df5e0d01090a96b7220d7cc614..b718221cb552688343307c37f260308009316f97 100644 (file)
@@ -6,7 +6,7 @@
  *
  * Copyright (c) 1994, Regents of the University of California
  *
- * $Id: portal.h,v 1.10 1998/09/01 04:39:25 momjian Exp $
+ * $Id: portal.h,v 1.11 1999/02/06 16:50:34 wieck Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -44,8 +44,8 @@ typedef PortalD *Portal;
 struct PortalD
 {
        char       *name;                       /* XXX PortalName */
-       struct PortalVariableMemory variable;
-       struct PortalHeapMemory heap;
+       struct PortalVariableMemoryData variable;
+       struct PortalHeapMemoryData heap;
        QueryDesc  *queryDesc;
        TupleDesc       attinfo;
        EState     *state;