Tweak accumArrayResult() to double the size of its working arrays when
authorTom Lane
Wed, 8 Nov 2006 19:24:38 +0000 (19:24 +0000)
committerTom Lane
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 b510d42bb90ec48c830ea852e30b20e20c5701bb..667335b5ab300b21c4a5561bbe09dd5191d31fb9 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 a273ee765e11c2fd486cb6d5de3d34cc94282cf4..791f6ebd9993825e2e0816bfa129a686dde1011a 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;