@@ -162,7 +162,13 @@ struct dictobject {
162162 PyObject_HEAD
163163 int ma_fill ; /* # Active + # Dummy */
164164 int ma_used ; /* # Active */
165- int ma_size ; /* total # slots in ma_table */
165+
166+ /* The table contains ma_mask + 1 slots, and that's a power of 2.
167+ * We store the mask instead of the size because the mask is more
168+ * frequently needed.
169+ */
170+ int ma_mask ;
171+
166172 /* ma_table points to ma_smalltable for small tables, else to
167173 * additional malloc'ed memory. ma_table is never NULL! This rule
168174 * saves repeated runtime null-tests in the workhorse getitem and
@@ -194,7 +200,7 @@ show_counts(void)
194200#define empty_to_minsize (mp ) do { \
195201 memset((mp)->ma_smalltable, 0, sizeof((mp)->ma_smalltable)); \
196202 (mp)->ma_table = (mp)->ma_smalltable; \
197- (mp)->ma_size = MINSIZE; \
203+ (mp)->ma_mask = MINSIZE - 1 ; \
198204 (mp)->ma_used = (mp)->ma_fill = 0; \
199205 } while(0)
200206
@@ -248,7 +254,7 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
248254 register int i ;
249255 register unsigned int perturb ;
250256 register dictentry * freeslot ;
251- register unsigned int mask = mp -> ma_size - 1 ;
257+ register unsigned int mask = mp -> ma_mask ;
252258 dictentry * ep0 = mp -> ma_table ;
253259 register dictentry * ep ;
254260 register int restore_error ;
@@ -359,7 +365,7 @@ lookdict_string(dictobject *mp, PyObject *key, register long hash)
359365 register int i ;
360366 register unsigned int perturb ;
361367 register dictentry * freeslot ;
362- register unsigned int mask = mp -> ma_size - 1 ;
368+ register unsigned int mask = mp -> ma_mask ;
363369 dictentry * ep0 = mp -> ma_table ;
364370 register dictentry * ep ;
365371
@@ -492,7 +498,7 @@ dictresize(dictobject *mp, int minused)
492498 /* Make the dict empty, using the new table. */
493499 assert (newtable != oldtable );
494500 mp -> ma_table = newtable ;
495- mp -> ma_size = newsize ;
501+ mp -> ma_mask = newsize - 1 ;
496502 memset (newtable , 0 , sizeof (dictentry ) * newsize );
497503 mp -> ma_used = 0 ;
498504 i = mp -> ma_fill ;
@@ -580,7 +586,7 @@ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
580586 if (hash == -1 )
581587 return -1 ;
582588 }
583- assert (mp -> ma_fill < mp -> ma_size );
589+ assert (mp -> ma_fill <= mp -> ma_mask ); /* at least one empty slot */
584590 n_used = mp -> ma_used ;
585591 Py_INCREF (value );
586592 Py_INCREF (key );
@@ -591,7 +597,7 @@ PyDict_SetItem(register PyObject *op, PyObject *key, PyObject *value)
591597 * much larger than ma_used, meaning a lot of dict keys have been
592598 * deleted).
593599 */
594- if (mp -> ma_used > n_used && mp -> ma_fill * 3 >= mp -> ma_size * 2 ) {
600+ if (mp -> ma_used > n_used && mp -> ma_fill * 3 >= ( mp -> ma_mask + 1 ) * 2 ) {
595601 if (dictresize (mp , mp -> ma_used * 2 ) != 0 )
596602 return -1 ;
597603 }
@@ -652,7 +658,7 @@ PyDict_Clear(PyObject *op)
652658 return ;
653659 mp = (dictobject * )op ;
654660#ifdef Py_DEBUG
655- n = mp -> ma_size ;
661+ n = mp -> ma_mask + 1 ;
656662 i = 0 ;
657663#endif
658664
@@ -721,10 +727,10 @@ PyDict_Next(PyObject *op, int *ppos, PyObject **pkey, PyObject **pvalue)
721727 i = * ppos ;
722728 if (i < 0 )
723729 return 0 ;
724- while (i < mp -> ma_size && mp -> ma_table [i ].me_value == NULL )
730+ while (i <= mp -> ma_mask && mp -> ma_table [i ].me_value == NULL )
725731 i ++ ;
726732 * ppos = i + 1 ;
727- if (i >= mp -> ma_size )
733+ if (i > mp -> ma_mask )
728734 return 0 ;
729735 if (pkey )
730736 * pkey = mp -> ma_table [i ].me_key ;
@@ -772,7 +778,7 @@ dict_print(register dictobject *mp, register FILE *fp, register int flags)
772778
773779 fprintf (fp , "{" );
774780 any = 0 ;
775- for (i = 0 ; i < mp -> ma_size ; i ++ ) {
781+ for (i = 0 ; i <= mp -> ma_mask ; i ++ ) {
776782 dictentry * ep = mp -> ma_table + i ;
777783 PyObject * pvalue = ep -> me_value ;
778784 if (pvalue != NULL ) {
@@ -819,7 +825,7 @@ dict_repr(dictobject *mp)
819825 sepa = PyString_FromString (", " );
820826 colon = PyString_FromString (": " );
821827 any = 0 ;
822- for (i = 0 ; i < mp -> ma_size && v ; i ++ ) {
828+ for (i = 0 ; i <= mp -> ma_mask && v ; i ++ ) {
823829 dictentry * ep = mp -> ma_table + i ;
824830 PyObject * pvalue = ep -> me_value ;
825831 if (pvalue != NULL ) {
@@ -905,7 +911,7 @@ dict_keys(register dictobject *mp, PyObject *args)
905911 Py_DECREF (v );
906912 goto again ;
907913 }
908- for (i = 0 , j = 0 ; i < mp -> ma_size ; i ++ ) {
914+ for (i = 0 , j = 0 ; i <= mp -> ma_mask ; i ++ ) {
909915 if (mp -> ma_table [i ].me_value != NULL ) {
910916 PyObject * key = mp -> ma_table [i ].me_key ;
911917 Py_INCREF (key );
@@ -936,7 +942,7 @@ dict_values(register dictobject *mp, PyObject *args)
936942 Py_DECREF (v );
937943 goto again ;
938944 }
939- for (i = 0 , j = 0 ; i < mp -> ma_size ; i ++ ) {
945+ for (i = 0 , j = 0 ; i <= mp -> ma_mask ; i ++ ) {
940946 if (mp -> ma_table [i ].me_value != NULL ) {
941947 PyObject * value = mp -> ma_table [i ].me_value ;
942948 Py_INCREF (value );
@@ -981,7 +987,7 @@ dict_items(register dictobject *mp, PyObject *args)
981987 goto again ;
982988 }
983989 /* Nothing we do below makes any function calls. */
984- for (i = 0 , j = 0 ; i < mp -> ma_size ; i ++ ) {
990+ for (i = 0 , j = 0 ; i <= mp -> ma_mask ; i ++ ) {
985991 if (mp -> ma_table [i ].me_value != NULL ) {
986992 key = mp -> ma_table [i ].me_key ;
987993 value = mp -> ma_table [i ].me_value ;
@@ -1010,11 +1016,11 @@ dict_update(register dictobject *mp, PyObject *args)
10101016 /* Do one big resize at the start, rather than incrementally
10111017 resizing as we insert new items. Expect that there will be
10121018 no (or few) overlapping keys. */
1013- if ((mp -> ma_fill + other -> ma_used )* 3 >= mp -> ma_size * 2 ) {
1019+ if ((mp -> ma_fill + other -> ma_used )* 3 >= ( mp -> ma_mask + 1 ) * 2 ) {
10141020 if (dictresize (mp , (mp -> ma_used + other -> ma_used )* 3 /2 ) != 0 )
10151021 return NULL ;
10161022 }
1017- for (i = 0 ; i < other -> ma_size ; i ++ ) {
1023+ for (i = 0 ; i <= other -> ma_mask ; i ++ ) {
10181024 entry = & other -> ma_table [i ];
10191025 if (entry -> me_value != NULL ) {
10201026 Py_INCREF (entry -> me_key );
@@ -1055,7 +1061,7 @@ PyDict_Copy(PyObject *o)
10551061 if (mp -> ma_used > 0 ) {
10561062 if (dictresize (copy , mp -> ma_used * 3 /2 ) != 0 )
10571063 return NULL ;
1058- for (i = 0 ; i < mp -> ma_size ; i ++ ) {
1064+ for (i = 0 ; i <= mp -> ma_mask ; i ++ ) {
10591065 entry = & mp -> ma_table [i ];
10601066 if (entry -> me_value != NULL ) {
10611067 Py_INCREF (entry -> me_key );
@@ -1123,7 +1129,7 @@ characterize(dictobject *a, dictobject *b, PyObject **pval)
11231129 PyObject * aval = NULL ; /* a[akey] */
11241130 int i , cmp ;
11251131
1126- for (i = 0 ; i < a -> ma_size ; i ++ ) {
1132+ for (i = 0 ; i <= a -> ma_mask ; i ++ ) {
11271133 PyObject * thiskey , * thisaval , * thisbval ;
11281134 if (a -> ma_table [i ].me_value == NULL )
11291135 continue ;
@@ -1136,7 +1142,7 @@ characterize(dictobject *a, dictobject *b, PyObject **pval)
11361142 goto Fail ;
11371143 }
11381144 if (cmp > 0 ||
1139- i >= a -> ma_size ||
1145+ i > a -> ma_mask ||
11401146 a -> ma_table [i ].me_value == NULL )
11411147 {
11421148 /* Not the *smallest* a key; or maybe it is
@@ -1251,7 +1257,7 @@ dict_equal(dictobject *a, dictobject *b)
12511257 return 0 ;
12521258
12531259 /* Same # of entries -- check all of 'em. Exit early on any diff. */
1254- for (i = 0 ; i < a -> ma_size ; i ++ ) {
1260+ for (i = 0 ; i <= a -> ma_mask ; i ++ ) {
12551261 PyObject * aval = a -> ma_table [i ].me_value ;
12561262 if (aval != NULL ) {
12571263 int cmp ;
@@ -1427,11 +1433,11 @@ dict_popitem(dictobject *mp, PyObject *args)
14271433 * finger that's out of bounds now because it wrapped around
14281434 * or the table shrunk -- simply make sure it's in bounds now.
14291435 */
1430- if (i >= mp -> ma_size || i < 1 )
1436+ if (i > mp -> ma_mask || i < 1 )
14311437 i = 1 ; /* skip slot 0 */
14321438 while ((ep = & mp -> ma_table [i ])-> me_value == NULL ) {
14331439 i ++ ;
1434- if (i >= mp -> ma_size )
1440+ if (i > mp -> ma_mask )
14351441 i = 1 ;
14361442 }
14371443 }
0 commit comments