74ff854
From e15d51510048927f172f1bf1f27ede65907d940d Mon Sep 17 00:00:00 2001
74ff854
From: Leon Bottou <leon@bottou.org>
74ff854
Date: Mon, 8 Apr 2019 22:25:55 -0400
74ff854
Subject: bug 299 fixed
74ff854
74ff854
74ff854
diff --git a/libdjvu/GContainer.h b/libdjvu/GContainer.h
74ff854
index 96b067c..0140211 100644
74ff854
--- a/libdjvu/GContainer.h
74ff854
+++ b/libdjvu/GContainer.h
74ff854
@@ -550,52 +550,61 @@ public:
74ff854
 template <class TYPE> void
74ff854
 GArrayTemplate<TYPE>::sort(int lo, int hi)
74ff854
 {
74ff854
-  if (hi <= lo)
74ff854
-    return;
74ff854
-  if (hi > hibound || lo
74ff854
-    G_THROW( ERR_MSG("GContainer.illegal_subscript") );
74ff854
   TYPE *data = (TYPE*)(*this);
74ff854
-  // Test for insertion sort
74ff854
-  if (hi <= lo + 50)
74ff854
+  while(true)
74ff854
     {
74ff854
-      for (int i=lo+1; i<=hi; i++)
74ff854
+      if (hi <= lo)
74ff854
+        return;
74ff854
+      if (hi > hibound || lo
74ff854
+        G_THROW( ERR_MSG("GContainer.illegal_subscript") );
74ff854
+      // Test for insertion sort
74ff854
+      if (hi <= lo + 50)
74ff854
         {
74ff854
-          int j = i;
74ff854
-          TYPE tmp = data[i];
74ff854
-          while ((--j>=lo) && !(data[j]<=tmp))
74ff854
-            data[j+1] = data[j];
74ff854
-          data[j+1] = tmp;
74ff854
+          for (int i=lo+1; i<=hi; i++)
74ff854
+            {
74ff854
+              int j = i;
74ff854
+              TYPE tmp = data[i];
74ff854
+              while ((--j>=lo) && !(data[j]<=tmp))
74ff854
+                data[j+1] = data[j];
74ff854
+              data[j+1] = tmp;
74ff854
+            }
74ff854
+          return;
74ff854
         }
74ff854
-      return;
74ff854
-    }
74ff854
-  // -- determine suitable quick-sort pivot
74ff854
-  TYPE tmp = data[lo];
74ff854
-  TYPE pivot = data[(lo+hi)/2];
74ff854
-  if (pivot <= tmp)
74ff854
-    { tmp = pivot; pivot=data[lo]; }
74ff854
-  if (data[hi] <= tmp)
74ff854
-    { pivot = tmp; }
74ff854
-  else if (data[hi] <= pivot)
74ff854
-    { pivot = data[hi]; }
74ff854
-  // -- partition set
74ff854
-  int h = hi;
74ff854
-  int l = lo;
74ff854
-  while (l < h)
74ff854
-    {
74ff854
-      while (! (pivot <= data[l])) l++;
74ff854
-      while (! (data[h] <= pivot)) h--;
74ff854
-      if (l < h)
74ff854
+      // -- determine median-of-three pivot
74ff854
+      TYPE tmp = data[lo];
74ff854
+      TYPE pivot = data[(lo+hi)/2];
74ff854
+      if (pivot <= tmp)
74ff854
+        { tmp = pivot; pivot=data[lo]; }
74ff854
+      if (data[hi] <= tmp)
74ff854
+        { pivot = tmp; }
74ff854
+      else if (data[hi] <= pivot)
74ff854
+        { pivot = data[hi]; }
74ff854
+      // -- partition set
74ff854
+      int h = hi;
74ff854
+      int l = lo;
74ff854
+      while (l < h)
74ff854
         {
74ff854
-          tmp = data[l];
74ff854
-          data[l] = data[h];
74ff854
-          data[h] = tmp;
74ff854
-          l = l+1;
74ff854
-          h = h-1;
74ff854
+          while (! (pivot <= data[l])) l++;
74ff854
+          while (! (data[h] <= pivot)) h--;
74ff854
+          if (l < h)
74ff854
+            {
74ff854
+              tmp = data[l];
74ff854
+              data[l] = data[h];
74ff854
+              data[h] = tmp;
74ff854
+              l = l+1;
74ff854
+              h = h-1;
74ff854
+            }
74ff854
+        }
74ff854
+      // -- recurse, small partition first
74ff854
+      //    tail-recursion elimination
74ff854
+      if (h - lo <= hi - l) {
74ff854
+        sort(lo,h);
74ff854
+        lo = l; // sort(l,hi)
74ff854
+      } else {
74ff854
+        sort(l,hi);
74ff854
+        hi = h; // sort(lo,h)
74ff854
       }
74ff854
     }
74ff854
-  // -- recursively restart
74ff854
-  sort(lo, h);
74ff854
-  sort(l, hi);
74ff854
 }
74ff854
 
74ff854
 template<class TYPE> inline TYPE&