Coverage Report

Created: 2026-06-01 06:57

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/zstd/lib/dictBuilder/divsufsort.c
Line
Count
Source
1
/*
2
 * divsufsort.c for libdivsufsort-lite
3
 * Copyright (c) 2003-2008 Yuta Mori All Rights Reserved.
4
 *
5
 * Permission is hereby granted, free of charge, to any person
6
 * obtaining a copy of this software and associated documentation
7
 * files (the "Software"), to deal in the Software without
8
 * restriction, including without limitation the rights to use,
9
 * copy, modify, merge, publish, distribute, sublicense, and/or sell
10
 * copies of the Software, and to permit persons to whom the
11
 * Software is furnished to do so, subject to the following
12
 * conditions:
13
 *
14
 * The above copyright notice and this permission notice shall be
15
 * included in all copies or substantial portions of the Software.
16
 *
17
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
 * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
 * OTHER DEALINGS IN THE SOFTWARE.
25
 */
26
27
/*- Compiler specifics -*/
28
#if defined(_MSC_VER)
29
#  pragma warning(disable : 4127)    /* C4127 : Condition expression is constant */
30
#endif
31
32
33
/*- Dependencies -*/
34
#include <assert.h>
35
#include <limits.h>
36
#include <stddef.h>
37
#include <stdio.h>
38
#include <stdlib.h>
39
40
#include "divsufsort.h"
41
42
0
#define PTRDIFF_TO_INT(x) (assert((x) <= INT_MAX && (x) >= INT_MIN), (int)(x))
43
44
/*- Constants -*/
45
#if defined(INLINE)
46
# undef INLINE
47
#endif
48
#if !defined(INLINE)
49
# define INLINE __inline
50
#endif
51
#if defined(ALPHABET_SIZE) && (ALPHABET_SIZE < 1)
52
# undef ALPHABET_SIZE
53
#endif
54
#if !defined(ALPHABET_SIZE)
55
0
# define ALPHABET_SIZE (256)
56
#endif
57
0
#define BUCKET_A_SIZE (ALPHABET_SIZE)
58
0
#define BUCKET_B_SIZE (ALPHABET_SIZE * ALPHABET_SIZE)
59
#if defined(SS_INSERTIONSORT_THRESHOLD)
60
# if SS_INSERTIONSORT_THRESHOLD < 1
61
#  undef SS_INSERTIONSORT_THRESHOLD
62
#  define SS_INSERTIONSORT_THRESHOLD (1)
63
# endif
64
#else
65
0
# define SS_INSERTIONSORT_THRESHOLD (8)
66
#endif
67
#if defined(SS_BLOCKSIZE)
68
# if SS_BLOCKSIZE < 0
69
#  undef SS_BLOCKSIZE
70
#  define SS_BLOCKSIZE (0)
71
# elif 32768 <= SS_BLOCKSIZE
72
#  undef SS_BLOCKSIZE
73
#  define SS_BLOCKSIZE (32767)
74
# endif
75
#else
76
0
# define SS_BLOCKSIZE (1024)
77
#endif
78
/* minstacksize = log(SS_BLOCKSIZE) / log(3) * 2 */
79
#if SS_BLOCKSIZE == 0
80
# define SS_MISORT_STACKSIZE (96)
81
#elif SS_BLOCKSIZE <= 4096
82
# define SS_MISORT_STACKSIZE (16)
83
#else
84
# define SS_MISORT_STACKSIZE (24)
85
#endif
86
#define SS_SMERGE_STACKSIZE (32)
87
0
#define TR_INSERTIONSORT_THRESHOLD (8)
88
#define TR_STACKSIZE (64)
89
90
91
/*- Macros -*/
92
#ifndef SWAP
93
0
# define SWAP(_a, _b) do { t = (_a); (_a) = (_b); (_b) = t; } while(0)
94
#endif /* SWAP */
95
#ifndef MIN
96
# define MIN(_a, _b) (((_a) < (_b)) ? (_a) : (_b))
97
#endif /* MIN */
98
#ifndef MAX
99
# define MAX(_a, _b) (((_a) > (_b)) ? (_a) : (_b))
100
#endif /* MAX */
101
#define STACK_PUSH(_a, _b, _c, _d)\
102
0
  do {\
103
0
    assert(ssize < STACK_SIZE);\
104
0
    stack[ssize].a = (_a), stack[ssize].b = (_b),\
105
0
    stack[ssize].c = (_c), stack[ssize++].d = (_d);\
106
0
  } while(0)
107
#define STACK_PUSH5(_a, _b, _c, _d, _e)\
108
0
  do {\
109
0
    assert(ssize < STACK_SIZE);\
110
0
    stack[ssize].a = (_a), stack[ssize].b = (_b),\
111
0
    stack[ssize].c = (_c), stack[ssize].d = (_d), stack[ssize++].e = (_e);\
112
0
  } while(0)
