@@ -659,8 +659,6 @@ quicksort(list, compare)
659659 PyListObject * list ; /* List to sort */
660660 PyObject * compare ;/* Comparison function object, or NULL for default */
661661{
662- int size = list -> ob_size ; /* Number of elements to sort */
663- PyObject * * array = list -> ob_item ; /* Start of array to sort */
664662 register PyObject * tmp , * pivot ;
665663 register PyObject * * l , * * r , * * p ;
666664 PyObject * * lo , * * hi , * * notp ;
@@ -669,10 +667,12 @@ quicksort(list, compare)
669667 PyObject * * histack [STACKSIZE ];
670668
671669 /* Start out with the whole array on the work stack */
672- lostack [0 ] = array ;
673- histack [0 ] = array + size ;
670+ lostack [0 ] = list -> ob_item ;
671+ histack [0 ] = list -> ob_item + list -> ob_size ;
674672 top = 1 ;
675673
674+ #define SETK (X ,Y ) if ((k = docompare(X,Y,compare,list))==CMPERROR) goto fail
675+
676676 /* Repeat until the work stack is empty */
677677 while (-- top >= 0 ) {
678678 lo = lostack [top ];
@@ -688,10 +688,7 @@ quicksort(list, compare)
688688 pivot = * r ;
689689 do {
690690 p = l + ((r - l ) >> 1 );
691- k = docompare (pivot , * p ,
692- compare , list );
693- if (k == CMPERROR )
694- return -1 ;
691+ SETK (pivot , * p );
695692 if (k < 0 )
696693 r = p ;
697694 else
@@ -708,28 +705,30 @@ quicksort(list, compare)
708705 continue ;
709706 }
710707
711- /* Choose median of first, middle and last as pivot */
708+ /* Choose median of first, middle and last as pivot;
709+ this is a simple unrolled 3-element insertion sort */
712710 l = lo ; /* First */
713711 p = lo + (n >>1 ); /* Middle */
714712 r = hi - 1 ; /* Last */
715713
716- k = docompare (* p , * l , compare , list );
717- if (k == CMPERROR )
718- return -1 ;
719- if (k < 0 )
720- { tmp = * p ; * p = * l ; * l = tmp ; }
721-
722- k = docompare (* r , * p , compare , list );
723- if (k == CMPERROR )
724- return -1 ;
725- if (k < 0 )
726- { tmp = * r ; * r = * p ; * p = tmp ; }
714+ pivot = * p ;
715+ SETK (pivot , * l );
716+ if (k < 0 ) {
717+ * p = * l ;
718+ * l = pivot ;
719+ }
727720
728- k = docompare (* p , * l , compare , list );
729- if (k == CMPERROR )
730- return -1 ;
731- if (k < 0 )
732- { tmp = * p ; * p = * l ; * l = tmp ; }
721+ pivot = * r ;
722+ SETK (pivot , * p );
723+ if (k < 0 ) {
724+ * r = * p ;
725+ * p = pivot ; /* for consistency */
726+ SETK (pivot , * l );
727+ if (k < 0 ) {
728+ * p = * l ;
729+ * l = pivot ;
730+ }
731+ }
733732
734733 pivot = * p ;
735734 l ++ ;
@@ -741,9 +740,7 @@ quicksort(list, compare)
741740
742741 /* Move left index to element >= pivot */
743742 while (l < p ) {
744- k = docompare (* l , pivot , compare , list );
745- if (k == CMPERROR )
746- return -1 ;
743+ SETK (* l , pivot );
747744 if (k < 0 )
748745 l ++ ;
749746 else {
@@ -753,9 +750,7 @@ quicksort(list, compare)
753750 }
754751 /* Move right index to element <= pivot */
755752 while (r > p ) {
756- k = docompare (pivot , * r , compare , list );
757- if (k == CMPERROR )
758- return -1 ;
753+ SETK (pivot , * r );
759754 if (k < 0 )
760755 r -- ;
761756 else {
@@ -780,9 +775,9 @@ quicksort(list, compare)
780775 /* One (exactly) of the pointers is at p */
781776 /* assert (p == l) ^ (p == r) */
782777 notp = lisp ? r : l ;
778+ * p = * notp ;
783779 k = (r - l ) >> 1 ;
784780 if (k ) {
785- * p = * notp ;
786781 if (lisp ) {
787782 p = r - k ;
788783 l ++ ;
@@ -791,14 +786,12 @@ quicksort(list, compare)
791786 p = l + k ;
792787 r -- ;
793788 }
794- /* assert l < p < r */
795789 * notp = * p ;
796790 * p = pivot ; /* for consistency */
797791 continue ;
798792 }
799793
800794 /* assert l+1 == r */
801- * p = * notp ;
802795 * notp = pivot ;
803796 p = notp ;
804797 break ;
@@ -818,9 +811,7 @@ quicksort(list, compare)
818811 * This wastes a compare if it fails, but can win big
819812 * when there are runs of duplicates.
820813 */
821- k = docompare (pivot , * l , compare , list );
822- if (k == CMPERROR )
823- return -1 ;
814+ SETK (pivot , * l );
824815 if (!(k < 0 )) {
825816 /* Now extend as far as possible (around p) so that:
826817 All in [lo,r) are <= pivot
@@ -831,9 +822,7 @@ quicksort(list, compare)
831822 */
832823 while (r > lo ) {
833824 /* because r-1 < p, *(r-1) <= pivot is known */
834- k = docompare (* (r - 1 ), pivot , compare , list );
835- if (k == CMPERROR )
836- return -1 ;
825+ SETK (* (r - 1 ), pivot );
837826 if (k < 0 )
838827 break ;
839828 /* <= and not < implies == */
@@ -843,9 +832,7 @@ quicksort(list, compare)
843832 l ++ ;
844833 while (l < hi ) {
845834 /* because l > p, pivot <= *l is known */
846- k = docompare (pivot , * l , compare , list );
847- if (k == CMPERROR )
848- return -1 ;
835+ SETK (pivot , * l );
849836 if (k < 0 )
850837 break ;
851838 /* <= and not < implies == */
@@ -873,6 +860,11 @@ quicksort(list, compare)
873860
874861 /* Success */
875862 return 0 ;
863+
864+ fail :
865+ return -1 ;
866+
867+ #undef SETK
876868}
877869
878870static PyObject *
0 commit comments