@@ -11,7 +11,7 @@ annotated by François Pinard, and converted to C by Raymond Hettinger.
1111static int
1212siftdown (PyListObject * heap , Py_ssize_t startpos , Py_ssize_t pos )
1313{
14- PyObject * newitem , * parent ;
14+ PyObject * newitem , * parent , * * arr ;
1515 Py_ssize_t parentpos , size ;
1616 int cmp ;
1717
@@ -24,12 +24,13 @@ siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
2424
2525 /* Follow the path to the root, moving parents down until finding
2626 a place newitem fits. */
27- newitem = PyList_GET_ITEM (heap , pos );
27+ arr = _PyList_ITEMS (heap );
28+ newitem = arr [pos ];
2829 while (pos > startpos ) {
2930 parentpos = (pos - 1 ) >> 1 ;
30- parent = PyList_GET_ITEM ( heap , parentpos ) ;
31+ parent = arr [ parentpos ] ;
3132 cmp = PyObject_RichCompareBool (newitem , parent , Py_LT );
32- if (cmp == -1 )
33+ if (cmp < 0 )
3334 return -1 ;
3435 if (size != PyList_GET_SIZE (heap )) {
3536 PyErr_SetString (PyExc_RuntimeError ,
@@ -38,10 +39,11 @@ siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
3839 }
3940 if (cmp == 0 )
4041 break ;
41- parent = PyList_GET_ITEM (heap , parentpos );
42- newitem = PyList_GET_ITEM (heap , pos );
43- PyList_SET_ITEM (heap , parentpos , newitem );
44- PyList_SET_ITEM (heap , pos , parent );
42+ arr = _PyList_ITEMS (heap );
43+ parent = arr [parentpos ];
44+ newitem = arr [pos ];
45+ arr [parentpos ] = newitem ;
46+ arr [pos ] = parent ;
4547 pos = parentpos ;
4648 }
4749 return 0 ;
@@ -51,7 +53,7 @@ static int
5153siftup (PyListObject * heap , Py_ssize_t pos )
5254{
5355 Py_ssize_t startpos , endpos , childpos , limit ;
54- PyObject * tmp1 , * tmp2 ;
56+ PyObject * tmp1 , * tmp2 , * * arr ;
5557 int cmp ;
5658
5759 assert (PyList_Check (heap ));
@@ -63,30 +65,31 @@ siftup(PyListObject *heap, Py_ssize_t pos)
6365 }
6466
6567 /* Bubble up the smaller child until hitting a leaf. */
68+ arr = _PyList_ITEMS (heap );
6669 limit = endpos / 2 ; /* smallest pos that has no child */
6770 while (pos < limit ) {
6871 /* Set childpos to index of smaller child. */
6972 childpos = 2 * pos + 1 ; /* leftmost child position */
7073 if (childpos + 1 < endpos ) {
7174 cmp = PyObject_RichCompareBool (
72- PyList_GET_ITEM ( heap , childpos ) ,
73- PyList_GET_ITEM ( heap , childpos + 1 ) ,
75+ arr [ childpos ] ,
76+ arr [ childpos + 1 ] ,
7477 Py_LT );
75- if (cmp == -1 )
78+ if (cmp < 0 )
7679 return -1 ;
77- if (cmp == 0 )
78- childpos ++ ; /* rightmost child is smallest */
80+ childpos += ((unsigned )cmp ^ 1 ); /* increment when cmp==0 */
7981 if (endpos != PyList_GET_SIZE (heap )) {
8082 PyErr_SetString (PyExc_RuntimeError ,
8183 "list changed size during iteration" );
8284 return -1 ;
8385 }
8486 }
8587 /* Move the smaller child up. */
86- tmp1 = PyList_GET_ITEM (heap , childpos );
87- tmp2 = PyList_GET_ITEM (heap , pos );
88- PyList_SET_ITEM (heap , childpos , tmp2 );
89- PyList_SET_ITEM (heap , pos , tmp1 );
88+ arr = _PyList_ITEMS (heap );
89+ tmp1 = arr [childpos ];
90+ tmp2 = arr [pos ];
91+ arr [childpos ] = tmp2 ;
92+ arr [pos ] = tmp1 ;
9093 pos = childpos ;
9194 }
9295 /* Bubble it up to its final resting place (by sifting its parents down). */
@@ -227,7 +230,7 @@ heappushpop(PyObject *self, PyObject *args)
227230 }
228231
229232 cmp = PyObject_RichCompareBool (PyList_GET_ITEM (heap , 0 ), item , Py_LT );
230- if (cmp == -1 )
233+ if (cmp < 0 )
231234 return NULL ;
232235 if (cmp == 0 ) {
233236 Py_INCREF (item );
@@ -362,7 +365,7 @@ PyDoc_STRVAR(heapify_doc,
362365static int
363366siftdown_max (PyListObject * heap , Py_ssize_t startpos , Py_ssize_t pos )
364367{
365- PyObject * newitem , * parent ;
368+ PyObject * newitem , * parent , * * arr ;
366369 Py_ssize_t parentpos , size ;
367370 int cmp ;
368371
@@ -375,12 +378,13 @@ siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
375378
376379 /* Follow the path to the root, moving parents down until finding
377380 a place newitem fits. */
378- newitem = PyList_GET_ITEM (heap , pos );
381+ arr = _PyList_ITEMS (heap );
382+ newitem = arr [pos ];
379383 while (pos > startpos ) {
380384 parentpos = (pos - 1 ) >> 1 ;
381- parent = PyList_GET_ITEM ( heap , parentpos ) ;
385+ parent = arr [ parentpos ] ;
382386 cmp = PyObject_RichCompareBool (parent , newitem , Py_LT );
383- if (cmp == -1 )
387+ if (cmp < 0 )
384388 return -1 ;
385389 if (size != PyList_GET_SIZE (heap )) {
386390 PyErr_SetString (PyExc_RuntimeError ,
@@ -389,10 +393,11 @@ siftdown_max(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
389393 }
390394 if (cmp == 0 )
391395 break ;
392- parent = PyList_GET_ITEM (heap , parentpos );
393- newitem = PyList_GET_ITEM (heap , pos );
394- PyList_SET_ITEM (heap , parentpos , newitem );
395- PyList_SET_ITEM (heap , pos , parent );
396+ arr = _PyList_ITEMS (heap );
397+ parent = arr [parentpos ];
398+ newitem = arr [pos ];
399+ arr [parentpos ] = newitem ;
400+ arr [pos ] = parent ;
396401 pos = parentpos ;
397402 }
398403 return 0 ;
@@ -402,7 +407,7 @@ static int
402407siftup_max (PyListObject * heap , Py_ssize_t pos )
403408{
404409 Py_ssize_t startpos , endpos , childpos , limit ;
405- PyObject * tmp1 , * tmp2 ;
410+ PyObject * tmp1 , * tmp2 , * * arr ;
406411 int cmp ;
407412
408413 assert (PyList_Check (heap ));
@@ -414,30 +419,31 @@ siftup_max(PyListObject *heap, Py_ssize_t pos)
414419 }
415420
416421 /* Bubble up the smaller child until hitting a leaf. */
422+ arr = _PyList_ITEMS (heap );
417423 limit = endpos / 2 ; /* smallest pos that has no child */
418424 while (pos < limit ) {
419425 /* Set childpos to index of smaller child. */
420426 childpos = 2 * pos + 1 ; /* leftmost child position */
421427 if (childpos + 1 < endpos ) {
422428 cmp = PyObject_RichCompareBool (
423- PyList_GET_ITEM ( heap , childpos + 1 ) ,
424- PyList_GET_ITEM ( heap , childpos ) ,
429+ arr [ childpos + 1 ] ,
430+ arr [ childpos ] ,
425431 Py_LT );
426- if (cmp == -1 )
432+ if (cmp < 0 )
427433 return -1 ;
428- if (cmp == 0 )
429- childpos ++ ; /* rightmost child is smallest */
434+ childpos += ((unsigned )cmp ^ 1 ); /* increment when cmp==0 */
430435 if (endpos != PyList_GET_SIZE (heap )) {
431436 PyErr_SetString (PyExc_RuntimeError ,
432437 "list changed size during iteration" );
433438 return -1 ;
434439 }
435440 }
436441 /* Move the smaller child up. */
437- tmp1 = PyList_GET_ITEM (heap , childpos );
438- tmp2 = PyList_GET_ITEM (heap , pos );
439- PyList_SET_ITEM (heap , childpos , tmp2 );
440- PyList_SET_ITEM (heap , pos , tmp1 );
442+ arr = _PyList_ITEMS (heap );
443+ tmp1 = arr [childpos ];
444+ tmp2 = arr [pos ];
445+ arr [childpos ] = tmp2 ;
446+ arr [pos ] = tmp1 ;
441447 pos = childpos ;
442448 }
443449 /* Bubble it up to its final resting place (by sifting its parents down). */
0 commit comments