@@ -34,7 +34,7 @@ OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
3434/* Entries 1 upto MAXSAVESIZE are free lists, entry 0 is the empty
3535 tuple () of which at most one instance will be allocated.
3636*/
37- static tupleobject * free_list [MAXSAVESIZE ];
37+ static tupleobject * free_tuples [MAXSAVESIZE ];
3838#endif
3939#ifdef COUNT_ALLOCS
4040int fast_tuple_allocs ;
@@ -52,16 +52,16 @@ newtupleobject(size)
5252 return NULL ;
5353 }
5454#if MAXSAVESIZE > 0
55- if (size == 0 && free_list [0 ]) {
56- op = free_list [0 ];
55+ if (size == 0 && free_tuples [0 ]) {
56+ op = free_tuples [0 ];
5757 INCREF (op );
5858#ifdef COUNT_ALLOCS
5959 tuple_zero_allocs ++ ;
6060#endif
6161 return (object * ) op ;
6262 }
63- if (0 < size && size < MAXSAVESIZE && (op = free_list [size ]) != NULL ) {
64- free_list [size ] = (tupleobject * ) op -> ob_item [0 ];
63+ if (0 < size && size < MAXSAVESIZE && (op = free_tuples [size ]) != NULL ) {
64+ free_tuples [size ] = (tupleobject * ) op -> ob_item [0 ];
6565#ifdef COUNT_ALLOCS
6666 fast_tuple_allocs ++ ;
6767#endif
@@ -80,7 +80,7 @@ newtupleobject(size)
8080 NEWREF (op );
8181#if MAXSAVESIZE > 0
8282 if (size == 0 ) {
83- free_list [0 ] = op ;
83+ free_tuples [0 ] = op ;
8484 INCREF (op ); /* extra INCREF so that this is never freed */
8585 }
8686#endif
@@ -149,8 +149,8 @@ tupledealloc(op)
149149 XDECREF (op -> ob_item [i ]);
150150#if MAXSAVESIZE > 0
151151 if (0 < op -> ob_size && op -> ob_size < MAXSAVESIZE ) {
152- op -> ob_item [0 ] = (object * ) free_list [op -> ob_size ];
153- free_list [op -> ob_size ] = op ;
152+ op -> ob_item [0 ] = (object * ) free_tuples [op -> ob_size ];
153+ free_tuples [op -> ob_size ] = op ;
154154 } else
155155#endif
156156 free ((ANY * )op );
@@ -397,36 +397,67 @@ typeobject Tupletype = {
397397 is only one module referencing the object. You can also think of it
398398 as creating a new tuple object and destroying the old one, only
399399 more efficiently. In any case, don't use this if the tuple may
400- already be known to some other part of the code... */
400+ already be known to some other part of the code...
401+ If last_is_sticky is set, the tuple will grow or shrink at the
402+ front, otherwise it will grow or shrink at the end. */
401403
402404int
403- resizetuple (pv , newsize )
405+ resizetuple (pv , newsize , last_is_sticky )
404406 object * * pv ;
405407 int newsize ;
408+ int last_is_sticky ;
406409{
407- register object * v ;
410+ register tupleobject * v ;
408411 register tupleobject * sv ;
409- v = * pv ;
412+ int i ;
413+ int sizediff ;
414+
415+ v = (tupleobject * ) * pv ;
416+ sizediff = newsize - v -> ob_size ;
410417 if (!is_tupleobject (v ) || v -> ob_refcnt != 1 ) {
411418 * pv = 0 ;
412419 DECREF (v );
413420 err_badcall ();
414421 return -1 ;
415422 }
423+ if (sizediff == 0 )
424+ return 0 ;
416425 /* XXX UNREF/NEWREF interface should be more symmetrical */
417426#ifdef REF_DEBUG
418427 -- ref_total ;
419428#endif
420429 UNREF (v );
421- * pv = (object * )
430+ if (last_is_sticky && sizediff < 0 ) {
431+ /* shrinking: move entries to the front and zero moved entries */
432+ for (i = 0 ; i < newsize ; i ++ ) {
433+ XDECREF (v -> ob_item [i ]);
434+ v -> ob_item [i ] = v -> ob_item [i - sizediff ];
435+ v -> ob_item [i - sizediff ] = NULL ;
436+ }
437+ }
438+ for (i = newsize ; i < v -> ob_size ; i ++ ) {
439+ XDECREF (v -> ob_item [i ]);
440+ v -> ob_item [i ] = NULL ;
441+ }
442+ sv = (tupleobject * )
422443 realloc ((char * )v ,
423444 sizeof (tupleobject ) + newsize * sizeof (object * ));
424- if (* pv == NULL ) {
445+ * pv = (object * ) sv ;
446+ if (sv == NULL ) {
425447 DEL (v );
426448 err_nomem ();
427449 return -1 ;
428450 }
429- NEWREF (* pv );
430- ((tupleobject * ) * pv )-> ob_size = newsize ;
451+ NEWREF (sv );
452+ for (i = sv -> ob_size ; i < newsize ; i ++ )
453+ sv -> ob_item [i ] = NULL ;
454+ if (last_is_sticky && sizediff > 0 ) {
455+ /* growing: move entries to the end and zero moved entries */
456+ for (i = newsize - 1 ; i >= sizediff ; i -- ) {
457+ sv -> ob_item [i ] = sv -> ob_item [i - sizediff ];
458+ sv -> ob_item [i - sizediff ] = NULL ;
459+ }
460+ }
461+ sv -> ob_size = newsize ;
431462 return 0 ;
432463}
0 commit comments