New alloc set code using a memory block pool for small allocations.
authorJan Wieck
Sat, 6 Feb 1999 16:50:34 +0000 (16:50 +0000)
committerJan Wieck
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 
+#include 
+
+#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 
 #include 
 #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 
+#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;