113
#define STACK_POP(_a, _b, _c, _d)\
114
0
  do {\
115
0
    assert(0 <= ssize);\
116
0
    if(ssize == 0) { return; }\
117
0
    (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\
118
0
    (_c) = stack[ssize].c, (_d) = stack[ssize].d;\
119
0
  } while(0)
120
#define STACK_POP5(_a, _b, _c, _d, _e)\
121
0
  do {\
122
0
    assert(0 <= ssize);\
123
0
    if(ssize == 0) { return; }\
124
0
    (_a) = stack[--ssize].a, (_b) = stack[ssize].b,\
125
0
    (_c) = stack[ssize].c, (_d) = stack[ssize].d, (_e) = stack[ssize].e;\
126
0
  } while(0)
127
0
#define BUCKET_A(_c0) bucket_A[(_c0)]
128
#if ALPHABET_SIZE == 256
129
0
#define BUCKET_B(_c0, _c1) (bucket_B[((_c1) << 8) | (_c0)])
130
0
#define BUCKET_BSTAR(_c0, _c1) (bucket_B[((_c0) << 8) | (_c1)])
131
#else
132
#define BUCKET_B(_c0, _c1) (bucket_B[(_c1) * ALPHABET_SIZE + (_c0)])
133
#define BUCKET_BSTAR(_c0, _c1) (bucket_B[(_c0) * ALPHABET_SIZE + (_c1)])
134
#endif
135
136
137
/*- Private Functions -*/
138
139
static const int lg_table[256]= {
140
 -1,0,1,1,2,2,2,2,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,4,
141
  5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
142
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
143
  6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
144
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
145
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
146
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
147
  7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7
148
};
149
150
#if (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE)
151
152
static INLINE
153
int
154
0
ss_ilg(int n) {
155
#if SS_BLOCKSIZE == 0
156
  return (n & 0xffff0000) ?
157
          ((n & 0xff000000) ?
158
            24 + lg_table[(n >> 24) & 0xff] :
159
            16 + lg_table[(n >> 16) & 0xff]) :
160
          ((n & 0x0000ff00) ?
161
             8 + lg_table[(n >>  8) & 0xff] :
162
             0 + lg_table[(n >>  0) & 0xff]);
163
#elif SS_BLOCKSIZE < 256
164
  return lg_table[n];
165
#else
166
0
  return (n & 0xff00) ?
167
0
          8 + lg_table[(n >> 8) & 0xff] :
168
0
          0 + lg_table[(n >> 0) & 0xff];
169
0
#endif
170
0
}
171
172
#endif /* (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) */
173
174
#if SS_BLOCKSIZE != 0
175
176
static const int sqq_table[256] = {
177
  0,  16,  22,  27,  32,  35,  39,  42,  45,  48,  50,  53,  55,  57,  59,  61,
178
 64,  65,  67,  69,  71,  73,  75,  76,  78,  80,  81,  83,  84,  86,  87,  89,
179
 90,  91,  93,  94,  96,  97,  98,  99, 101, 102, 103, 104, 106, 107, 108, 109,
180
110, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126,
181
128, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142,
182
143, 144, 144, 145, 146, 147, 148, 149, 150, 150, 151, 152, 153, 154, 155, 155,
183
156, 157, 158, 159, 160, 160, 161, 162, 163, 163, 164, 165, 166, 167, 167, 168,
184
169, 170, 170, 171, 172, 173, 173, 174, 175, 176, 176, 177, 178, 178, 179, 180,
185
181, 181, 182, 183, 183, 184, 185, 185, 186, 187, 187, 188, 189, 189, 190, 191,
186
192, 192, 193, 193, 194, 195, 195, 196, 197, 197, 198, 199, 199, 200, 201, 201,
187
202, 203, 203, 204, 204, 205, 206, 206, 207, 208, 208, 209, 209, 210, 211, 211,
188
212, 212, 213, 214, 214, 215, 215, 216, 217, 217, 218, 218, 219, 219, 220, 221,
189
221, 222, 222, 223, 224, 224, 225, 225, 226, 226, 227, 227, 228, 229, 229, 230,
190
230, 231, 231, 232, 232, 233, 234, 234, 235, 235, 236, 236, 237, 237, 238, 238,
191
239, 240, 240, 241, 241, 242, 242, 243, 243, 244, 244, 245, 245, 246, 246, 247,
192
247, 248, 248, 249, 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, 254, 255
193
};
194
195
static INLINE
196
int
197
0
ss_isqrt(int x) {
198
0
  int y, e;
199
200
0
  if(x >= (SS_BLOCKSIZE * SS_BLOCKSIZE)) { return SS_BLOCKSIZE; }
201
0
  e = ((unsigned)x & 0xffff0000) ?
202
0
        (((unsigned)x & 0xff000000) ?
203
0
          24 + lg_table[(x >> 24) & 0xff] :
204
0
          16 + lg_table[(x >> 16) & 0xff]) :
205
0
        ((x & 0x0000ff00) ?
206
0
           8 + lg_table[(x >>  8) & 0xff] :
207
0
           0 + lg_table[(x >>  0) & 0xff]);
208
209
0
  if(e >= 16) {
210
0
    y = sqq_table[x >> ((e - 6) - (e & 1))] << ((e >> 1) - 7);
211
0
    if(e >= 24) { y = (y + 1 + x / y) >> 1; }
212
0
    y = (y + 1 + x / y) >> 1;
213
0
  } else if(e >= 8) {
214
0
    y = (sqq_table[x >> ((e - 6) - (e & 1))] >> (7 - (e >> 1))) + 1;
215
0
  } else {
216
0
    return sqq_table[x] >> 4;
217
0
  }
218
219
0
  return (x < (y * y)) ? y - 1 : y;
220
0
}
221
222
#endif /* SS_BLOCKSIZE != 0 */
223
224
225
/*---------------------------------------------------------------------------*/
226
227
/* Compares two suffixes. */
228
static INLINE
229
int
230
ss_compare(const unsigned char *T,
231
           const int *p1, const int *p2,
232
0
           int depth) {
233
0
  const unsigned char *U1, *U2, *U1n, *U2n;
234
235
0
  for(U1 = T + depth + *p1,
236
0
      U2 = T + depth + *p2,
237
0
      U1n = T + *(p1 + 1) + 2,
238
0
      U2n = T + *(p2 + 1) + 2;
239
0
      (U1 < U1n) && (U2 < U2n) && (*U1 == *U2);
240
0
      ++U1, ++U2) {
241
0
  }
242
243
0
  return U1 < U1n ?
244
0
        (U2 < U2n ? *U1 - *U2 : 1) :
245
0
        (U2 < U2n ? -1 : 0);
246
0
}
247
248
249
/*---------------------------------------------------------------------------*/
250
251
#if (SS_BLOCKSIZE != 1) && (SS_INSERTIONSORT_THRESHOLD != 1)
252
253
/* Insertionsort for small size groups */
254
static
255
void
256
ss_insertionsort(const unsigned char *T, const int *PA,
257
0
                 int *first, int *last, int depth) {
258
0
  int *i, *j;
259
0
  int t;
260
0
  int r;
261
262
0
  for(i = last - 2; first <= i; --i) {
263
0
    for(t = *i, j = i + 1; 0 < (r = ss_compare(T, PA + t, PA + *j, depth));) {
264
0
      do { *(j - 1) = *j; } while((++j < last) && (*j < 0));
265
0
      if(last <= j) { break; }
266
0
    }
267
0
    if(r == 0) { *j = ~*j; }
268
0
    *(j - 1) = t;
269
0
  }
270
0
}
271
272
#endif /* (SS_BLOCKSIZE != 1) && (SS_INSERTIONSORT_THRESHOLD != 1) */
273
274
275
/*---------------------------------------------------------------------------*/
276
277
#if (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE)
278
279
static INLINE
280
void
281
ss_fixdown(const unsigned char *Td, const int *PA,
282
0
           int *SA, int i, int size) {
283
0
  int j, k;
284
0
  int v;
285
0
  int c, d, e;
286
287
0
  for(v = SA[i], c = Td[PA[v]]; (j = 2 * i + 1) < size; SA[i] = SA[k], i = k) {
288
0
    d = Td[PA[SA[k = j++]]];
289
0
    if(d < (e = Td[PA[SA[j]]])) { k = j; d = e; }
290
0
    if(d <= c) { break; }
291
0
  }
292
0
  SA[i] = v;
293
0
}
294
295
/* Simple top-down heapsort. */
296
static
297
void
298
0
ss_heapsort(const unsigned char *Td, const int *PA, int *SA, int size) {
299
0
  int i, m;
300
0
  int t;
301
302
0
  m = size;
303
0
  if((size % 2) == 0) {
304
0
    m--;
305
0
    if(Td[PA[SA[m / 2]]] < Td[PA[SA[m]]]) { SWAP(SA[m], SA[m / 2]); }
306
0
  }
307
308
0
  for(i = m / 2 - 1; 0 <= i; --i) { ss_fixdown(Td, PA, SA, i, m); }
309
0
  if((size % 2) == 0) { SWAP(SA[0], SA[m]); ss_fixdown(Td, PA, SA, 0, m); }
310
0
  for(i = m - 1; 0 < i; --i) {
311
0
    t = SA[0], SA[0] = SA[i];
312
0
    ss_fixdown(Td, PA, SA, 0, i);
313
0
    SA[i] = t;
314
0
  }
315
0
}
316
317
318
/*---------------------------------------------------------------------------*/
319
320
/* Returns the median of three elements. */
321
static INLINE
322
int *
323
ss_median3(const unsigned char *Td, const int *PA,
324
0
           int *v1, int *v2, int *v3) {
325
0
  int *t;
326
0
  if(Td[PA[*v1]] > Td[PA[*v2]]) { SWAP(v1, v2); }
327
0
  if(Td[PA[*v2]] > Td[PA[*v3]]) {
328
0
    if(Td[PA[*v1]] > Td[PA[*v3]]) { return v1; }
329
0
    else { return v3; }
330
0
  }
331
0
  return v2;
332
0
}
333
334
/* Returns the median of five elements. */
335
static INLINE
336
int *
337
ss_median5(const unsigned char *Td, const int *PA,
338
0
           int *v1, int *v2, int *v3, int *v4, int *v5) {
339
0
  int *t;
340
0
  if(Td[PA[*v2]] > Td[PA[*v3]]) { SWAP(v2, v3); }
341
0
  if(Td[PA[*v4]] > Td[PA[*v5]]) { SWAP(v4, v5); }
342
0
  if(Td[PA[*v2]] > Td[PA[*v4]]) { SWAP(v2, v4); SWAP(v3, v5); }
343
0
  if(Td[PA[*v1]] > Td[PA[*v3]]) { SWAP(v1, v3); }
344
0
  if(Td[PA[*v1]] > Td[PA[*v4]]) { SWAP(v1, v4); SWAP(v3, v5); }
345
0
  if(Td[PA[*v3]] > Td[PA[*v4]]) { return v4; }
346
0
  return v3;
347
0
}
348
349
/* Returns the pivot element. */
350
static INLINE
351
int *
352
0
ss_pivot(const unsigned char *Td, const int *PA, int *first, int *last) {
353
0
  int *middle;
354
0
  int t;
355
356
0
  t = PTRDIFF_TO_INT(last - first);
357
0
  middle = first + t / 2;
358
359
0
  if(t <= 512) {
360
0
    if(t <= 32) {
361
0
      return ss_median3(Td, PA, first, middle, last - 1);
362
0
    } else {
363
0
      t >>= 2;
364
0
      return ss_median5(Td, PA, first, first + t, middle, last - 1 - t, last - 1);
365
0
    }
366
0
  }
367
0
  t >>= 3;
368
0
  first  = ss_median3(Td, PA, first, first + t, first + (t << 1));
369
0
  middle = ss_median3(Td, PA, middle - t, middle, middle + t);
370
0
  last   = ss_median3(Td, PA, last - 1 - (t << 1), last - 1 - t, last - 1);
371
0
  return ss_median3(Td, PA, first, middle, last);
372
0
}
373
374
375
/*---------------------------------------------------------------------------*/
376
377
/* Binary partition for substrings. */
378
static INLINE
379
int *
380
ss_partition(const int *PA,
381
0
                    int *first, int *last, int depth) {
382
0
  int *a, *b;
383
0
  int t;
384
0
  for(a = first - 1, b = last;;) {
385
0
    for(; (++a < b) && ((PA[*a] + depth) >= (PA[*a + 1] + 1));) { *a = ~*a; }
386
0
    for(; (a < --b) && ((PA[*b] + depth) <  (PA[*b + 1] + 1));) { }
387
0
    if(b <= a) { break; }
388
0
    t = ~*b;
389
0
    *b = *a;
390
0
    *a = t;
391
0
  }
392
0
  if(first < a) { *first = ~*first; }
393
0
  return a;
394
0
}
395
396
/* Multikey introsort for medium size groups. */
397
static
398
void
399
ss_mintrosort(const unsigned char *T, const int *PA,
400
              int *first, int *last,
401
0
              int depth) {
402
0
#define STACK_SIZE SS_MISORT_STACKSIZE
403
0
  struct { int *a, *b, c; int d; } stack[STACK_SIZE];
404
0
  const unsigned char *Td;
405
0
  int *a, *b, *c, *d, *e, *f;
406
0
  int s, t;
407
0
  int ssize;
408
0
  int limit;
409
0
  int v, x = 0;
410
411
0
  for(ssize = 0, limit = ss_ilg(PTRDIFF_TO_INT(last - first));;) {
412
413
0
    if((last - first) <= SS_INSERTIONSORT_THRESHOLD) {
414
0
#if 1 < SS_INSERTIONSORT_THRESHOLD
415
0
      if(1 < (last - first)) { ss_insertionsort(T, PA, first, last, depth); }
416
0
#endif
417
0
      STACK_POP(first, last, depth, limit);
418
0
      continue;
419
0
    }
420
421
0
    Td = T + depth;
422
0
    if(limit-- == 0) { ss_heapsort(Td, PA, first, PTRDIFF_TO_INT(last - first)); }
423
0
    if(limit < 0) {
424
0
      for(a = first + 1, v = Td[PA[*first]]; a < last; ++a) {
425
0
        if((x = Td[PA[*a]]) != v) {
426
0
          if(1 < (a - first)) { break; }
427
0
          v = x;
428
0
          first = a;
429
0
        }
430
0
      }
431
0
      if(Td[PA[*first] - 1] < v) {
432
0
        first = ss_partition(PA, first, a, depth);
433
0
      }
434
0
      if((a - first) <= (last - a)) {
435
0
        if(1 < (a - first)) {
436
0
          STACK_PUSH(a, last, depth, -1);
437
0
          last = a, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(a - first));
438
0
        } else {
439
0
          first = a, limit = -1;
440
0
        }
441
0
      } else {
442
0
        if(1 < (last - a)) {
443
0
          STACK_PUSH(first, a, depth + 1, ss_ilg(PTRDIFF_TO_INT(a - first)));
444
0
          first = a, limit = -1;
445
0
        } else {
446
0
          last = a, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(a - first));
447
0
        }
448
0
      }
449
0
      continue;
450
0
    }
451
452
    /* choose pivot */
453
0
    a = ss_pivot(Td, PA, first, last);
454
0
    v = Td[PA[*a]];
455
0
    SWAP(*first, *a);
456
457
    /* partition */
458
0
    for(b = first; (++b < last) && ((x = Td[PA[*b]]) == v);) { }
459
0
    if(((a = b) < last) && (x < v)) {
460
0
      for(; (++b < last) && ((x = Td[PA[*b]]) <= v);) {
461
0
        if(x == v) { SWAP(*b, *a); ++a; }
462
0
      }
463
0
    }
464
0
    for(c = last; (b < --c) && ((x = Td[PA[*c]]) == v);) { }
465
0
    if((b < (d = c)) && (x > v)) {
466
0
      for(; (b < --c) && ((x = Td[PA[*c]]) >= v);) {
467
0
        if(x == v) { SWAP(*c, *d); --d; }
468
0
      }
469
0
    }
470
0
    for(; b < c;) {
471
0
      SWAP(*b, *c);
472
0
      for(; (++b < c) && ((x = Td[PA[*b]]) <= v);) {
473
0
        if(x == v) { SWAP(*b, *a); ++a; }
474
0
      }
475
0
      for(; (b < --c) && ((x = Td[PA[*c]]) >= v);) {
476
0
        if(x == v) { SWAP(*c, *d); --d; }
477
0
      }
478
0
    }
479
480
0
    if(a <= d) {
481
0
      c = b - 1;
482
483
0
      if((s = PTRDIFF_TO_INT(a - first)) > (t = PTRDIFF_TO_INT(b - a))) { s = t; }
484
0
      for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
485
0
      if((s = PTRDIFF_TO_INT(d - c)) > (t = PTRDIFF_TO_INT(last - d - 1))) { s = t; }
486
0
      for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
487
488
0
      a = first + (b - a), c = last - (d - c);
489
0
      b = (v <= Td[PA[*a] - 1]) ? a : ss_partition(PA, a, c, depth);
490
491
0
      if((a - first) <= (last - c)) {
492
0
        if((last - c) <= (c - b)) {
493
0
          STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
494
0
          STACK_PUSH(c, last, depth, limit);
495
0
          last = a;
496
0
        } else if((a - first) <= (c - b)) {
497
0
          STACK_PUSH(c, last, depth, limit);
498
0
          STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
499
0
          last = a;
500
0
        } else {
501
0
          STACK_PUSH(c, last, depth, limit);
502
0
          STACK_PUSH(first, a, depth, limit);
503
0
          first = b, last = c, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(c - b));
504
0
        }
505
0
      } else {
506
0
        if((a - first) <= (c - b)) {
507
0
          STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
508
0
          STACK_PUSH(first, a, depth, limit);
509
0
          first = c;
510
0
        } else if((last - c) <= (c - b)) {
511
0
          STACK_PUSH(first, a, depth, limit);
512
0
          STACK_PUSH(b, c, depth + 1, ss_ilg(PTRDIFF_TO_INT(c - b)));
513
0
          first = c;
514
0
        } else {
515
0
          STACK_PUSH(first, a, depth, limit);
516
0
          STACK_PUSH(c, last, depth, limit);
517
0
          first = b, last = c, depth += 1, limit = ss_ilg(PTRDIFF_TO_INT(c - b));
518
0
        }
519
0
      }
520
0
    } else {
521
0
      limit += 1;
522
0
      if(Td[PA[*first] - 1] < v) {
523
0
        first = ss_partition(PA, first, last, depth);
524
0
        limit = ss_ilg(PTRDIFF_TO_INT(last - first));
525
0
      }
526
0
      depth += 1;
527
0
    }
