OSDN Git Service

Tweak accumArrayResult() to double the size of its working arrays when
authorTom Lane <tgl@sss.pgh.pa.us>
Wed, 8 Nov 2006 19:24:38 +0000 (19:24 +0000)
committerTom Lane <tgl@sss.pgh.pa.us>
Wed, 8 Nov 2006 19:24:38 +0000 (19:24 +0000)
more space is needed, instead of incrementing by a fixed amount; the old
method wastes lots of space and time when the ultimate size is large.
Per gripe from Tatsuo.

src/backend/utils/adt/arrayfuncs.c
src/include/utils/array.h

index b510d42..667335b 100644 (file)
@@ -8,7 +8,7 @@
  *
  *
  * IDENTIFICATION
- *       $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.134 2006/10/06 17:13:59 petere Exp $
+ *       $PostgreSQL: pgsql/src/backend/utils/adt/arrayfuncs.c,v 1.135 2006/11/08 19:24:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -4337,10 +4337,9 @@ accumArrayResult(ArrayBuildState *astate,
                oldcontext = MemoryContextSwitchTo(arr_context);
                astate = (ArrayBuildState *) palloc(sizeof(ArrayBuildState));
                astate->mcontext = arr_context;
-               astate->dvalues = (Datum *)
-                       palloc(ARRAY_ELEMS_CHUNKSIZE * sizeof(Datum));
-               astate->dnulls = (bool *)
-                       palloc(ARRAY_ELEMS_CHUNKSIZE * sizeof(bool));
+               astate->alen = 64;              /* arbitrary starting array size */
+               astate->dvalues = (Datum *) palloc(astate->alen * sizeof(Datum));
+               astate->dnulls = (bool *) palloc(astate->alen * sizeof(bool));
                astate->nelems = 0;
                astate->element_type = element_type;
                get_typlenbyvalalign(element_type,
@@ -4353,14 +4352,13 @@ accumArrayResult(ArrayBuildState *astate,
                oldcontext = MemoryContextSwitchTo(astate->mcontext);
                Assert(astate->element_type == element_type);
                /* enlarge dvalues[]/dnulls[] if needed */
-               if ((astate->nelems % ARRAY_ELEMS_CHUNKSIZE) == 0)
+               if (astate->nelems >= astate->alen)
                {
+                       astate->alen *= 2;
                        astate->dvalues = (Datum *)
-                               repalloc(astate->dvalues,
-                                  (astate->nelems + ARRAY_ELEMS_CHUNKSIZE) * sizeof(Datum));
+                               repalloc(astate->dvalues, astate->alen * sizeof(Datum));
                        astate->dnulls = (bool *)
-                               repalloc(astate->dnulls,
-                                       (astate->nelems + ARRAY_ELEMS_CHUNKSIZE) * sizeof(bool));
+                               repalloc(astate->dnulls, astate->alen * sizeof(bool));
                }
        }
 
index a273ee7..791f6eb 100644 (file)
@@ -49,7 +49,7 @@
  * Portions Copyright (c) 1996-2006, PostgreSQL Global Development Group
  * Portions Copyright (c) 1994, Regents of the University of California
  *
- * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.59 2006/09/10 20:14:20 tgl Exp $
+ * $PostgreSQL: pgsql/src/include/utils/array.h,v 1.60 2006/11/08 19:24:38 tgl Exp $
  *
  *-------------------------------------------------------------------------
  */
@@ -78,13 +78,8 @@ typedef struct ArrayBuildState
        MemoryContext mcontext;         /* where all the temp stuff is kept */
        Datum      *dvalues;            /* array of accumulated Datums */
        bool       *dnulls;                     /* array of is-null flags for Datums */
-
-       /*
-        * The allocated size of dvalues[] and dnulls[] is always a multiple of
-        * ARRAY_ELEMS_CHUNKSIZE
-        */
-#define ARRAY_ELEMS_CHUNKSIZE  64
-       int                     nelems;                 /* number of valid Datums in dvalues[] */
+       int                     alen;                   /* allocated length of above arrays */
+       int                     nelems;                 /* number of valid entries in above arrays */
        Oid                     element_type;   /* data type of the Datums */
        int16           typlen;                 /* needed info about datatype */
        bool            typbyval;