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