528
0
  }
529
0
#undef STACK_SIZE
530
0
}
531
532
#endif /* (SS_BLOCKSIZE == 0) || (SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE) */
533
534
535
/*---------------------------------------------------------------------------*/
536
537
#if SS_BLOCKSIZE != 0
538
539
static INLINE
540
void
541
0
ss_blockswap(int *a, int *b, int n) {
542
0
  int t;
543
0
  for(; 0 < n; --n, ++a, ++b) {
544
0
    t = *a, *a = *b, *b = t;
545
0
  }
546
0
}
547
548
static INLINE
549
void
550
0
ss_rotate(int *first, int *middle, int *last) {
551
0
  int *a, *b, t;
552
0
  int l, r;
553
0
  l = PTRDIFF_TO_INT(middle - first);
554
0
  r = PTRDIFF_TO_INT(last - middle);
555
0
  for(; (0 < l) && (0 < r);) {
556
0
    if(l == r) { ss_blockswap(first, middle, l); break; }
557
0
    if(l < r) {
558
0
      a = last - 1, b = middle - 1;
559
0
      t = *a;
560
0
      do {
561
0
        *a-- = *b, *b-- = *a;
562
0
        if(b < first) {
563
0
          *a = t;
564
0
          last = a;
565
0
          if((r -= l + 1) <= l) { break; }
566
0
          a -= 1, b = middle - 1;
567
0
          t = *a;
568
0
        }
569
0
      } while(1);
570
0
    } else {
571
0
      a = first, b = middle;
572
0
      t = *a;
573
0
      do {
574
0
        *a++ = *b, *b++ = *a;
575
0
        if(last <= b) {
576
0
          *a = t;
577
0
          first = a + 1;
578
0
          if((l -= r + 1) <= r) { break; }
579
0
          a += 1, b = middle;
580
0
          t = *a;
581
0
        }
582
0
      } while(1);
583
0
    }
584
0
  }
585
0
}
586
587
588
/*---------------------------------------------------------------------------*/
589
590
static
591
void
592
ss_inplacemerge(const unsigned char *T, const int *PA,
593
                int *first, int *middle, int *last,
594
0
                int depth) {
595
0
  const int *p;
596
0
  int *a, *b;
597
0
  int len, half;
598
0
  int q, r;
599
0
  int x;
600
601
0
  for(;;) {
602
0
    if(*(last - 1) < 0) { x = 1; p = PA + ~*(last - 1); }
603
0
    else                { x = 0; p = PA +  *(last - 1); }
604
0
    for(a = first, len = PTRDIFF_TO_INT(middle - first), half = len >> 1, r = -1;
605
0
        0 < len;
606
0
        len = half, half >>= 1) {
607
0
      b = a + half;
608
0
      q = ss_compare(T, PA + ((0 <= *b) ? *b : ~*b), p, depth);
609
0
      if(q < 0) {
610
0
        a = b + 1;
611
0
        half -= (len & 1) ^ 1;
612
0
      } else {
613
0
        r = q;
614
0
      }
615
0
    }
616
0
    if(a < middle) {
617
0
      if(r == 0) { *a = ~*a; }
618
0
      ss_rotate(a, middle, last);
619
0
      last -= middle - a;
620
0
      middle = a;
621
0
      if(first == middle) { break; }
622
0
    }
623
0
    --last;
624
0
    if(x != 0) { while(*--last < 0) { } }
625
0
    if(middle == last) { break; }
626
0
  }
627
0
}
628
629
630
/*---------------------------------------------------------------------------*/
631
632
/* Merge-forward with internal buffer. */
633
static
634
void
635
ss_mergeforward(const unsigned char *T, const int *PA,
636
                int *first, int *middle, int *last,
637
0
                int *buf, int depth) {
638
0
  int *a, *b, *c, *bufend;
639
0
  int t;
640
0
  int r;
641
642
0
  bufend = buf + (middle - first) - 1;
643
0
  ss_blockswap(buf, first, PTRDIFF_TO_INT(middle - first));
644
645
0
  for(t = *(a = first), b = buf, c = middle;;) {
646
0
    r = ss_compare(T, PA + *b, PA + *c, depth);
647
0
    if(r < 0) {
648
0
      do {
649
0
        *a++ = *b;
650
0
        if(bufend <= b) { *bufend = t; return; }
651
0
        *b++ = *a;
652
0
      } while(*b < 0);
653
0
    } else if(r > 0) {
654
0
      do {
655
0
        *a++ = *c, *c++ = *a;
656
0
        if(last <= c) {
657
0
          while(b < bufend) { *a++ = *b, *b++ = *a; }
658
0
          *a = *b, *b = t;
659
0
          return;
660
0
        }
661
0
      } while(*c < 0);
662
0
    } else {
663
0
      *c = ~*c;
664
0
      do {
665
0
        *a++ = *b;
666
0
        if(bufend <= b) { *bufend = t; return; }
667
0
        *b++ = *a;
668
0
      } while(*b < 0);
669
670
0
      do {
671
0
        *a++ = *c, *c++ = *a;
672
0
        if(last <= c) {
673
0
          while(b < bufend) { *a++ = *b, *b++ = *a; }
674
0
          *a = *b, *b = t;
675
0
          return;
676
0
        }
677
0
      } while(*c < 0);
678
0
    }
679
0
  }
680
0
}
681
682
/* Merge-backward with internal buffer. */
683
static
684
void
685
ss_mergebackward(const unsigned char *T, const int *PA,
686
                 int *first, int *middle, int *last,
687
0
                 int *buf, int depth) {
688
0
  const int *p1, *p2;
689
0
  int *a, *b, *c, *bufend;
690
0
  int t;
691
0
  int r;
692
0
  int x;
693
694
0
  bufend = buf + (last - middle) - 1;
695
0
  ss_blockswap(buf, middle, PTRDIFF_TO_INT(last - middle));
696
697
0
  x = 0;
698
0
  if(*bufend < 0)       { p1 = PA + ~*bufend; x |= 1; }
699
0
  else                  { p1 = PA +  *bufend; }
700
0
  if(*(middle - 1) < 0) { p2 = PA + ~*(middle - 1); x |= 2; }
701
0
  else                  { p2 = PA +  *(middle - 1); }
702
0
  for(t = *(a = last - 1), b = bufend, c = middle - 1;;) {
703
0
    r = ss_compare(T, p1, p2, depth);
704
0
    if(0 < r) {
705
0
      if(x & 1) { do { *a-- = *b, *b-- = *a; } while(*b < 0); x ^= 1; }
706
0
      *a-- = *b;
707
0
      if(b <= buf) { *buf = t; break; }
708
0
      *b-- = *a;
709
0
      if(*b < 0) { p1 = PA + ~*b; x |= 1; }
710
0
      else       { p1 = PA +  *b; }
711
0
    } else if(r < 0) {
712
0
      if(x & 2) { do { *a-- = *c, *c-- = *a; } while(*c < 0); x ^= 2; }
713
0
      *a-- = *c, *c-- = *a;
714
0
      if(c < first) {
715
0
        while(buf < b) { *a-- = *b, *b-- = *a; }
716
0
        *a = *b, *b = t;
717
0
        break;
718
0
      }
719
0
      if(*c < 0) { p2 = PA + ~*c; x |= 2; }
720
0
      else       { p2 = PA +  *c; }
721
0
    } else {
722
0
      if(x & 1) { do { *a-- = *b, *b-- = *a; } while(*b < 0); x ^= 1; }
723
0
      *a-- = ~*b;
724
0
      if(b <= buf) { *buf = t; break; }
725
0
      *b-- = *a;
726
0
      if(x & 2) { do { *a-- = *c, *c-- = *a; } while(*c < 0); x ^= 2; }
727
0
      *a-- = *c, *c-- = *a;
728
0
      if(c < first) {
729
0
        while(buf < b) { *a-- = *b, *b-- = *a; }
730
0
        *a = *b, *b = t;
731
0
        break;
732
0
      }
733
0
      if(*b < 0) { p1 = PA + ~*b; x |= 1; }
734
0
      else       { p1 = PA +  *b; }
735
0
      if(*c < 0) { p2 = PA + ~*c; x |= 2; }
736
0
      else       { p2 = PA +  *c; }
737
0
    }
738
0
  }
739
0
}
740
741
/* D&C based merge. */
742
static
743
void
744
ss_swapmerge(const unsigned char *T, const int *PA,
745
             int *first, int *middle, int *last,
746
0
             int *buf, int bufsize, int depth) {
747
0
#define STACK_SIZE SS_SMERGE_STACKSIZE
748
0
#define GETIDX(a) ((0 <= (a)) ? (a) : (~(a)))
749
0
#define MERGE_CHECK(a, b, c)\
750
0
  do {\
751
0
    if(((c) & 1) ||\
752
0
       (((c) & 2) && (ss_compare(T, PA + GETIDX(*((a) - 1)), PA + *(a), depth) == 0))) {\
753
0
      *(a) = ~*(a);\
754
0
    }\
755
0
    if(((c) & 4) && ((ss_compare(T, PA + GETIDX(*((b) - 1)), PA + *(b), depth) == 0))) {\
756
0
      *(b) = ~*(b);\
757
0
    }\
758
0
  } while(0)
759
0
  struct { int *a, *b, *c; int d; } stack[STACK_SIZE];
760
0
  int *l, *r, *lm, *rm;
761
0
  int m, len, half;
762
0
  int ssize;
763
0
  int check, next;
764
765
0
  for(check = 0, ssize = 0;;) {
766
0
    if((last - middle) <= bufsize) {
767
0
      if((first < middle) && (middle < last)) {
768
0
        ss_mergebackward(T, PA, first, middle, last, buf, depth);
769
0
      }
770
0
      MERGE_CHECK(first, last, check);
771
0
      STACK_POP(first, middle, last, check);
772
0
      continue;
773
0
    }
774
775
0
    if((middle - first) <= bufsize) {
776
0
      if(first < middle) {
777
0
        ss_mergeforward(T, PA, first, middle, last, buf, depth);
778
0
      }
779
0
      MERGE_CHECK(first, last, check);
780
0
      STACK_POP(first, middle, last, check);
781
0
      continue;
782
0
    }
783
784
0
    for(m = 0, len = PTRDIFF_TO_INT(MIN(middle - first, last - middle)), half = len >> 1;
785
0
        0 < len;
786
0
        len = half, half >>= 1) {
787
0
      if(ss_compare(T, PA + GETIDX(*(middle + m + half)),
788
0
                       PA + GETIDX(*(middle - m - half - 1)), depth) < 0) {
789
0
        m += half + 1;
790
0
        half -= (len & 1) ^ 1;
791
0
      }
792
0
    }
793
794
0
    if(0 < m) {
795
0
      lm = middle - m, rm = middle + m;
796
0
      ss_blockswap(lm, middle, m);
797
0
      l = r = middle, next = 0;
798
0
      if(rm < last) {
799
0
        if(*rm < 0) {
800
0
          *rm = ~*rm;
801
0
          if(first < lm) { for(; *--l < 0;) { } next |= 4; }
802
0
          next |= 1;
803
0
        } else if(first < lm) {
804
0
          for(; *r < 0; ++r) { }
805
0
          next |= 2;
806
0
        }
807
0
      }
808
809
0
      if((l - first) <= (last - r)) {
810
0
        STACK_PUSH(r, rm, last, (next & 3) | (check & 4));
811
0
        middle = lm, last = l, check = (check & 3) | (next & 4);
812
0
      } else {
813
0
        if((next & 2) && (r == middle)) { next ^= 6; }
814
0
        STACK_PUSH(first, lm, l, (check & 3) | (next & 4));
815
0
        first = r, middle = rm, check = (next & 3) | (check & 4);
816
0
      }
817
0
    } else {
818
0
      if(ss_compare(T, PA + GETIDX(*(middle - 1)), PA + *middle, depth) == 0) {
819
0
        *middle = ~*middle;
820
0
      }
821
0
      MERGE_CHECK(first, last, check);
822
0
      STACK_POP(first, middle, last, check);
823
0
    }
824
0
  }
825
0
#undef STACK_SIZE
826
0
}
827
828
#endif /* SS_BLOCKSIZE != 0 */
829
830
831
/*---------------------------------------------------------------------------*/
832
833
/* Substring sort */
834
static
835
void
836
sssort(const unsigned char *T, const int *PA,
837
       int *first, int *last,
838
       int *buf, int bufsize,
839
0
       int depth, int n, int lastsuffix) {
840
0
  int *a;
841
0
#if SS_BLOCKSIZE != 0
842
0
  int *b, *middle, *curbuf;
843
0
  int j, k, curbufsize, limit;
844
0
#endif
845
0
  int i;
846
847
0
  if(lastsuffix != 0) { ++first; }
848
849
#if SS_BLOCKSIZE == 0
850
  ss_mintrosort(T, PA, first, last, depth);
851
#else
852
0
  if((bufsize < SS_BLOCKSIZE) &&
853
0
      (bufsize < PTRDIFF_TO_INT(last - first)) &&
854
0
      (bufsize < (limit = ss_isqrt(PTRDIFF_TO_INT(last - first))))) {
855
0
    if(SS_BLOCKSIZE < limit) { limit = SS_BLOCKSIZE; }
856
0
    buf = middle = last - limit, bufsize = limit;
857
0
  } else {
858
0
    middle = last, limit = 0;
859
0
  }
860
0
  for(a = first, i = 0; SS_BLOCKSIZE < (middle - a); a += SS_BLOCKSIZE, ++i) {
861
0
#if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE
862
0
    ss_mintrosort(T, PA, a, a + SS_BLOCKSIZE, depth);
863
#elif 1 < SS_BLOCKSIZE
864
    ss_insertionsort(T, PA, a, a + SS_BLOCKSIZE, depth);
865
#endif
866
0
    curbufsize = PTRDIFF_TO_INT(last - (a + SS_BLOCKSIZE));
867
0
    curbuf = a + SS_BLOCKSIZE;
868
0
    if(curbufsize <= bufsize) { curbufsize = bufsize, curbuf = buf; }
869
0
    for(b = a, k = SS_BLOCKSIZE, j = i; j & 1; b -= k, k <<= 1, j >>= 1) {
870
0
      ss_swapmerge(T, PA, b - k, b, b + k, curbuf, curbufsize, depth);
871
0
    }
872
0
  }
873
0
#if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE
874
0
  ss_mintrosort(T, PA, a, middle, depth);
875
#elif 1 < SS_BLOCKSIZE
876
  ss_insertionsort(T, PA, a, middle, depth);
877
#endif
878
0
  for(k = SS_BLOCKSIZE; i != 0; k <<= 1, i >>= 1) {
879
0
    if(i & 1) {
880
0
      ss_swapmerge(T, PA, a - k, a, middle, buf, bufsize, depth);
881
0
      a -= k;
882
0
    }
883
0
  }
884
0
  if(limit != 0) {
885
0
#if SS_INSERTIONSORT_THRESHOLD < SS_BLOCKSIZE
886
0
    ss_mintrosort(T, PA, middle, last, depth);
887
#elif 1 < SS_BLOCKSIZE
888
    ss_insertionsort(T, PA, middle, last, depth);
889
#endif
890
0
    ss_inplacemerge(T, PA, first, middle, last, depth);
891
0
  }
892
0
#endif
893
894
0
  if(lastsuffix != 0) {
895
    /* Insert last type B* suffix. */
896
0
    int PAi[2]; PAi[0] = PA[*(first - 1)], PAi[1] = n - 2;
897
0
    for(a = first, i = *(first - 1);
898
0
        (a < last) && ((*a < 0) || (0 < ss_compare(T, &(PAi[0]), PA + *a, depth)));
899
0
        ++a) {
900
0
      *(a - 1) = *a;
901
0
    }
902
0
    *(a - 1) = i;
903
0
  }
904
0
}
905
906
907
/*---------------------------------------------------------------------------*/
908
909
static INLINE
910
int
911
0
tr_ilg(int n) {
912
0
  return (n & 0xffff0000) ?
913
0
          ((n & 0xff000000) ?
914
0
            24 + lg_table[(n >> 24) & 0xff] :
915
0
            16 + lg_table[(n >> 16) & 0xff]) :
916
0
          ((n & 0x0000ff00) ?
917
0
             8 + lg_table[(n >>  8) & 0xff] :
918
0
             0 + lg_table[(n >>  0) & 0xff]);
919
0
}
920
921
922
/*---------------------------------------------------------------------------*/
923
924
/* Simple insertionsort for small size groups. */
925
static
926
void
927
0
tr_insertionsort(const int *ISAd, int *first, int *last) {
928
0
  int *a, *b;
929
0
  int t, r;
930
931
0
  for(a = first + 1; a < last; ++a) {
932
0
    for(t = *a, b = a - 1; 0 > (r = ISAd[t] - ISAd[*b]);) {
933
0
      do { *(b + 1) = *b; } while((first <= --b) && (*b < 0));
934
0
      if(b < first) { break; }
935
0
    }
936
0
    if(r == 0) { *b = ~*b; }
937
0
    *(b + 1) = t;
938
0
  }
939
0
}
940
941
942
/*---------------------------------------------------------------------------*/
943
944
static INLINE
945
void
946
0
tr_fixdown(const int *ISAd, int *SA, int i, int size) {
947
0
  int j, k;
948
0
  int v;
949
0
  int c, d, e;
950
951
0
  for(v = SA[i], c = ISAd[v]; (j = 2 * i + 1) < size; SA[i] = SA[k], i = k) {
952
0
    d = ISAd[SA[k = j++]];
953
0
    if(d < (e = ISAd[SA[j]])) { k = j; d = e; }
954
0
    if(d <= c) { break; }
955
0
  }
956
0
  SA[i] = v;
957
0
}
958
959
/* Simple top-down heapsort. */
960
static
961
void
962
0
tr_heapsort(const int *ISAd, int *SA, int size) {
963
0
  int i, m;
964
0
  int t;
965
966
0
  m = size;
967
0
  if((size % 2) == 0) {
968
0
    m--;
969
0
    if(ISAd[SA[m / 2]] < ISAd[SA[m]]) { SWAP(SA[m], SA[m / 2]); }
970
0
  }
971
972
0
  for(i = m / 2 - 1; 0 <= i; --i) { tr_fixdown(ISAd, SA, i, m); }
973
0
  if((size % 2) == 0) { SWAP(SA[0], SA[m]); tr_fixdown(ISAd, SA, 0, m); }
974
0
  for(i = m - 1; 0 < i; --i) {
975
0
    t = SA[0], SA[0] = SA[i];
976
0
    tr_fixdown(ISAd, SA, 0, i);
977
0
    SA[i] = t;
978
0
  }
979
0
}
980
981
982
/*---------------------------------------------------------------------------*/
983
984
/* Returns the median of three elements. */
985
static INLINE
986
int *
987
0
tr_median3(const int *ISAd, int *v1, int *v2, int *v3) {
988
0
  int *t;
989
0
  if(ISAd[*v1] > ISAd[*v2]) { SWAP(v1, v2); }
990
0
  if(ISAd[*v2] > ISAd[*v3]) {
991
0
    if(ISAd[*v1] > ISAd[*v3]) { return v1; }
992
0
    else { return v3; }
993
0
  }
994
0
  return v2;
995
0
}
996
997
/* Returns the median of five elements. */
998
static INLINE
999
int *
1000
tr_median5(const int *ISAd,
1001
0
           int *v1, int *v2, int *v3, int *v4, int *v5) {
1002
0
  int *t;
1003
0
  if(ISAd[*v2] > ISAd[*v3]) { SWAP(v2, v3); }
1004
0
  if(ISAd[*v4] > ISAd[*v5]) { SWAP(v4, v5); }
1005
0
  if(ISAd[*v2] > ISAd[*v4]) { SWAP(v2, v4); SWAP(v3, v5); }
1006
0
  if(ISAd[*v1] > ISAd[*v3]) { SWAP(v1, v3); }
1007
0
  if(ISAd[*v1] > ISAd[*v4]) { SWAP(v1, v4); SWAP(v3, v5); }
1008
0
  if(ISAd[*v3] > ISAd[*v4]) { return v4; }
1009
0
  return v3;
1010
0
}
1011
1012
/* Returns the pivot element. */
1013
static INLINE
1014
int *
1015
0
tr_pivot(const int *ISAd, int *first, int *last) {
1016
0
  int *middle;
1017
0
  int t;
1018
1019
0
  t = PTRDIFF_TO_INT(last - first);
1020
0
  middle = first + t / 2;
1021
1022
0
  if(t <= 512) {
1023
0
    if(t <= 32) {
1024
0
      return tr_median3(ISAd, first, middle, last - 1);
1025
0
    } else {
1026
0
      t >>= 2;
1027
0
      return tr_median5(ISAd, first, first + t, middle, last - 1 - t, last - 1);
1028
0
    }
1029
0
  }
1030
0
  t >>= 3;
1031
0
  first  = tr_median3(ISAd, first, first + t, first + (t << 1));
1032
0
  middle = tr_median3(ISAd, middle - t, middle, middle + t);
1033
0
  last   = tr_median3(ISAd, last - 1 - (t << 1), last - 1 - t, last - 1);
1034
0
  return tr_median3(ISAd, first, middle, last);
1035
0
}
1036
1037
1038
/*---------------------------------------------------------------------------*/
1039
1040
typedef struct _trbudget_t trbudget_t;
1041
struct _trbudget_t {
1042
  int chance;
1043
  int remain;
1044
  int incval;
1045
  int count;
1046
};
1047
1048
static INLINE
1049
void
1050
0
trbudget_init(trbudget_t *budget, int chance, int incval) {
1051
0
  budget->chance = chance;
1052
0
  budget->remain = budget->incval = incval;
1053
0
}
1054
1055
static INLINE
1056
int
1057
0
trbudget_check(trbudget_t *budget, int size) {
1058
0
  if(size <= budget->remain) { budget->remain -= size; return 1; }
1059
0
  if(budget->chance == 0) { budget->count += size; return 0; }
1060
0
  budget->remain += budget->incval - size;
1061
0
  budget->chance -= 1;
1062
0
  return 1;
1063
0
}
1064
1065
1066
/*---------------------------------------------------------------------------*/
1067
1068
static INLINE
1069
void
1070
tr_partition(const int *ISAd,
1071
             int *first, int *middle, int *last,
1072
0
             int **pa, int **pb, int v) {
1073
0
  int *a, *b, *c, *d, *e, *f;
1074
0
  int t, s;
1075
0
  int x = 0;
1076
1077
0
  for(b = middle - 1; (++b < last) && ((x = ISAd[*b]) == v);) { }
1078
0
  if(((a = b) < last) && (x < v)) {
1079
0
    for(; (++b < last) && ((x = ISAd[*b]) <= v);) {
1080
0
      if(x == v) { SWAP(*b, *a); ++a; }
1081
0
    }
1082
0
  }
1083
0
  for(c = last; (b < --c) && ((x = ISAd[*c]) == v);) { }
1084
0
  if((b < (d = c)) && (x > v)) {
1085
0
    for(; (b < --c) && ((x = ISAd[*c]) >= v);) {
1086
0
      if(x == v) { SWAP(*c, *d); --d; }
1087
0
    }
1088
0
  }
1089
0
  for(; b < c;) {
1090
0
    SWAP(*b, *c);
1091
0
    for(; (++b < c) && ((x = ISAd[*b]) <= v);) {
1092
0
      if(x == v) { SWAP(*b, *a); ++a; }
1093
0
    }
1094
0
    for(; (b < --c) && ((x = ISAd[*c]) >= v);) {
1095
0
      if(x == v) { SWAP(*c, *d); --d; }
1096
0
    }
1097
0
  }
1098
1099
0
  if(a <= d) {
1100
0
    c = b - 1;
1101
0
    if((s = PTRDIFF_TO_INT(a - first)) > (t = PTRDIFF_TO_INT(b - a))) { s = t; }
1102
0
    for(e = first, f = b - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
1103
0
    if((s = PTRDIFF_TO_INT(d - c)) > (t = PTRDIFF_TO_INT(last - d - 1))) { s = t; }
1104
0
    for(e = b, f = last - s; 0 < s; --s, ++e, ++f) { SWAP(*e, *f); }
1105
0
    first += (b - a), last -= (d - c);
1106
0
  }
1107
0
  *pa = first, *pb = last;
1108
0
}
1109
1110
static
1111
void
1112
tr_copy(int *ISA, const int *SA,
1113
        int *first, int *a, int *b, int *last,
1114
0
        int depth) {
1115
  /* sort suffixes of middle partition
1116
     by using sorted order of suffixes of left and right partition. */
1117
0
  int *c, *d, *e;
1118
0
  int s, v;
1119
1120
0
  v = PTRDIFF_TO_INT(b - SA - 1);
1121
0
  for(c = first, d = a - 1; c <= d; ++c) {
1122
0
    if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
1123
0
      *++d = s;
1124
0
      ISA[s] = PTRDIFF_TO_INT(d - SA);
1125
0
    }
1126
0
  }
1127
0
  for(c = last - 1, e = d + 1, d = b; e < d; --c) {
1128
0
    if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
1129
0
      *--d = s;
1130
0
      ISA[s] = PTRDIFF_TO_INT(d - SA);
1131
0
    }
1132
0
  }
