]> git.ipfire.org Git - thirdparty/Python/cpython.git/commitdiff
Fixed bugs in resizetuple and extended the interface.
authorSjoerd Mullender <sjoerd@acm.org>
Mon, 1 Nov 1993 13:46:50 +0000 (13:46 +0000)
committerSjoerd Mullender <sjoerd@acm.org>
Mon, 1 Nov 1993 13:46:50 +0000 (13:46 +0000)
Added ifdefs in stringobject.c for shared strings of length 1.
Renamed free_list in tupleobject.c to free_tuples.

Include/tupleobject.h
Objects/stringobject.c
Objects/tupleobject.c
Python/bltinmodule.c

index 8fe28a2394cdc7cdf6c7cb434e23b7b2605baf3f..9897f6d135ec99324cbbcc1c47778d41f67c668b 100644 (file)
@@ -58,7 +58,7 @@ extern int gettuplesize PROTO((object *));
 extern object *gettupleitem PROTO((object *, int));
 extern int settupleitem PROTO((object *, int, object *));
 extern object *gettupleslice PROTO((object *, int, int));
-extern int resizetuple PROTO((object **, int));
+extern int resizetuple PROTO((object **, int, int));
 
 /* Macro, trading safety for speed */
 #define GETTUPLEITEM(op, i) ((op)->ob_item[i])
index 61863b63d08b83db51d9b1fa74e4c2a587db4bb1..0d03a3ba2b4f8c3651004daa9482b477f57b93e7 100644 (file)
@@ -39,7 +39,9 @@ int null_strings, one_strings;
 #endif
 
 static stringobject *characters[UCHAR_MAX + 1];
+#ifndef DONT_SHARE_SHORT_STRINGS
 static stringobject *nullstring;
+#endif
 
 /*
    Newsizedstringobject() and newstringobject() try in certain cases
@@ -62,6 +64,7 @@ newsizedstringobject(str, size)
        int size;
 {
        register stringobject *op;
+#ifndef DONT_SHARE_SHORT_STRINGS
        if (size == 0 && (op = nullstring) != NULL) {
 #ifdef COUNT_ALLOCS
                null_strings++;
@@ -76,6 +79,7 @@ newsizedstringobject(str, size)
                INCREF(op);
                return (object *)op;
        }
+#endif /* DONT_SHARE_SHORT_STRINGS */
        op = (stringobject *)
                malloc(sizeof(stringobject) + size * sizeof(char));
        if (op == NULL)
@@ -89,6 +93,7 @@ newsizedstringobject(str, size)
        if (str != NULL)
                memcpy(op->ob_sval, str, size);
        op->ob_sval[size] = '\0';
+#ifndef DONT_SHARE_SHORT_STRINGS
        if (size == 0) {
                nullstring = op;
                INCREF(op);
@@ -96,6 +101,7 @@ newsizedstringobject(str, size)
                characters[*str & UCHAR_MAX] = op;
                INCREF(op);
        }
+#endif
        return (object *) op;
 }
 
@@ -105,6 +111,7 @@ newstringobject(str)
 {
        register unsigned int size = strlen(str);
        register stringobject *op;
+#ifndef DONT_SHARE_SHORT_STRINGS
        if (size == 0 && (op = nullstring) != NULL) {
 #ifdef COUNT_ALLOCS
                null_strings++;
@@ -119,6 +126,7 @@ newstringobject(str)
                INCREF(op);
                return (object *)op;
        }
+#endif /* DONT_SHARE_SHORT_STRINGS */
        op = (stringobject *)
                malloc(sizeof(stringobject) + size * sizeof(char));
        if (op == NULL)
@@ -130,6 +138,7 @@ newstringobject(str)
 #endif
        NEWREF(op);
        strcpy(op->ob_sval, str);
+#ifndef DONT_SHARE_SHORT_STRINGS
        if (size == 0) {
                nullstring = op;
                INCREF(op);
@@ -137,6 +146,7 @@ newstringobject(str)
                characters[*str & UCHAR_MAX] = op;
                INCREF(op);
        }
+#endif
        return (object *) op;
 }
 
index 0047a09c7e838bdc79872a927b24b9d68e07aba2..68fed9e45facf8887858d69bad047b6e8b64df79 100644 (file)
@@ -34,7 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 /* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
    tuple () of which at most one instance will be allocated.
 */
-static tupleobject *free_list[MAXSAVESIZE];
+static tupleobject *free_tuples[MAXSAVESIZE];
 #endif
 #ifdef COUNT_ALLOCS
 int fast_tuple_allocs;
@@ -52,16 +52,16 @@ newtupleobject(size)
                return NULL;
        }
 #if MAXSAVESIZE > 0
