Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1243)

Unified Diff: courgette/third_party/qsufsort.h

Issue 1914303002: [Courgette] Fix sorting in QSufSort's split(). (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Comment nit. Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: courgette/third_party/qsufsort.h
diff --git a/courgette/third_party/qsufsort.h b/courgette/third_party/qsufsort.h
index 399768c474ecf1e76e53a5d46861460fb24d192c..7bb46dfc7365caa156bdbea0551d4de3790bea54 100644
--- a/courgette/third_party/qsufsort.h
+++ b/courgette/third_party/qsufsort.h
@@ -13,10 +13,14 @@
2010-05-26 - Use a paged array for V and I. The address space may be too
fragmented for these big arrays to be contiguous.
--Stephen Adams <sra@chromium.org>
- 2015-08-03 - Extrat qsufsort to a separate file as template.
+ 2015-08-03 - Extract QSufSort to a separate file as template.
--Samuel Huang <huangs@chromium.org>
2015-08-19 - Optimize split() and search(), add comments.
--Samuel Huang <huangs@chromium.org>
+ 2016-04-27 - Change split() to use Bentley & McIlroy's pivot selection
+ algorithm, which QSufSort originally used. Reference:
+ http://www.larsson.dogma.net/qsufsort.c
+ --Samuel Huang <huangs@chromium.org>
*/
#include <algorithm>
@@ -39,9 +43,19 @@ namespace qsuf {
// presented in "Faster Suffix Sorting" by N. Jesper Larsson and Kunihiko
// Sadakane, special cased for bytes.
-template <typename T> static void split(T I, T V, int start, int end, int h) {
+namespace {
+
+template <typename T> T median3(const T& a, const T& b, const T& c) {
+ if (a < b)
+ return b < c ? b : (a < c ? c : a);
+ return b > c ? b : (a > c ? c : a);
+}
+
+} // namespace
+
+template <typename T> void split(T I, T V, int start, int end, int h) {
// For small interval, apply selection sort.
- if (end - start < 6) {
+ if (end - start < 16) {
for (int i = start; i < end; ) {
int skip = 1;
int best = V[I[i] + h];
@@ -72,11 +86,24 @@ template <typename T> static void split(T I, T V, int start, int end, int h) {
return;
}
+ // Select pivot, algorithm by Bentley & McIlroy.
+ int n = end - start;
+ int mid = start + (n >> 1);
+ int pivot = V[I[mid] + h];
+ int p1 = V[I[start] + h];
+ int p2 = V[I[end - 1] + h];
+ if (n > 40) { // Big array: Pseudomedian of 9.
+ int s = n >> 3;
+ pivot = median3(pivot, V[I[mid - s] + h], V[I[mid + s] + h]);
+ p1 = median3(p1, V[I[start + s] + h], V[I[start + s + s] + h]);
+ p2 = median3(p2, V[I[end - 1 - s] + h], V[I[end - 1 - s - s] + h]);
+ } // Else medium array: Pseudomedian of 3.
+ pivot = median3(pivot, p1, p2);
+
// Split [start, end) into 3 intervals:
// [start, j) with secondary keys < pivot,
// [j, k) with secondary keys == pivot,
// [k, end) with secondary keys > pivot.
- int pivot = V[I[(start + end) / 2] + h];
int j = start;
int k = end;
for (int i = start; i < k; ) {
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698