1133
0
}
1134
1135
static
1136
void
1137
tr_partialcopy(int *ISA, const int *SA,
1138
               int *first, int *a, int *b, int *last,
1139
0
               int depth) {
1140
0
  int *c, *d, *e;
1141
0
  int s, v;
1142
0
  int rank, lastrank, newrank = -1;
1143
1144
0
  v = PTRDIFF_TO_INT(b - SA - 1);
1145
0
  lastrank = -1;
1146
0
  for(c = first, d = a - 1; c <= d; ++c) {
1147
0
    if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
1148
0
      *++d = s;
1149
0
      rank = ISA[s + depth];
1150
0
      if(lastrank != rank) { lastrank = rank; newrank = PTRDIFF_TO_INT(d - SA); }
1151
0
      ISA[s] = newrank;
1152
0
    }
1153
0
  }
1154
1155
0
  lastrank = -1;
1156
0
  for(e = d; first <= e; --e) {
1157
0
    rank = ISA[*e];
1158
0
    if(lastrank != rank) { lastrank = rank; newrank = PTRDIFF_TO_INT(e - SA); }
1159
0
    if(newrank != rank) { ISA[*e] = newrank; }
1160
0
  }
1161
1162
0
  lastrank = -1;
1163
0
  for(c = last - 1, e = d + 1, d = b; e < d; --c) {
1164
0
    if((0 <= (s = *c - depth)) && (ISA[s] == v)) {
1165
0
      *--d = s;
1166
0
      rank = ISA[s + depth];
1167
0
      if(lastrank != rank) { lastrank = rank; newrank = PTRDIFF_TO_INT(d - SA); }
1168
0
      ISA[s] = newrank;
1169
0
    }
1170
0
  }