-       if (size == 0 && free_list[0]) {
-               op = free_list[0];
+       if (size == 0 && free_tuples[0]) {
+               op = free_tuples[0];
                INCREF(op);
 #ifdef COUNT_ALLOCS
                tuple_zero_allocs++;
 #endif
                return (object *) op;
        }
-       if (0 < size && size < MAXSAVESIZE && (op = free_list[size]) != NULL) {
-               free_list[size] = (tupleobject *) op->ob_item[0];
+       if (0 < size && size < MAXSAVESIZE && (op = free_tuples[size]) != NULL) {
+               free_tuples[size] = (tupleobject *) op->ob_item[0];
 #ifdef COUNT_ALLOCS
                fast_tuple_allocs++;
 #endif
@@ -80,7 +80,7 @@ newtupleobject(size)
        NEWREF(op);
 #if MAXSAVESIZE > 0
        if (size == 0) {
-               free_list[0] = op;
+               free_tuples[0] = op;
                INCREF(op);     /* extra INCREF so that this is never freed */
        }
 #endif
@@ -149,8 +149,8 @@ tupledealloc(op)
                XDECREF(op->ob_item[i]);
 #if MAXSAVESIZE > 0
        if (0 < op->ob_size && op->ob_size < MAXSAVESIZE) {
-               op->ob_item[0] = (object *) free_list[op->ob_size];
-               free_list[op->ob_size] = op;
+               op->ob_item[0] = (object *) free_tuples[op->ob_size];
+               free_tuples[op->ob_size] = op;
        } else
 #endif
                free((ANY *)op);
@@ -397,36 +397,67 @@ typeobject Tupletype = {
    is only one module referencing the object.  You can also think of it
    as creating a new tuple object and destroying the old one, only
    more efficiently.  In any case, don't use this if the tuple may
-   already be known to some other part of the code... */
+   already be known to some other part of the code...
+   If last_is_sticky is set, the tuple will grow or shrink at the
+   front, otherwise it will grow or shrink at the end. */
 
 int
-resizetuple(pv, newsize)
+resizetuple(pv, newsize, last_is_sticky)
        object **pv;
        int newsize;
+       int last_is_sticky;
 {
-       register object *v;
+       register tupleobject *v;
        register tupleobject *sv;
-       v = *pv;
+       int i;
+       int sizediff;
+
+       v = (tupleobject *) *pv;
+       sizediff = newsize - v->ob_size;
        if (!is_tupleobject(v) || v->ob_refcnt != 1) {
                *pv = 0;
                DECREF(v);
                err_badcall();
                return -1;
        }
+       if (sizediff == 0)
+               return 0;
        /* XXX UNREF/NEWREF interface should be more symmetrical */
 #ifdef REF_DEBUG
        --ref_total;
 #endif
        UNREF(v);
-       *pv = (object *)
+       if (last_is_sticky && sizediff < 0) {
+               /* shrinking: move entries to the front and zero moved entries */
+               for (i = 0; i < newsize; i++) {
+                       XDECREF(v->ob_item[i]);
+                       v->ob_item[i] = v->ob_item[i - sizediff];
+                       v->ob_item[i - sizediff] = NULL;
+               }
+       }
+       for (i = newsize; i < v->ob_size; i++) {
+               XDECREF(v->ob_item[i]);
+               v->ob_item[i] = NULL;
+       }
+       sv = (tupleobject *)
                realloc((char *)v,
                        sizeof(tupleobject) + newsize * sizeof(object *));
-       if (*pv == NULL) {
+       *pv = (object *) sv;
+       if (sv == NULL) {
                DEL(v);
                err_nomem();
                return -1;
        }
-       NEWREF(*pv);
-       ((tupleobject *) *pv)->ob_size = newsize;
+       NEWREF(sv);
+       for (i = sv->ob_size; i < newsize; i++)
+               sv->ob_item[i] = NULL;
+       if (last_is_sticky && sizediff > 0) {
+               /* growing: move entries to the end and zero moved entries */
+               for (i = newsize - 1; i >= sizediff; i--) {
+                       sv->ob_item[i] = sv->ob_item[i - sizediff];
+                       sv->ob_item[i - sizediff] = NULL;
+               }
+       }
+       sv->ob_size = newsize;
        return 0;
 }
index f4d7f47ae94135c2e5d7095a4554b6e2da87e229..6069ae051f296a905aac9f15c48f0d2e24ee920c 100644 (file)
@@ -1319,7 +1319,7 @@ filtertuple(func, tuple)
                }
        }
 
-       if (resizetuple(&result, j) < 0)
+       if (resizetuple(&result, j, 0) < 0)
                return NULL;
 
        if (shared)