@@ -11,7 +11,7 @@ annotated by François Pinard, and converted to C by Raymond Hettinger.
1111static int
1212_siftdown (PyListObject * heap , Py_ssize_t startpos , Py_ssize_t pos )
1313{
14- PyObject * newitem , * parent , * olditem ;
14+ PyObject * newitem , * parent ;
1515 int cmp ;
1616 Py_ssize_t parentpos ;
1717 Py_ssize_t size ;
@@ -23,60 +23,45 @@ _siftdown(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
2323 return -1 ;
2424 }
2525
26- newitem = PyList_GET_ITEM (heap , pos );
27- Py_INCREF (newitem );
2826 /* Follow the path to the root, moving parents down until finding
2927 a place newitem fits. */
28+ newitem = PyList_GET_ITEM (heap , pos );
3029 while (pos > startpos ){
3130 parentpos = (pos - 1 ) >> 1 ;
3231 parent = PyList_GET_ITEM (heap , parentpos );
3332 cmp = PyObject_RichCompareBool (newitem , parent , Py_LT );
34- if (cmp == -1 ) {
35- Py_DECREF (newitem );
33+ if (cmp == -1 )
3634 return -1 ;
37- }
3835 if (size != PyList_GET_SIZE (heap )) {
39- Py_DECREF (newitem );
4036 PyErr_SetString (PyExc_RuntimeError ,
4137 "list changed size during iteration" );
4238 return -1 ;
4339 }
4440 if (cmp == 0 )
4541 break ;
46- Py_INCREF (parent );
47- olditem = PyList_GET_ITEM (heap , pos );
42+ parent = PyList_GET_ITEM (heap , parentpos );
43+ newitem = PyList_GET_ITEM (heap , pos );
44+ PyList_SET_ITEM (heap , parentpos , newitem );
4845 PyList_SET_ITEM (heap , pos , parent );
49- Py_DECREF (olditem );
5046 pos = parentpos ;
51- if (size != PyList_GET_SIZE (heap )) {
52- PyErr_SetString (PyExc_RuntimeError ,
53- "list changed size during iteration" );
54- return -1 ;
55- }
5647 }
57- Py_DECREF (PyList_GET_ITEM (heap , pos ));
58- PyList_SET_ITEM (heap , pos , newitem );
5948 return 0 ;
6049}
6150
6251static int
6352_siftup (PyListObject * heap , Py_ssize_t pos )
6453{
6554 Py_ssize_t startpos , endpos , childpos , rightpos , limit ;
55+ PyObject * tmp1 , * tmp2 ;
6656 int cmp ;
67- PyObject * newitem , * tmp , * olditem ;
68- Py_ssize_t size ;
6957
7058 assert (PyList_Check (heap ));
71- size = PyList_GET_SIZE (heap );
72- endpos = size ;
59+ endpos = PyList_GET_SIZE (heap );
7360 startpos = pos ;
7461 if (pos >= endpos ) {
7562 PyErr_SetString (PyExc_IndexError , "index out of range" );
7663 return -1 ;
7764 }
78- newitem = PyList_GET_ITEM (heap , pos );
79- Py_INCREF (newitem );
8065
8166 /* Bubble up the smaller child until hitting a leaf. */
8267 limit = endpos / 2 ; /* smallest pos that has no child */
@@ -89,37 +74,24 @@ _siftup(PyListObject *heap, Py_ssize_t pos)
8974 PyList_GET_ITEM (heap , childpos ),
9075 PyList_GET_ITEM (heap , rightpos ),
9176 Py_LT );
92- if (cmp == -1 ) {
93- Py_DECREF (newitem );
77+ if (cmp == -1 )
9478 return -1 ;
95- }
9679 if (cmp == 0 )
9780 childpos = rightpos ;
98- }
99- if (size != PyList_GET_SIZE (heap )) {
100- Py_DECREF (newitem );
101- PyErr_SetString (PyExc_RuntimeError ,
102- "list changed size during iteration" );
103- return -1 ;
81+ if (endpos != PyList_GET_SIZE (heap )) {
82+ PyErr_SetString (PyExc_RuntimeError ,
83+ "list changed size during iteration" );
84+ return -1 ;
85+ }
10486 }
10587 /* Move the smaller child up. */
106- tmp = PyList_GET_ITEM (heap , childpos );
107- Py_INCREF (tmp );
108- olditem = PyList_GET_ITEM (heap , pos );
109- PyList_SET_ITEM (heap , pos , tmp );
110- Py_DECREF (olditem );
88+ tmp1 = PyList_GET_ITEM (heap , childpos );
89+ tmp2 = PyList_GET_ITEM (heap , pos );
90+ PyList_SET_ITEM (heap , childpos , tmp2 );
91+ PyList_SET_ITEM (heap , pos , tmp1 );
11192 pos = childpos ;
112- if (size != PyList_GET_SIZE (heap )) {
113- PyErr_SetString (PyExc_RuntimeError ,
114- "list changed size during iteration" );
115- return -1 ;
116- }
11793 }
118-
119- /* The leaf at pos is empty now. Put newitem there, and bubble
120- it up to its final resting place (by sifting its parents down). */
121- Py_DECREF (PyList_GET_ITEM (heap , pos ));
122- PyList_SET_ITEM (heap , pos , newitem );
94+ /* Bubble it up to its final resting place (by sifting its parents down). */
12395 return _siftdown (heap , startpos , pos );
12496}
12597
@@ -392,36 +364,32 @@ _siftdownmax(PyListObject *heap, Py_ssize_t startpos, Py_ssize_t pos)
392364 return -1 ;
393365 }
394366
395- newitem = PyList_GET_ITEM (heap , pos );
396- Py_INCREF (newitem );
397367 /* Follow the path to the root, moving parents down until finding
398368 a place newitem fits. */
369+ newitem = PyList_GET_ITEM (heap , pos );
399370 while (pos > startpos ){
400371 parentpos = (pos - 1 ) >> 1 ;
401372 parent = PyList_GET_ITEM (heap , parentpos );
402373 cmp = PyObject_RichCompareBool (parent , newitem , Py_LT );
403- if (cmp == -1 ) {
404- Py_DECREF (newitem );
374+ if (cmp == -1 )
405375 return -1 ;
406- }
407376 if (cmp == 0 )
408377 break ;
409- Py_INCREF (parent );
410- Py_DECREF (PyList_GET_ITEM (heap , pos ));
378+ parent = PyList_GET_ITEM (heap , parentpos );
379+ newitem = PyList_GET_ITEM (heap , pos );
380+ PyList_SET_ITEM (heap , parentpos , newitem );
411381 PyList_SET_ITEM (heap , pos , parent );
412382 pos = parentpos ;
413383 }
414- Py_DECREF (PyList_GET_ITEM (heap , pos ));
415- PyList_SET_ITEM (heap , pos , newitem );
416384 return 0 ;
417385}
418386
419387static int
420388_siftupmax (PyListObject * heap , Py_ssize_t pos )
421389{
422390 Py_ssize_t startpos , endpos , childpos , rightpos , limit ;
391+ PyObject * tmp1 , * tmp2 ;
423392 int cmp ;
424- PyObject * newitem , * tmp ;
425393
426394 assert (PyList_Check (heap ));
427395 endpos = PyList_GET_SIZE (heap );
@@ -430,8 +398,6 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos)
430398 PyErr_SetString (PyExc_IndexError , "index out of range" );
431399 return -1 ;
432400 }
433- newitem = PyList_GET_ITEM (heap , pos );
434- Py_INCREF (newitem );
435401
436402 /* Bubble up the smaller child until hitting a leaf. */
437403 limit = endpos / 2 ; /* smallest pos that has no child */
@@ -444,25 +410,24 @@ _siftupmax(PyListObject *heap, Py_ssize_t pos)
444410 PyList_GET_ITEM (heap , rightpos ),
445411 PyList_GET_ITEM (heap , childpos ),
446412 Py_LT );
447- if (cmp == -1 ) {
448- Py_DECREF (newitem );
413+ if (cmp == -1 )
449414 return -1 ;
450- }
451415 if (cmp == 0 )
452416 childpos = rightpos ;
417+ if (endpos != PyList_GET_SIZE (heap )) {
418+ PyErr_SetString (PyExc_RuntimeError ,
419+ "list changed size during iteration" );
420+ return -1 ;
421+ }
453422 }
454423 /* Move the smaller child up. */
455- tmp = PyList_GET_ITEM (heap , childpos );
456- Py_INCREF ( tmp );
457- Py_DECREF ( PyList_GET_ITEM ( heap , pos ) );
458- PyList_SET_ITEM (heap , pos , tmp );
424+ tmp1 = PyList_GET_ITEM (heap , childpos );
425+ tmp2 = PyList_GET_ITEM ( heap , pos );
426+ PyList_SET_ITEM ( heap , childpos , tmp2 );
427+ PyList_SET_ITEM (heap , pos , tmp1 );
459428 pos = childpos ;
460429 }
461-
462- /* The leaf at pos is empty now. Put newitem there, and bubble
463- it up to its final resting place (by sifting its parents down). */
464- Py_DECREF (PyList_GET_ITEM (heap , pos ));
465- PyList_SET_ITEM (heap , pos , newitem );
430+ /* Bubble it up to its final resting place (by sifting its parents down). */
466431 return _siftdownmax (heap , startpos , pos );
467432}
468433
0 commit comments