1171
0
}
1172
1173
static
1174
void
1175
tr_introsort(int *ISA, const int *ISAd,
1176
             int *SA, int *first, int *last,
1177
0
             trbudget_t *budget) {
1178
0
#define STACK_SIZE TR_STACKSIZE
1179
0
  struct { const int *a; int *b, *c; int d, e; }stack[STACK_SIZE];
1180
0
  int *a, *b, *c;
1181
0
  int t;
1182
0
  int v, x = 0;
1183
0
  int incr = PTRDIFF_TO_INT(ISAd - ISA);
1184
0
  int limit, next;
1185
0
  int ssize, trlink = -1;
1186
1187
0
  for(ssize = 0, limit = tr_ilg(PTRDIFF_TO_INT(last - first));;) {
1188
1189
0
    if(limit < 0) {
1190
0
      if(limit == -1) {
1191
        /* tandem repeat partition */
1192
0
        tr_partition(ISAd - incr, first, first, last, &a, &b, PTRDIFF_TO_INT(last - SA - 1));
1193
1194
        /* update ranks */
1195
0
        if(a < last) {
1196
0
          for(c = first, v = PTRDIFF_TO_INT(a - SA - 1); c < a; ++c) { ISA[*c] = v; }
1197
0
        }
1198
0
        if(b < last) {
1199
0
          for(c = a, v = PTRDIFF_TO_INT(b - SA - 1); c < b; ++c) { ISA[*c] = v; }
1200
0
        }
1201
1202
        /* push */
1203
0
        if(1 < (b - a)) {
1204
0
          STACK_PUSH5(NULL, a, b, 0, 0);
1205
0
          STACK_PUSH5(ISAd - incr, first, last, -2, trlink);
1206
0
          trlink = ssize - 2;
1207
0
        }
1208
0
        if((a - first) <= (last - b)) {
1209
0
          if(1 < (a - first)) {
1210
0
            STACK_PUSH5(ISAd, b, last, tr_ilg(PTRDIFF_TO_INT(last - b)), trlink);
1211
0
            last = a, limit = tr_ilg(PTRDIFF_TO_INT(a - first));
1212
0
          } else if(1 < (last - b)) {
1213
0
            first = b, limit = tr_ilg(PTRDIFF_TO_INT(last - b));
1214
0
          } else {
1215
0
            STACK_POP5(ISAd, first, last, limit, trlink);
1216
0
          }
1217
0
        } else {
1218
0
          if(1 < (last - b)) {
1219
0
            STACK_PUSH5(ISAd, first, a, tr_ilg(PTRDIFF_TO_INT(a - first)), trlink);
1220
0
            first = b, limit = tr_ilg(PTRDIFF_TO_INT(last - b));
1221
0
          } else if(1 < (a - first)) {
1222
0
            last = a, limit = tr_ilg(PTRDIFF_TO_INT(a - first));
1223
0
          } else {
1224
0
            STACK_POP5(ISAd, first, last, limit, trlink);
1225
0
          }
1226
0
        }
1227
0
      } else if(limit == -2) {
1228
        /* tandem repeat copy */
1229
0
        a = stack[--ssize].b, b = stack[ssize].c;
1230
0
        if(stack[ssize].d == 0) {
1231
0
          tr_copy(ISA, SA, first, a, b, last, PTRDIFF_TO_INT(ISAd - ISA));
1232
0
        } else {
1233
0
          if(0 <= trlink) { stack[trlink].d = -1; }
1234
0
          tr_partialcopy(ISA, SA, first, a, b, last, PTRDIFF_TO_INT(ISAd - ISA));
1235
0
        }
1236
0
        STACK_POP5(ISAd, first, last, limit, trlink);
1237
0
      } else {
1238
        /* sorted partition */
1239
0
        if(0 <= *first) {
1240
0
          a = first;
1241
0
          do { ISA[*a] = PTRDIFF_TO_INT(a - SA); } while((++a < last) && (0 <= *a));
1242
0
          first = a;
1243
0
        }
1244
0
        if(first < last) {
1245
0
          a = first; do { *a = ~*a; } while(*++a < 0);
1246
0
          next = (ISA[*a] != ISAd[*a]) ? tr_ilg(PTRDIFF_TO_INT(a - first + 1)) : -1;
1247
0
          if(++a < last) { for(b = first, v = PTRDIFF_TO_INT(a - SA - 1); b < a; ++b) { ISA[*b] = v; } }
1248
1249
          /* push */
1250
0
          if(trbudget_check(budget, PTRDIFF_TO_INT(a - first))) {
1251
0
            if((a - first) <= (last - a)) {
1252
0
              STACK_PUSH5(ISAd, a, last, -3, trlink);
1253
0
              ISAd += incr, last = a, limit = next;
1254
0
            } else {
1255
0
              if(1 < (last - a)) {
1256
0
                STACK_PUSH5(ISAd + incr, first, a, next, trlink);
1257
0
                first = a, limit = -3;
1258
0
              } else {
1259
0
                ISAd += incr, last = a, limit = next;
1260
0
              }
1261
0
            }
1262
0
          } else {
1263
0
            if(0 <= trlink) { stack[trlink].d = -1; }
1264
0
            if(1 < (last - a)) {
1265
0
              first = a, limit = -3;
1266
0
            } else {
1267
0
              STACK_POP5(ISAd, first, last, limit, trlink);
1268
0
            }
1269
0
          }
1270
0
        } else {
1271
0
          STACK_POP5(ISAd, first, last, limit, trlink);
1272
0
        }
1273
0
      }
1274
0
      continue;
1275
0
    }
1276
1277
0
    if((last - first) <= TR_INSERTIONSORT_THRESHOLD) {
1278
0
      tr_insertionsort(ISAd, first, last);
1279
0
      limit = -3;
1280
0
      continue;
1281
0
    }
1282
1283
0
    if(limit-- == 0) {
1284
0
      tr_heapsort(ISAd, first, PTRDIFF_TO_INT(last - first));
1285
0
      for(a = last - 1; first < a; a = b) {
1286
0
        for(x = ISAd[*a], b = a - 1; (first <= b) && (ISAd[*b] == x); --b) { *b = ~*b; }
1287
0
      }
1288
0
      limit = -3;
1289
0
      continue;
1290
0
    }
1291
1292
    /* choose pivot */
1293
0
    a = tr_pivot(ISAd, first, last);
1294
0
    SWAP(*first, *a);
1295
0
    v = ISAd[*first];
1296
1297
    /* partition */
1298
0
    tr_partition(ISAd, first, first + 1, last, &a, &b, v);
1299
0
    if((last - first) != (b - a)) {
1300
0
      next = (ISA[*a] != v) ? tr_ilg(PTRDIFF_TO_INT(b - a)) : -1;
1301
1302
      /* update ranks */
1303
0
      for(c = first, v = PTRDIFF_TO_INT(a - SA - 1); c < a; ++c) { ISA[*c] = v; }
1304
0
      if(b < last) { for(c = a, v = PTRDIFF_TO_INT(b - SA - 1); c < b; ++c) { ISA[*c] = v; } }
1305
1306
      /* push */
1307
0
      if((1 < (b - a)) && (trbudget_check(budget, PTRDIFF_TO_INT(b - a)))) {
1308
0
        if((a - first) <= (last - b)) {
1309
0
          if((last - b) <= (b - a)) {
1310
0
            if(1 < (a - first)) {
1311
0
              STACK_PUSH5(ISAd + incr, a, b, next, trlink);
1312
0
              STACK_PUSH5(ISAd, b, last, limit, trlink);
1313
0
              last = a;
1314
0
            } else if(1 < (last - b)) {
1315
0
              STACK_PUSH5(ISAd + incr, a, b, next, trlink);
1316
0
              first = b;
1317
0
            } else {
1318
0
              ISAd += incr, first = a, last = b, limit = next;
1319
0
            }
1320
0
          } else if((a - first) <= (b - a)) {
1321
0
            if(1 < (a - first)) {
1322
0
              STACK_PUSH5(ISAd, b, last, limit, trlink);
1323
0
              STACK_PUSH5(ISAd + incr, a, b, next, trlink);
1324
0
              last = a;
1325
0
            } else {
1326
0
              STACK_PUSH5(ISAd, b, last, limit, trlink);
1327
0
              ISAd += incr, first = a, last = b, limit = next;
1328
0
            }
1329
0
          } else {
1330
0
            STACK_PUSH5(ISAd, b, last, limit, trlink);
1331
0
            STACK_PUSH5(ISAd, first, a, limit, trlink);
1332
0
            ISAd += incr, first = a, last = b, limit = next;
1333
0
          }
1334
0
        } else {
1335
0
          if((a - first) <= (b - a)) {
1336
0
            if(1 < (last - b)) {
1337
0
              STACK_PUSH5(ISAd + incr, a, b, next, trlink);
1338
0
              STACK_PUSH5(ISAd, first, a, limit, trlink);
1339
0
              first = b;
1340
0
            } else if(1 < (a - first)) {
1341
0
              STACK_PUSH5(ISAd + incr, a, b, next, trlink);
1342
0
              last = a;
1343
0
            } else {
1344
0
              ISAd += incr, first = a, last = b, limit = next;
1345
0
            }
1346
0
          } else if((last - b) <= (b - a)) {
1347
0
            if(1 < (last - b)) {
1348
0
              STACK_PUSH5(ISAd, first, a, limit, trlink);
1349
0
              STACK_PUSH5(ISAd + incr, a, b, next, trlink);
1350
0
              first = b;
1351
0
            } else {
1352
0
              STACK_PUSH5(ISAd, first, a, limit, trlink);
1353
0
              ISAd += incr, first = a, last = b, limit = next;
1354
0
            }
1355
0
          } else {
1356
0
            STACK_PUSH5(ISAd, first, a, limit, trlink);
1357
0
            STACK_PUSH5(ISAd, b, last, limit, trlink);
1358
0
            ISAd += incr, first = a, last = b, limit = next;
1359
0
          }
1360
0
        }
1361
0
      } else {
1362
0
        if((1 < (b - a)) && (0 <= trlink)) { stack[trlink].d = -1; }
1363
0
        if((a - first) <= (last - b)) {
1364
0
          if(1 < (a - first)) {
1365
0
            STACK_PUSH5(ISAd, b, last, limit, trlink);
1366
0
            last = a;
1367
0
          } else if(1 < (last - b)) {
1368
0
            first = b;
1369
0
          } else {
1370
0
            STACK_POP5(ISAd, first, last, limit, trlink);
1371
0
          }
1372
0
        } else {
1373
0
          if(1 < (last - b)) {
1374
0
            STACK_PUSH5(ISAd, first, a, limit, trlink);
1375
0
            first = b;
1376
0
          } else if(1 < (a - first)) {
1377
0
            last = a;
1378
0
          } else {
1379
0
            STACK_POP5(ISAd, first, last, limit, trlink);
1380
0
          }
1381
0
        }
1382
0
      }
1383
0
    } else {
1384
0
      if(trbudget_check(budget, PTRDIFF_TO_INT(last - first))) {
1385
0
        limit = tr_ilg(PTRDIFF_TO_INT(last - first)), ISAd += incr;
1386
0
      } else {
1387
0
        if(0 <= trlink) { stack[trlink].d = -1; }
1388
0
        STACK_POP5(ISAd, first, last, limit, trlink);
1389
0
      }
1390
0
    }
1391
0
  }
1392
0
#undef STACK_SIZE
1393
0
}
1394
1395
1396
1397
/*---------------------------------------------------------------------------*/
1398
1399
/* Tandem repeat sort */
1400
static
1401
void
1402
0
trsort(int *ISA, int *SA, int n, int depth) {
1403
0
  int *ISAd;
1404
0
  int *first, *last;
1405
0
  trbudget_t budget;
1406
0
  int t, skip, unsorted;
1407
1408
0
  trbudget_init(&budget, tr_ilg(n) * 2 / 3, n);
1409
/*  trbudget_init(&budget, tr_ilg(n) * 3 / 4, n); */
1410
0
  for(ISAd = ISA + depth; -n < *SA; ISAd += ISAd - ISA) {
1411
0
    first = SA;
1412
0
    skip = 0;
1413
0
    unsorted = 0;
1414
0
    do {
1415
0
      if((t = *first) < 0) { first -= t; skip += t; }
1416
0
      else {
1417
0
        if(skip != 0) { *(first + skip) = skip; skip = 0; }
1418
0
        last = SA + ISA[t] + 1;
1419
0
        if(1 < (last - first)) {
1420
0
          budget.count = 0;
1421
0
          tr_introsort(ISA, ISAd, SA, first, last, &budget);
1422
0
          if(budget.count != 0) { unsorted += budget.count; }
1423
0
          else { skip = PTRDIFF_TO_INT(first - last); }
1424
0
        } else if((last - first) == 1) {
1425
0
          skip = -1;
1426
0
        }
1427
0
        first = last;
1428
0
      }
1429
0
    } while(first < (SA + n));
1430
0
    if(skip != 0) { *(first + skip) = skip; }
1431
0
    if(unsorted == 0) { break; }
1432
0
  }
1433
0
}
1434
1435
1436
/*---------------------------------------------------------------------------*/
1437
1438
/* Sorts suffixes of type B*. */
1439
static
1440
int
1441
sort_typeBstar(const unsigned char *T, int *SA,
1442
               int *bucket_A, int *bucket_B,
1443
0
               int n, int openMP) {
1444
0
  int *PAb, *ISAb, *buf;
1445
#ifdef LIBBSC_OPENMP
1446
  int *curbuf;
1447
  int l;
1448
#endif
1449
0
  int i, j, k, t, m, bufsize;
1450
0
  int c0, c1;
1451
#ifdef LIBBSC_OPENMP
1452
  int d0, d1;
1453
#endif
1454
0
  (void)openMP;
1455
1456
  /* Initialize bucket arrays. */
1457
0
  for(i = 0; i < BUCKET_A_SIZE; ++i) { bucket_A[i] = 0; }
1458
0
  for(i = 0; i < BUCKET_B_SIZE; ++i) { bucket_B[i] = 0; }
1459
1460
  /* Count the number of occurrences of the first one or two characters of each
1461
     type A, B and B* suffix. Moreover, store the beginning position of all
1462
     type B* suffixes into the array SA. */
1463
0
  for(i = n - 1, m = n, c0 = T[n - 1]; 0 <= i;) {
1464
    /* type A suffix. */
1465
0
    do { ++BUCKET_A(c1 = c0); } while((0 <= --i) && ((c0 = T[i]) >= c1));
1466
0
    if(0 <= i) {
1467
      /* type B* suffix. */
1468
0
      ++BUCKET_BSTAR(c0, c1);
1469
0
      SA[--m] = i;
1470
      /* type B suffix. */
1471
0
      for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) <= c1); --i, c1 = c0) {
1472
0
        ++BUCKET_B(c0, c1);
1473
0
      }
1474
0
    }
1475
0
  }
1476
0
  m = n - m;
1477
/*
1478
note:
1479
  A type B* suffix is lexicographically smaller than a type B suffix that
1480
  begins with the same first two characters.
1481
*/
1482
1483
  /* Calculate the index of start/end point of each bucket. */
1484
0
  for(c0 = 0, i = 0, j = 0; c0 < ALPHABET_SIZE; ++c0) {
1485
0
    t = i + BUCKET_A(c0);
1486
0
    BUCKET_A(c0) = i + j; /* start point */
1487
0
    i = t + BUCKET_B(c0, c0);
1488
0
    for(c1 = c0 + 1; c1 < ALPHABET_SIZE; ++c1) {
1489
0
      j += BUCKET_BSTAR(c0, c1);
1490
0
      BUCKET_BSTAR(c0, c1) = j; /* end point */
1491
0
      i += BUCKET_B(c0, c1);
1492
0
    }
1493
0
  }
1494
1495
0
  if(0 < m) {
1496
    /* Sort the type B* suffixes by their first two characters. */
1497
0
    PAb = SA + n - m; ISAb = SA + m;
1498
0
    for(i = m - 2; 0 <= i; --i) {
1499
0
      t = PAb[i], c0 = T[t], c1 = T[t + 1];
1500
0
      SA[--BUCKET_BSTAR(c0, c1)] = i;
1501
0
    }
1502
0
    t = PAb[m - 1], c0 = T[t], c1 = T[t + 1];
1503
0
    SA[--BUCKET_BSTAR(c0, c1)] = m - 1;
1504
1505
    /* Sort the type B* substrings using sssort. */
1506
#ifdef LIBBSC_OPENMP
1507
    if (openMP)
1508
    {
1509
        buf = SA + m;
1510
        c0 = ALPHABET_SIZE - 2, c1 = ALPHABET_SIZE - 1, j = m;
1511
#pragma omp parallel default(shared) private(bufsize, curbuf, k, l, d0, d1)
1512
        {
1513
          bufsize = (n - (2 * m)) / omp_get_num_threads();
1514
          curbuf = buf + omp_get_thread_num() * bufsize;
1515
          k = 0;
1516
          for(;;) {
1517
            #pragma omp critical(sssort_lock)
1518
            {
1519
              if(0 < (l = j)) {
1520
                d0 = c0, d1 = c1;
1521
                do {
1522
                  k = BUCKET_BSTAR(d0, d1);
1523
                  if(--d1 <= d0) {
1524
                    d1 = ALPHABET_SIZE - 1;
1525
                    if(--d0 < 0) { break; }
1526
                  }
1527
                } while(((l - k) <= 1) && (0 < (l = k)));
1528
                c0 = d0, c1 = d1, j = k;
1529
              }
1530
            }
1531
            if(l == 0) { break; }
1532
            sssort(T, PAb, SA + k, SA + l,
1533
                   curbuf, bufsize, 2, n, *(SA + k) == (m - 1));
1534
          }
1535
        }
1536
    }
1537
    else
1538
    {
1539
        buf = SA + m, bufsize = n - (2 * m);
1540
        for(c0 = ALPHABET_SIZE - 2, j = m; 0 < j; --c0) {
1541
          for(c1 = ALPHABET_SIZE - 1; c0 < c1; j = i, --c1) {
1542
            i = BUCKET_BSTAR(c0, c1);
1543
            if(1 < (j - i)) {
1544
              sssort(T, PAb, SA + i, SA + j,
1545
                     buf, bufsize, 2, n, *(SA + i) == (m - 1));
1546
            }
1547
          }
1548
        }
1549
    }
1550
#else
1551
0
    buf = SA + m, bufsize = n - (2 * m);
1552
0
    for(c0 = ALPHABET_SIZE - 2, j = m; 0 < j; --c0) {
1553
0
      for(c1 = ALPHABET_SIZE - 1; c0 < c1; j = i, --c1) {
1554
0
        i = BUCKET_BSTAR(c0, c1);
1555
0
        if(1 < (j - i)) {
1556
0
          sssort(T, PAb, SA + i, SA + j,
1557
0
                 buf, bufsize, 2, n, *(SA + i) == (m - 1));
1558
0
        }
1559
0
      }
1560
0
    }
1561
0
#endif
1562
1563
    /* Compute ranks of type B* substrings. */
1564
0
    for(i = m - 1; 0 <= i; --i) {
1565
0
      if(0 <= SA[i]) {
1566
0
        j = i;
1567
0
        do { ISAb[SA[i]] = i; } while((0 <= --i) && (0 <= SA[i]));
1568
0
        SA[i + 1] = i - j;
1569
0
        if(i <= 0) { break; }
1570
0
      }
1571
0
      j = i;
1572
0
      do { ISAb[SA[i] = ~SA[i]] = j; } while(SA[--i] < 0);
1573
0
      ISAb[SA[i]] = j;
1574
0
    }
1575
1576
    /* Construct the inverse suffix array of type B* suffixes using trsort. */
1577
0
    trsort(ISAb, SA, m, 1);
1578
1579
    /* Set the sorted order of type B* suffixes. */
1580
0
    for(i = n - 1, j = m, c0 = T[n - 1]; 0 <= i;) {
1581
0
      for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) >= c1); --i, c1 = c0) { }
1582
0
      if(0 <= i) {
1583
0
        t = i;
1584
0
        for(--i, c1 = c0; (0 <= i) && ((c0 = T[i]) <= c1); --i, c1 = c0) { }
1585
0
        SA[ISAb[--j]] = ((t == 0) || (1 < (t - i))) ? t : ~t;
1586
0
      }
1587
0
    }
1588
1589
    /* Calculate the index of start/end point of each bucket. */
1590
0
    BUCKET_B(ALPHABET_SIZE - 1, ALPHABET_SIZE - 1) = n; /* end point */
1591
0
    for(c0 = ALPHABET_SIZE - 2, k = m - 1; 0 <= c0; --c0) {
1592
0
      i = BUCKET_A(c0 + 1) - 1;
1593
0
      for(c1 = ALPHABET_SIZE - 1; c0 < c1; --c1) {
1594
0
        t = i - BUCKET_B(c0, c1);
1595
0
        BUCKET_B(c0, c1) = i; /* end point */
1596
1597
        /* Move all type B* suffixes to the correct position. */
1598
0
        for(i = t, j = BUCKET_BSTAR(c0, c1);
1599
0
            j <= k;
1600
0
            --i, --k) { SA[i] = SA[k]; }
1601
0
      }
1602
0
      BUCKET_BSTAR(c0, c0 + 1) = i - BUCKET_B(c0, c0) + 1; /* start point */
1603
0
      BUCKET_B(c0, c0) = i; /* end point */
1604
0
    }
1605
0
  }
1606
1607
0
  return m;
1608
0
}
1609
1610
/* Constructs the suffix array by using the sorted order of type B* suffixes. */
1611
static
1612
void
1613
construct_SA(const unsigned char *T, int *SA,
1614
             int *bucket_A, int *bucket_B,
1615
0
             int n, int m) {
1616
0
  int *i, *j, *k;
1617
0
  int s;
1618
0
  int c0, c1, c2;
1619
1620
0
  if(0 < m) {
1621
    /* Construct the sorted order of type B suffixes by using
1622
       the sorted order of type B* suffixes. */
1623
0
    for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) {
1624
      /* Scan the suffix array from right to left. */
1625
0
      for(i = SA + BUCKET_BSTAR(c1, c1 + 1),
1626
0
          j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1;
1627
0
          i <= j;
1628
0
          --j) {
1629
0
        if(0 < (s = *j)) {
1630
0
          assert(T[s] == c1);
1631
0
          assert(((s + 1) < n) && (T[s] <= T[s + 1]));
1632
0
          assert(T[s - 1] <= T[s]);
1633
0
          *j = ~s;
1634
0
          c0 = T[--s];
1635
0
          if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
1636
0
          if(c0 != c2) {
1637
0
            if(0 <= c2) { BUCKET_B(c2, c1) = PTRDIFF_TO_INT(k - SA); }
1638
0
            k = SA + BUCKET_B(c2 = c0, c1);
1639
0
          }
1640
0
          assert(k < j); assert(k != NULL);
1641
0
          *k-- = s;
1642
0
        } else {
1643
0
          assert(((s == 0) && (T[s] == c1)) || (s < 0));
1644
0
          *j = ~s;
1645
0
        }
1646
0
      }
1647
0
    }
1648
0
  }
1649
1650
  /* Construct the suffix array by using
1651
     the sorted order of type B suffixes. */
1652
0
  k = SA + BUCKET_A(c2 = T[n - 1]);
1653
0
  *k++ = (T[n - 2] < c2) ? ~(n - 1) : (n - 1);
1654
  /* Scan the suffix array from left to right. */
1655
0
  for(i = SA, j = SA + n; i < j; ++i) {
1656
0
    if(0 < (s = *i)) {
1657
0
      assert(T[s - 1] >= T[s]);
1658
0
      c0 = T[--s];
1659
0
      if((s == 0) || (T[s - 1] < c0)) { s = ~s; }
1660
0
      if(c0 != c2) {
1661
0
        BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
1662
0
        k = SA + BUCKET_A(c2 = c0);
1663
0
      }
1664
0
      assert(i < k);
1665
0
      *k++ = s;
1666
0
    } else {
1667
0
      assert(s < 0);
1668
0
      *i = ~s;
1669
0
    }
1670
0
  }
1671
0
}
1672
1673
/* Constructs the burrows-wheeler transformed string directly
1674
   by using the sorted order of type B* suffixes. */
1675
static
1676
int
1677
construct_BWT(const unsigned char *T, int *SA,
1678
              int *bucket_A, int *bucket_B,
1679
0
              int n, int m) {
1680
0
  int *i, *j, *k, *orig;
1681
0
  int s;
1682
0
  int c0, c1, c2;
1683
1684
0
  if(0 < m) {
1685
    /* Construct the sorted order of type B suffixes by using
1686
       the sorted order of type B* suffixes. */
1687
0
    for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) {
1688
      /* Scan the suffix array from right to left. */
1689
0
      for(i = SA + BUCKET_BSTAR(c1, c1 + 1),
1690
0
          j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1;
1691
0
          i <= j;
1692
0
          --j) {
1693
0
        if(0 < (s = *j)) {
1694
0
          assert(T[s] == c1);
1695
0
          assert(((s + 1) < n) && (T[s] <= T[s + 1]));
1696
0
          assert(T[s - 1] <= T[s]);
1697
0
          c0 = T[--s];
1698
0
          *j = ~((int)c0);
1699
0
          if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
1700
0
          if(c0 != c2) {
1701
0
            if(0 <= c2) { BUCKET_B(c2, c1) = PTRDIFF_TO_INT(k - SA); }
1702
0
            k = SA + BUCKET_B(c2 = c0, c1);
1703
0
          }
1704
0
          assert(k < j); assert(k != NULL);
1705
0
          *k-- = s;
1706
0
        } else if(s != 0) {
1707
0
          *j = ~s;
1708
0
#ifndef NDEBUG
1709
0
        } else {
1710
0
          assert(T[s] == c1);
1711
0
#endif
1712
0
        }
1713
0
      }
1714
0
    }
1715
0
  }
1716
1717
  /* Construct the BWTed string by using
1718
     the sorted order of type B suffixes. */
1719
0
  k = SA + BUCKET_A(c2 = T[n - 1]);
1720
0
  *k++ = (T[n - 2] < c2) ? ~((int)T[n - 2]) : (n - 1);
1721
  /* Scan the suffix array from left to right. */
1722
0
  for(i = SA, j = SA + n, orig = SA; i < j; ++i) {
1723
0
    if(0 < (s = *i)) {
1724
0
      assert(T[s - 1] >= T[s]);
1725
0
      c0 = T[--s];
1726
0
      *i = c0;
1727
0
      if((0 < s) && (T[s - 1] < c0)) { s = ~((int)T[s - 1]); }
1728
0
      if(c0 != c2) {
1729
0
        BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
1730
0
        k = SA + BUCKET_A(c2 = c0);
1731
0
      }
1732
0
      assert(i < k);
1733
0
      *k++ = s;
1734
0
    } else if(s != 0) {
1735
0
      *i = ~s;
1736
0
    } else {
1737
0
      orig = i;
1738
0
    }
1739
0
  }
1740
1741
0
  return PTRDIFF_TO_INT(orig - SA);
1742
0
}
1743
1744
/* Constructs the burrows-wheeler transformed string directly
1745
   by using the sorted order of type B* suffixes. */
1746
static
1747
int
1748
construct_BWT_indexes(const unsigned char *T, int *SA,
1749
                      int *bucket_A, int *bucket_B,
1750
                      int n, int m,
1751
0
                      unsigned char * num_indexes, int * indexes) {
1752
0
  int *i, *j, *k, *orig;
1753
0
  int s;
1754
0
  int c0, c1, c2;
1755
1756
0
  int mod = n / 8;
1757
0
  {
1758
0
      mod |= mod >> 1;  mod |= mod >> 2;
1759
0
      mod |= mod >> 4;  mod |= mod >> 8;
1760
0
      mod |= mod >> 16; mod >>= 1;
1761
1762
0
      *num_indexes = (unsigned char)((n - 1) / (mod + 1));
1763
0
  }
1764
1765
0
  if(0 < m) {
1766
    /* Construct the sorted order of type B suffixes by using
1767
       the sorted order of type B* suffixes. */
1768
0
    for(c1 = ALPHABET_SIZE - 2; 0 <= c1; --c1) {
1769
      /* Scan the suffix array from right to left. */
1770
0
      for(i = SA + BUCKET_BSTAR(c1, c1 + 1),
1771
0
          j = SA + BUCKET_A(c1 + 1) - 1, k = NULL, c2 = -1;
1772
0
          i <= j;
1773
0
          --j) {
1774
0
        if(0 < (s = *j)) {
1775
0
          assert(T[s] == c1);
1776
0
          assert(((s + 1) < n) && (T[s] <= T[s + 1]));
1777
0
          assert(T[s - 1] <= T[s]);
1778
1779
0
          if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = PTRDIFF_TO_INT(j - SA);
1780
1781
0
          c0 = T[--s];
1782
0
          *j = ~((int)c0);
1783
0
          if((0 < s) && (T[s - 1] > c0)) { s = ~s; }
1784
0
          if(c0 != c2) {
1785
0
            if(0 <= c2) { BUCKET_B(c2, c1) = PTRDIFF_TO_INT(k - SA); }
1786
0
            k = SA + BUCKET_B(c2 = c0, c1);
1787
0
          }
1788
0
          assert(k < j); assert(k != NULL);
1789
0
          *k-- = s;
1790
0
        } else if(s != 0) {
1791
0
          *j = ~s;
1792
0
#ifndef NDEBUG
1793
0
        } else {
1794
0
          assert(T[s] == c1);
1795
0
#endif
1796
0
        }
1797
0
      }
1798
0
    }
1799
0
  }
1800
1801
  /* Construct the BWTed string by using
1802
     the sorted order of type B suffixes. */
1803
0
  k = SA + BUCKET_A(c2 = T[n - 1]);
1804
0
  if (T[n - 2] < c2) {
1805
0
    if (((n - 1) & mod) == 0) indexes[(n - 1) / (mod + 1) - 1] = PTRDIFF_TO_INT(k - SA);
1806
0
    *k++ = ~((int)T[n - 2]);
1807
0
  }
1808
0
  else {
1809
0
    *k++ = n - 1;
1810
0
  }
1811
1812
  /* Scan the suffix array from left to right. */
1813
0
  for(i = SA, j = SA + n, orig = SA; i < j; ++i) {
1814
0
    if(0 < (s = *i)) {
1815
0
      assert(T[s - 1] >= T[s]);
1816
1817
0
      if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = PTRDIFF_TO_INT(i - SA);
1818
1819
0
      c0 = T[--s];
1820
0
      *i = c0;
1821
0
      if(c0 != c2) {
1822
0
        BUCKET_A(c2) = PTRDIFF_TO_INT(k - SA);
1823
0
        k = SA + BUCKET_A(c2 = c0);
1824
0
      }
1825
0
      assert(i < k);
1826
0
      if((0 < s) && (T[s - 1] < c0)) {
1827
0
          if ((s & mod) == 0) indexes[s / (mod + 1) - 1] = PTRDIFF_TO_INT(k - SA);
1828
0
          *k++ = ~((int)T[s - 1]);
1829
0
      } else
1830
0
        *k++ = s;
1831
0
    } else if(s != 0) {
1832
0
      *i = ~s;
1833
0
    } else {
1834
0
      orig = i;
1835
0
    }
1836
0
  }
1837
1838
0
  return PTRDIFF_TO_INT(orig - SA);
1839
0
}
1840
1841
1842
/*---------------------------------------------------------------------------*/
1843
1844
/*- Function -*/
1845
1846
int
1847
0
divsufsort(const unsigned char *T, int *SA, int n, int openMP) {
1848
0
  int *bucket_A, *bucket_B;
1849
0
  int m;
1850
0
  int err = 0;
1851
1852
  /* Check arguments. */
1853
0
  if((T == NULL) || (SA == NULL) || (n < 0)) { return -1; }
1854
0
  else if(n == 0) { return 0; }
1855
0
  else if(n == 1) { SA[0] = 0; return 0; }
1856
0
  else if(n == 2) { m = (T[0] < T[1]); SA[m ^ 1] = 0, SA[m] = 1; return 0; }
1857
1858
0
  bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int));
1859
0
  bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int));
1860
1861
  /* Suffixsort. */
1862
0
  if((bucket_A != NULL) && (bucket_B != NULL)) {
1863
0
    m = sort_typeBstar(T, SA, bucket_A, bucket_B, n, openMP);
1864
0
    construct_SA(T, SA, bucket_A, bucket_B, n, m);
1865
0
  } else {
1866
0
    err = -2;
1867
0
  }
1868
1869
0
  free(bucket_B);
1870
0
  free(bucket_A);
1871
1872
0
  return err;
1873
0
}
1874
1875
int
1876
0
divbwt(const unsigned char *T, unsigned char *U, int *A, int n, unsigned char * num_indexes, int * indexes, int openMP) {
1877
0
  int *B;
1878
0
  int *bucket_A, *bucket_B;
1879
0
  int m, pidx, i;
1880
1881
  /* Check arguments. */
1882
0
  if((T == NULL) || (U == NULL) || (n < 0)) { return -1; }
1883
0
  else if(n <= 1) { if(n == 1) { U[0] = T[0]; } return n; }
1884
1885
0
  if((B = A) == NULL) { B = (int *)malloc((size_t)(n + 1) * sizeof(int)); }
1886
0
  bucket_A = (int *)malloc(BUCKET_A_SIZE * sizeof(int));
1887
0
  bucket_B = (int *)malloc(BUCKET_B_SIZE * sizeof(int));
1888
1889
  /* Burrows-Wheeler Transform. */
1890
0
  if((B != NULL) && (bucket_A != NULL) && (bucket_B != NULL)) {
1891
0
    m = sort_typeBstar(T, B, bucket_A, bucket_B, n, openMP);
1892
1893
0
    if (num_indexes == NULL || indexes == NULL) {
1894
0
        pidx = construct_BWT(T, B, bucket_A, bucket_B, n, m);
1895
0
    } else {
1896
0
        pidx = construct_BWT_indexes(T, B, bucket_A, bucket_B, n, m, num_indexes, indexes);
1897
0
    }
1898
1899
    /* Copy to output string. */
1900
0
    U[0] = T[n - 1];
1901
0
    for(i = 0; i < pidx; ++i) { U[i + 1] = (unsigned char)B[i]; }
1902
0
    for(i += 1; i < n; ++i) { U[i] = (unsigned char)B[i]; }
1903
0
    pidx += 1;
1904
0
  } else {
1905
0
    pidx = -2;
1906
0
  }
1907
1908
0
  free(bucket_B);
1909
0
  free(bucket_A);
1910
0
  if(A == NULL) { free(B); }
1911
1912
0
  return pidx;
1913
0
}