Coverage Report

Created: 2026-06-07 07:06

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/sentencepiece/third_party/esaxx/sais.hxx
Line
Count
Source
1
/*
2
 * sais.hxx for sais-lite
3
 * Copyright (c) 2008-2009 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
#ifndef _SAIS_HXX
28
#define _SAIS_HXX 1
29
#ifdef __cplusplus
30
31
#ifdef __INTEL_COMPILER
32
#pragma warning(disable : 383 981 1418)
33
// for icc 64-bit
34
//#define __builtin_vsnprintf(a, b, c, d) __builtin_vsnprintf(a, b, c, (char *)d)
35
#endif
36
37
#include <iterator>
38
#ifdef _OPENMP
39
# include <omp.h>
40
#endif
41
42
namespace saisxx_private {
43
44
/* find the start or end of each bucket */
45
template<typename string_type, typename bucket_type, typename index_type>
46
void
47
55.7k
getCounts(const string_type T, bucket_type C, index_type n, index_type k) {
48
#ifdef _OPENMP
49
  bucket_type D;
50
  index_type i, j, p, sum, first, last;
51
  int thnum, maxthreads = omp_get_max_threads();
52
#pragma omp parallel default(shared) private(D, i, thnum, first, last)
53
  {
54
    thnum = omp_get_thread_num();
55
    D = C + thnum * k;
56
    first = n / maxthreads * thnum;
57
    last = (thnum < (maxthreads - 1)) ? n / maxthreads * (thnum + 1) : n;
58
    for(i = 0; i < k; ++i) { D[i] = 0; }
59
    for(i = first; i < last; ++i) { ++D[T[i]]; }
60
  }
61
  if(1 < maxthreads) {
62
#pragma omp parallel for default(shared) private(i, j, p, sum)
63
    for(i = 0; i < k; ++i) {
64
      for(j = 1, p = i + k, sum = C[i]; j < maxthreads; ++j, p += k) {
65
        sum += C[p];
66
      }
67
      C[i] = sum;
68
    }
69
  }
70
#else
71
55.7k
  index_type i;
72
41.3G
  for(i = 0; i < k; ++i) { C[i] = 0; }
73
39.4M
  for(i = 0; i < n; ++i) { ++C[T[i]]; }
74
55.7k
#endif
75
55.7k
}
Unexecuted instantiation: void saisxx_private::getCounts<std::__1::__wrap_iter<unsigned int*>, long*, long>(std::__1::__wrap_iter<unsigned int*>, long*, long, long)
Unexecuted instantiation: void saisxx_private::getCounts<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long, long)
Unexecuted instantiation: void saisxx_private::getCounts<std::__1::__wrap_iter<long*>, long*, long>(std::__1::__wrap_iter<long*>, long*, long, long)
Unexecuted instantiation: void saisxx_private::getCounts<std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, long)
void saisxx_private::getCounts<std::__1::__wrap_iter<unsigned int*>, int*, int>(std::__1::__wrap_iter<unsigned int*>, int*, int, int)
Line
Count
Source
47
37.0k
getCounts(const string_type T, bucket_type C, index_type n, index_type k) {
48
#ifdef _OPENMP
49
  bucket_type D;
50
  index_type i, j, p, sum, first, last;
51
  int thnum, maxthreads = omp_get_max_threads();
52
#pragma omp parallel default(shared) private(D, i, thnum, first, last)
53
  {
54
    thnum = omp_get_thread_num();
55
    D = C + thnum * k;
56
    first = n / maxthreads * thnum;
57
    last = (thnum < (maxthreads - 1)) ? n / maxthreads * (thnum + 1) : n;
58
    for(i = 0; i < k; ++i) { D[i] = 0; }
59
    for(i = first; i < last; ++i) { ++D[T[i]]; }
60
  }
61
  if(1 < maxthreads) {
62
#pragma omp parallel for default(shared) private(i, j, p, sum)
63
    for(i = 0; i < k; ++i) {
64
      for(j = 1, p = i + k, sum = C[i]; j < maxthreads; ++j, p += k) {
65
        sum += C[p];
66
      }
67
      C[i] = sum;
68
    }
69
  }
70
#else
71
37.0k
  index_type i;
72
41.2G
  for(i = 0; i < k; ++i) { C[i] = 0; }
73
34.9M
  for(i = 0; i < n; ++i) { ++C[T[i]]; }
74
37.0k
#endif
75
37.0k
}
Unexecuted instantiation: void saisxx_private::getCounts<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int, int)
void saisxx_private::getCounts<std::__1::__wrap_iter<int*>, int*, int>(std::__1::__wrap_iter<int*>, int*, int, int)
Line
Count
Source
47
1.07k
getCounts(const string_type T, bucket_type C, index_type n, index_type k) {
48
#ifdef _OPENMP
49
  bucket_type D;
50
  index_type i, j, p, sum, first, last;
51
  int thnum, maxthreads = omp_get_max_threads();
52
#pragma omp parallel default(shared) private(D, i, thnum, first, last)
53
  {
54
    thnum = omp_get_thread_num();
55
    D = C + thnum * k;
56
    first = n / maxthreads * thnum;
57
    last = (thnum < (maxthreads - 1)) ? n / maxthreads * (thnum + 1) : n;
58
    for(i = 0; i < k; ++i) { D[i] = 0; }
59
    for(i = first; i < last; ++i) { ++D[T[i]]; }
60
  }
61
  if(1 < maxthreads) {
62
#pragma omp parallel for default(shared) private(i, j, p, sum)
63
    for(i = 0; i < k; ++i) {
64
      for(j = 1, p = i + k, sum = C[i]; j < maxthreads; ++j, p += k) {
65
        sum += C[p];
66
      }
67
      C[i] = sum;
68
    }
69
  }
70
#else
71
1.07k
  index_type i;
72
14.5k
  for(i = 0; i < k; ++i) { C[i] = 0; }
73
164k
  for(i = 0; i < n; ++i) { ++C[T[i]]; }
74
1.07k
#endif
75
1.07k
}
void saisxx_private::getCounts<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, int)
Line
Count
Source
47
17.5k
getCounts(const string_type T, bucket_type C, index_type n, index_type k) {
48
#ifdef _OPENMP
49
  bucket_type D;
50
  index_type i, j, p, sum, first, last;
51
  int thnum, maxthreads = omp_get_max_threads();
52
#pragma omp parallel default(shared) private(D, i, thnum, first, last)
53
  {
54
    thnum = omp_get_thread_num();
55
    D = C + thnum * k;
56
    first = n / maxthreads * thnum;
57
    last = (thnum < (maxthreads - 1)) ? n / maxthreads * (thnum + 1) : n;
58
    for(i = 0; i < k; ++i) { D[i] = 0; }
59
    for(i = first; i < last; ++i) { ++D[T[i]]; }
60
  }
61
  if(1 < maxthreads) {
62
#pragma omp parallel for default(shared) private(i, j, p, sum)
63
    for(i = 0; i < k; ++i) {
64
      for(j = 1, p = i + k, sum = C[i]; j < maxthreads; ++j, p += k) {
65
        sum += C[p];
66
      }
67
      C[i] = sum;
68
    }
69
  }
70
#else
71
17.5k
  index_type i;
72
2.65M
  for(i = 0; i < k; ++i) { C[i] = 0; }
73
4.29M
  for(i = 0; i < n; ++i) { ++C[T[i]]; }
74
17.5k
#endif
75
17.5k
}
76
template<typename bucket_type, typename index_type>
77
void
78
78.1k
getBuckets(const bucket_type C, bucket_type B, index_type k, bool end) {
79
78.1k
  index_type i, sum = 0;
80
27.5G
  if(end) { for(i = 0; i < k; ++i) { sum += C[i]; B[i] = sum; } }
81
13.7G
  else { for(i = 0; i < k; ++i) { sum += C[i]; B[i] = sum - C[i]; } }
82
78.1k
}
Unexecuted instantiation: void saisxx_private::getBuckets<long*, long>(long*, long*, long, bool)
Unexecuted instantiation: void saisxx_private::getBuckets<std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, bool)
void saisxx_private::getBuckets<int*, int>(int*, int*, int, bool)
Line
Count
Source
78
38.1k
getBuckets(const bucket_type C, bucket_type B, index_type k, bool end) {
79
38.1k
  index_type i, sum = 0;
80
27.5G
  if(end) { for(i = 0; i < k; ++i) { sum += C[i]; B[i] = sum; } }
81
13.7G
  else { for(i = 0; i < k; ++i) { sum += C[i]; B[i] = sum - C[i]; } }
82
38.1k
}
void saisxx_private::getBuckets<std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, bool)
Line
Count
Source
78
40.0k
getBuckets(const bucket_type C, bucket_type B, index_type k, bool end) {
79
40.0k
  index_type i, sum = 0;
80
4.37M
  if(end) { for(i = 0; i < k; ++i) { sum += C[i]; B[i] = sum; } }
81
2.18M
  else { for(i = 0; i < k; ++i) { sum += C[i]; B[i] = sum - C[i]; } }
82
40.0k
}
83
84
/* compute SA and BWT */
85
template<typename string_type, typename sarray_type,
86
         typename bucket_type, typename index_type>
87
void
88
induceSA(string_type T, sarray_type SA, bucket_type C, bucket_type B,
89
26.0k
         index_type n, index_type k) {
90
26.0k
typedef typename std::iterator_traits<string_type>::value_type char_type;
91
26.0k
  sarray_type b;
92
26.0k
  index_type i, j;
93
26.0k
  char_type c0, c1;
94
  /* compute SAl */
95
26.0k
  if(C == B) { getCounts(T, C, n, k); }
96
26.0k
  getBuckets(C, B, k, false); /* find starts of buckets */
97
26.0k
  b = SA + B[c1 = T[j = n - 1]];
98
26.0k
  *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
99
15.3M
  for(i = 0; i < n; ++i) {
100
15.3M
    j = SA[i], SA[i] = ~j;
101
15.3M
    if(0 < j) {
102
8.36M
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
103
8.36M
      *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
104
8.36M
    }
105
15.3M
  }
106
  /* compute SAs */
107
26.0k
  if(C == B) { getCounts(T, C, n, k); }
108
26.0k
  getBuckets(C, B, k, true); /* find ends of buckets */
109
15.3M
  for(i = n - 1, b = SA + B[c1 = 0]; 0 <= i; --i) {
110
15.3M
    if(0 < (j = SA[i])) {
111
6.93M
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
112
6.93M
      *--b = ((j == 0) || (T[j - 1] > c1)) ? ~j : j;
113
8.39M
    } else {
114
8.39M
      SA[i] = ~j;
115
8.39M
    }
116
15.3M
  }
117
26.0k
}
Unexecuted instantiation: void saisxx_private::induceSA<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long*, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long*, long*, long, long)
Unexecuted instantiation: void saisxx_private::induceSA<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, long)
Unexecuted instantiation: void saisxx_private::induceSA<std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long*, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long*, long*, long, long)
Unexecuted instantiation: void saisxx_private::induceSA<std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, long)
void saisxx_private::induceSA<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int*, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int*, int*, int, int)
Line
Count
Source
89
12.3k
         index_type n, index_type k) {
90
12.3k
typedef typename std::iterator_traits<string_type>::value_type char_type;
91
12.3k
  sarray_type b;
92
12.3k
  index_type i, j;
93
12.3k
  char_type c0, c1;
94
  /* compute SAl */
95
12.3k
  if(C == B) { getCounts(T, C, n, k); }
96
12.3k
  getBuckets(C, B, k, false); /* find starts of buckets */
97
12.3k
  b = SA + B[c1 = T[j = n - 1]];
98
12.3k
  *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
99
11.6M
  for(i = 0; i < n; ++i) {
100
11.6M
    j = SA[i], SA[i] = ~j;
101
11.6M
    if(0 < j) {
102
6.56M
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
103
6.56M
      *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
104
6.56M
    }
105
11.6M
  }
106
  /* compute SAs */
107
12.3k
  if(C == B) { getCounts(T, C, n, k); }
108
12.3k
  getBuckets(C, B, k, true); /* find ends of buckets */
109
11.6M
  for(i = n - 1, b = SA + B[c1 = 0]; 0 <= i; --i) {
110
11.6M
    if(0 < (j = SA[i])) {
111
5.06M
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
112
5.06M
      *--b = ((j == 0) || (T[j - 1] > c1)) ? ~j : j;
113
6.57M
    } else {
114
6.57M
      SA[i] = ~j;
115
6.57M
    }
116
11.6M
  }
117
12.3k
}
Unexecuted instantiation: void saisxx_private::induceSA<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, int)
void saisxx_private::induceSA<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int*, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int*, int*, int, int)
Line
Count
Source
89
358
         index_type n, index_type k) {
90
358
typedef typename std::iterator_traits<string_type>::value_type char_type;
91
358
  sarray_type b;
92
358
  index_type i, j;
93
358
  char_type c0, c1;
94
  /* compute SAl */
95
358
  if(C == B) { getCounts(T, C, n, k); }
96
358
  getBuckets(C, B, k, false); /* find starts of buckets */
97
358
  b = SA + B[c1 = T[j = n - 1]];
98
358
  *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
99
54.8k
  for(i = 0; i < n; ++i) {
100
54.5k
    j = SA[i], SA[i] = ~j;
101
54.5k
    if(0 < j) {
102
17.5k
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
103
17.5k
      *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
104
17.5k
    }
105
54.5k
  }
106
  /* compute SAs */
107
358
  if(C == B) { getCounts(T, C, n, k); }
108
358
  getBuckets(C, B, k, true); /* find ends of buckets */
109
54.8k
  for(i = n - 1, b = SA + B[c1 = 0]; 0 <= i; --i) {
110
54.5k
    if(0 < (j = SA[i])) {
111
36.6k
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
112
36.6k
      *--b = ((j == 0) || (T[j - 1] > c1)) ? ~j : j;
113
36.6k
    } else {
114
17.8k
      SA[i] = ~j;
115
17.8k
    }
116
54.5k
  }
117
358
}
void saisxx_private::induceSA<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, int)
Line
Count
Source
89
13.3k
         index_type n, index_type k) {
90
13.3k
typedef typename std::iterator_traits<string_type>::value_type char_type;
91
13.3k
  sarray_type b;
92
13.3k
  index_type i, j;
93
13.3k
  char_type c0, c1;
94
  /* compute SAl */
95
13.3k
  if(C == B) { getCounts(T, C, n, k); }
96
13.3k
  getBuckets(C, B, k, false); /* find starts of buckets */
97
13.3k
  b = SA + B[c1 = T[j = n - 1]];
98
13.3k
  *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
99
3.64M
  for(i = 0; i < n; ++i) {
100
3.62M
    j = SA[i], SA[i] = ~j;
101
3.62M
    if(0 < j) {
102
1.78M
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
103
1.78M
      *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
104
1.78M
    }
105
3.62M
  }
106
  /* compute SAs */
107
13.3k
  if(C == B) { getCounts(T, C, n, k); }
108
13.3k
  getBuckets(C, B, k, true); /* find ends of buckets */
109
3.64M
  for(i = n - 1, b = SA + B[c1 = 0]; 0 <= i; --i) {
110
3.62M
    if(0 < (j = SA[i])) {
111
1.83M
      if((c0 = T[--j]) != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
112
1.83M
      *--b = ((j == 0) || (T[j - 1] > c1)) ? ~j : j;
113
1.83M
    } else {
114
1.79M
      SA[i] = ~j;
115
1.79M
    }
116
3.62M
  }
117
13.3k
}
118
template<typename string_type, typename sarray_type,
119
         typename bucket_type, typename index_type>
120
int
121
computeBWT(string_type T, sarray_type SA, bucket_type C, bucket_type B,
122
0
           index_type n, index_type k) {
123
0
typedef typename std::iterator_traits<string_type>::value_type char_type;
124
0
  sarray_type b;
125
0
  index_type i, j, pidx = -1;
126
0
  char_type c0, c1;
127
  /* compute SAl */
128
0
  if(C == B) { getCounts(T, C, n, k); }
129
0
  getBuckets(C, B, k, false); /* find starts of buckets */
130
0
  b = SA + B[c1 = T[j = n - 1]];
131
0
  *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
132
0
  for(i = 0; i < n; ++i) {
133
0
    if(0 < (j = SA[i])) {
134
0
      SA[i] = ~(c0 = T[--j]);
135
0
      if(c0 != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
136
0
      *b++ = ((0 < j) && (T[j - 1] < c1)) ? ~j : j;
137
0
    } else if(j != 0) {
138
0
      SA[i] = ~j;
139
0
    }
140
0
  }
141
  /* compute SAs */
142
0
  if(C == B) { getCounts(T, C, n, k); }
143
0
  getBuckets(C, B, k, true); /* find ends of buckets */
144
0
  for(i = n - 1, b = SA + B[c1 = 0]; 0 <= i; --i) {
145
0
    if(0 < (j = SA[i])) {
146
0
      SA[i] = (c0 = T[--j]);
147
0
      if(c0 != c1) { B[c1] = b - SA; b = SA + B[c1 = c0]; }
148
0
      *--b = ((0 < j) && (T[j - 1] > c1)) ? ~((index_type)T[j - 1]) : j;
149
0
    } else if(j != 0) {
150
0
      SA[i] = ~j;
151
0
    } else {
152
0
      pidx = i;
153
0
    }
154
0
  }
155
0
  return pidx;
156
0
}
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long*, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long*, long*, long, long)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, long)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long*, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long*, long*, long, long)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, long)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int*, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int*, int*, int, int)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, int)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int*, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int*, int*, int, int)
Unexecuted instantiation: int saisxx_private::computeBWT<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, int)
157
158
/* find the suffix array SA of T[0..n-1] in {0..k}^n
159
   use a working space (excluding s and SA) of at most 2n+O(1) for a constant alphabet */
160
template<typename string_type, typename sarray_type, typename index_type>
161
int
162
suffixsort(string_type T, sarray_type SA,
163
           index_type fs, index_type n, index_type k,
164
13.0k
           bool isbwt) {
165
13.0k
typedef typename std::iterator_traits<string_type>::value_type char_type;
166
13.0k
  sarray_type RA;
167
13.0k
  index_type i, j, m, p, q, plen, qlen, name;
168
13.0k
  int pidx = 0;
169
13.0k
  bool diff;
170
13.0k
  int c;
171
#ifdef _OPENMP
172
  int maxthreads = omp_get_max_threads();
173
#else
174
64.8k
# define maxthreads 1
175
13.0k
#endif
176
13.0k
  char_type c0, c1;
177
178
  /* stage 1: reduce the problem by at least 1/2
179
     sort all the S-substrings */
180
13.0k
  if(fs < (maxthreads * k)) {
181
6.35k
    index_type *C, *B;
182
6.35k
    C = new index_type[maxthreads * k];
183
6.35k
    B = (1 < maxthreads) ? C + k : C;
184
6.35k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
185
#ifdef _OPENMP
186
#pragma omp parallel for default(shared) private(i)
187
#endif
188
5.85M
    for(i = 0; i < n; ++i) { SA[i] = 0; }
189
5.84M
    for(i = n - 2, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
190
5.84M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
191
3.29M
      else if(c != 0) { SA[--B[c1]] = i + 1, c = 0; }
192
5.84M
    }
193
6.35k
    induceSA(T, SA, C, B, n, k);
194
6.35k
    delete [] C;
195
6.67k
  } else {
196
6.67k
    sarray_type C, B;
197
6.67k
    C = SA + n;
198
6.67k
    B = ((1 < maxthreads) || (k <= (fs - k))) ? C + k : C;
199
6.67k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
200
#ifdef _OPENMP
201
#pragma omp parallel for default(shared) private(i)
202
#endif
203
1.82M
    for(i = 0; i < n; ++i) { SA[i] = 0; }
204
1.81M
    for(i = n - 2, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
205
1.80M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
206
891k
      else if(c != 0) { SA[--B[c1]] = i + 1, c = 0; }
207
1.80M
    }
208
6.67k
    induceSA(T, SA, C, B, n, k);
209
6.67k
  }
210
211
  /* compact all the sorted substrings into the first m items of SA
212
     2*m must be not larger than n (proveable) */
213
#ifdef _OPENMP
214
#pragma omp parallel for default(shared) private(i, j, p, c0, c1)
215
  for(i = 0; i < n; ++i) {
216
    p = SA[i];
217
    if((0 < p) && (T[p - 1] > (c0 = T[p]))) {
218
      for(j = p + 1; (j < n) && (c0 == (c1 = T[j])); ++j) { }
219
      if((j < n) && (c0 < c1)) { SA[i] = ~p; }
220
    }
221
  }
222
  for(i = 0, m = 0; i < n; ++i) { if((p = SA[i]) < 0) { SA[m++] = ~p; } }
223
#else
224
7.67M
  for(i = 0, m = 0; i < n; ++i) {
225
7.66M
    p = SA[i];
226
7.66M
    if((0 < p) && (T[p - 1] > (c0 = T[p]))) {
227
3.62M
      for(j = p + 1; (j < n) && (c0 == (c1 = T[j])); ++j) { }
228
2.78M
      if((j < n) && (c0 < c1)) { SA[m++] = p; }
229
2.78M
    }
230
7.66M
  }
231
13.0k
#endif
232
13.0k
  j = m + (n >> 1);
233
#ifdef _OPENMP
234
#pragma omp parallel for default(shared) private(i)
235
#endif
236
3.84M
  for(i = m; i < j; ++i) { SA[i] = 0; } /* init the name array buffer */
237
  /* store the length of all substrings */
238
7.66M
  for(i = n - 2, j = n, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
239
7.64M
    if((c0 = T[i]) < (c1 + c)) { c = 1; }
240
4.18M
    else if(c != 0) { SA[m + ((i + 1) >> 1)] = j - i - 1; j = i + 1; c = 0; }
241
7.64M
  }
242
  /* find the lexicographic names of all substrings */
243
1.98M
  for(i = 0, name = 0, q = n, qlen = 0; i < m; ++i) {
244
1.97M
    p = SA[i], plen = SA[m + (p >> 1)], diff = true;
245
1.97M
    if(plen == qlen) {
246
3.79M
      for(j = 0; (j < plen) && (T[p + j] == T[q + j]); ++j) { }
247
1.01M
      if(j == plen) { diff = false; }
248
1.01M
    }
249
1.97M
    if(diff != false) { ++name, q = p, qlen = plen; }
250
1.97M
    SA[m + (p >> 1)] = name;
251
1.97M
  }
252
253
  /* stage 2: solve the reduced problem
254
     recurse if names are not yet unique */
255
13.0k
  if(name < m) {
256
6.85k
    RA = SA + n + fs - m;
257
3.58M
    for(i = m + (n >> 1) - 1, j = m - 1; m <= i; --i) {
258
3.57M
      if(SA[i] != 0) { RA[j--] = SA[i] - 1; }
259
3.57M
    }
260
6.85k
    if(suffixsort(RA, SA, fs + n - m * 2, m, name, false) != 0) { return -2; }
261
7.15M
    for(i = n - 2, j = m - 1, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
262
7.14M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
263
3.91M
      else if(c != 0) { RA[j--] = i + 1, c = 0; } /* get p1 */
264
7.14M
    }
265
#ifdef _OPENMP
266
#pragma omp parallel for default(shared) private(i)
267
#endif
268
1.84M
    for(i = 0; i < m; ++i) { SA[i] = RA[SA[i]]; } /* get index in s */
269
6.85k
  }
270
271
  /* stage 3: induce the result for the original problem */
272
13.0k
  if(fs < (maxthreads * k)) {
273
6.35k
    index_type *B, *C;
274
6.35k
    C = new index_type[maxthreads * k];
275
6.35k
    B = (1 < maxthreads) ? C + k : C;
276
    /* put all left-most S characters into their buckets */
277
6.35k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
278
#ifdef _OPENMP
279
#pragma omp parallel for default(shared) private(i)
280
#endif
281
4.44M
    for(i = m; i < n; ++i) { SA[i] = 0; } /* init SA[m..n-1] */
282
1.41M
    for(i = m - 1; 0 <= i; --i) {
283
1.41M
      j = SA[i], SA[i] = 0;
284
1.41M
      SA[--B[T[j]]] = j;
285
1.41M
    }
286
6.35k
    if(isbwt == false) { induceSA(T, SA, C, B, n, k); }
287
0
    else { pidx = computeBWT(T, SA, C, B, n, k); }
288
6.35k
    delete [] C;
289
6.67k
  } else {
290
6.67k
    sarray_type C, B;
291
6.67k
    C = SA + n;
292
6.67k
    B = ((1 < maxthreads) || (k <= (fs - k))) ? C + k : C;
293
    /* put all left-most S characters into their buckets */
294
6.67k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
295
#ifdef _OPENMP
296
#pragma omp parallel for default(shared) private(i)
297
#endif
298
1.25M
    for(i = m; i < n; ++i) { SA[i] = 0; } /* init SA[m..n-1] */
299
573k
    for(i = m - 1; 0 <= i; --i) {
300
566k
      j = SA[i], SA[i] = 0;
301
566k
      SA[--B[T[j]]] = j;
302
566k
    }
303
6.67k
    if(isbwt == false) { induceSA(T, SA, C, B, n, k); }
304
0
    else { pidx = computeBWT(T, SA, C, B, n, k); }
305
6.67k
  }
306
307
13.0k
  return pidx;
308
13.0k
#ifndef _OPENMP
309
13.0k
# undef maxthreads
310
13.0k
#endif
311
13.0k
}
Unexecuted instantiation: int saisxx_private::suffixsort<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long, long, long, bool)
Unexecuted instantiation: int saisxx_private::suffixsort<std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<long*>, std::__1::__wrap_iter<long*>, long, long, long, bool)
int saisxx_private::suffixsort<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int, int, int, bool)
Line
Count
Source
164
6.17k
           bool isbwt) {
165
6.17k
typedef typename std::iterator_traits<string_type>::value_type char_type;
166
6.17k
  sarray_type RA;
167
6.17k
  index_type i, j, m, p, q, plen, qlen, name;
168
6.17k
  int pidx = 0;
169
6.17k
  bool diff;
170
6.17k
  int c;
171
#ifdef _OPENMP
172
  int maxthreads = omp_get_max_threads();
173
#else
174
6.17k
# define maxthreads 1
175
6.17k
#endif
176
6.17k
  char_type c0, c1;
177
178
  /* stage 1: reduce the problem by at least 1/2
179
     sort all the S-substrings */
180
6.17k
  if(fs < (maxthreads * k)) {
181
6.17k
    index_type *C, *B;
182
6.17k
    C = new index_type[maxthreads * k];
183
6.17k
    B = (1 < maxthreads) ? C + k : C;
184
6.17k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
185
#ifdef _OPENMP
186
#pragma omp parallel for default(shared) private(i)
187
#endif
188
5.82M
    for(i = 0; i < n; ++i) { SA[i] = 0; }
189
5.82M
    for(i = n - 2, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
190
5.81M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
191
3.28M
      else if(c != 0) { SA[--B[c1]] = i + 1, c = 0; }
192
5.81M
    }
193
6.17k
    induceSA(T, SA, C, B, n, k);
194
6.17k
    delete [] C;
195
6.17k
  } else {
196
0
    sarray_type C, B;
197
0
    C = SA + n;
198
0
    B = ((1 < maxthreads) || (k <= (fs - k))) ? C + k : C;
199
0
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
200
#ifdef _OPENMP
201
#pragma omp parallel for default(shared) private(i)
202
#endif
203
0
    for(i = 0; i < n; ++i) { SA[i] = 0; }
204
0
    for(i = n - 2, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
205
0
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
206
0
      else if(c != 0) { SA[--B[c1]] = i + 1, c = 0; }
207
0
    }
208
0
    induceSA(T, SA, C, B, n, k);
209
0
  }
210
211
  /* compact all the sorted substrings into the first m items of SA
212
     2*m must be not larger than n (proveable) */
213
#ifdef _OPENMP
214
#pragma omp parallel for default(shared) private(i, j, p, c0, c1)
215
  for(i = 0; i < n; ++i) {
216
    p = SA[i];
217
    if((0 < p) && (T[p - 1] > (c0 = T[p]))) {
218
      for(j = p + 1; (j < n) && (c0 == (c1 = T[j])); ++j) { }
219
      if((j < n) && (c0 < c1)) { SA[i] = ~p; }
220
    }
221
  }
222
  for(i = 0, m = 0; i < n; ++i) { if((p = SA[i]) < 0) { SA[m++] = ~p; } }
223
#else
224
5.82M
  for(i = 0, m = 0; i < n; ++i) {
225
5.82M
    p = SA[i];
226
5.82M
    if((0 < p) && (T[p - 1] > (c0 = T[p]))) {
227
2.69M
      for(j = p + 1; (j < n) && (c0 == (c1 = T[j])); ++j) { }
228
1.91M
      if((j < n) && (c0 < c1)) { SA[m++] = p; }
229
1.91M
    }
230
5.82M
  }
231
6.17k
#endif
232
6.17k
  j = m + (n >> 1);
233
#ifdef _OPENMP
234
#pragma omp parallel for default(shared) private(i)
235
#endif
236
2.91M
  for(i = m; i < j; ++i) { SA[i] = 0; } /* init the name array buffer */
237
  /* store the length of all substrings */
238
5.82M
  for(i = n - 2, j = n, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
239
5.81M
    if((c0 = T[i]) < (c1 + c)) { c = 1; }
240
3.28M
    else if(c != 0) { SA[m + ((i + 1) >> 1)] = j - i - 1; j = i + 1; c = 0; }
241
5.81M
  }
242
  /* find the lexicographic names of all substrings */
243
1.41M
  for(i = 0, name = 0, q = n, qlen = 0; i < m; ++i) {
244
1.40M
    p = SA[i], plen = SA[m + (p >> 1)], diff = true;
245
1.40M
    if(plen == qlen) {
246
3.26M
      for(j = 0; (j < plen) && (T[p + j] == T[q + j]); ++j) { }
247
792k
      if(j == plen) { diff = false; }
248
792k
    }
249
1.40M
    if(diff != false) { ++name, q = p, qlen = plen; }
250
1.40M
    SA[m + (p >> 1)] = name;
251
1.40M
  }
252
253
  /* stage 2: solve the reduced problem
254
     recurse if names are not yet unique */
255
6.17k
  if(name < m) {
256
3.80k
    RA = SA + n + fs - m;
257
2.84M
    for(i = m + (n >> 1) - 1, j = m - 1; m <= i; --i) {
258
2.84M
      if(SA[i] != 0) { RA[j--] = SA[i] - 1; }
259
2.84M
    }
260
3.80k
    if(suffixsort(RA, SA, fs + n - m * 2, m, name, false) != 0) { return -2; }
261
5.68M
    for(i = n - 2, j = m - 1, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
262
5.67M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
263
3.19M
      else if(c != 0) { RA[j--] = i + 1, c = 0; } /* get p1 */
264
5.67M
    }
265
#ifdef _OPENMP
266
#pragma omp parallel for default(shared) private(i)
267
#endif
268
1.38M
    for(i = 0; i < m; ++i) { SA[i] = RA[SA[i]]; } /* get index in s */
269
3.80k
  }
270
271
  /* stage 3: induce the result for the original problem */
272
6.17k
  if(fs < (maxthreads * k)) {
273
6.17k
    index_type *B, *C;
274
6.17k
    C = new index_type[maxthreads * k];
275
6.17k
    B = (1 < maxthreads) ? C + k : C;
276
    /* put all left-most S characters into their buckets */
277
6.17k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
278
#ifdef _OPENMP
279
#pragma omp parallel for default(shared) private(i)
280
#endif
281
4.42M
    for(i = m; i < n; ++i) { SA[i] = 0; } /* init SA[m..n-1] */
282
1.41M
    for(i = m - 1; 0 <= i; --i) {
283
1.40M
      j = SA[i], SA[i] = 0;
284
1.40M
      SA[--B[T[j]]] = j;
285
1.40M
    }
286
6.17k
    if(isbwt == false) { induceSA(T, SA, C, B, n, k); }
287
0
    else { pidx = computeBWT(T, SA, C, B, n, k); }
288
6.17k
    delete [] C;
289
6.17k
  } else {
290
0
    sarray_type C, B;
291
0
    C = SA + n;
292
0
    B = ((1 < maxthreads) || (k <= (fs - k))) ? C + k : C;
293
    /* put all left-most S characters into their buckets */
294
0
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
295
#ifdef _OPENMP
296
#pragma omp parallel for default(shared) private(i)
297
#endif
298
0
    for(i = m; i < n; ++i) { SA[i] = 0; } /* init SA[m..n-1] */
299
0
    for(i = m - 1; 0 <= i; --i) {
300
0
      j = SA[i], SA[i] = 0;
301
0
      SA[--B[T[j]]] = j;
302
0
    }
303
0
    if(isbwt == false) { induceSA(T, SA, C, B, n, k); }
304
0
    else { pidx = computeBWT(T, SA, C, B, n, k); }
305
0
  }
306
307
6.17k
  return pidx;
308
6.17k
#ifndef _OPENMP
309
6.17k
# undef maxthreads
310
6.17k
#endif
311
6.17k
}
int saisxx_private::suffixsort<std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<int*>, std::__1::__wrap_iter<int*>, int, int, int, bool)
Line
Count
Source
164
6.85k
           bool isbwt) {
165
6.85k
typedef typename std::iterator_traits<string_type>::value_type char_type;
166
6.85k
  sarray_type RA;
167
6.85k
  index_type i, j, m, p, q, plen, qlen, name;
168
6.85k
  int pidx = 0;
169
6.85k
  bool diff;
170
6.85k
  int c;
171
#ifdef _OPENMP
172
  int maxthreads = omp_get_max_threads();
173
#else
174
6.85k
# define maxthreads 1
175
6.85k
#endif
176
6.85k
  char_type c0, c1;
177
178
  /* stage 1: reduce the problem by at least 1/2
179
     sort all the S-substrings */
180
6.85k
  if(fs < (maxthreads * k)) {
181
179
    index_type *C, *B;
182
179
    C = new index_type[maxthreads * k];
183
179
    B = (1 < maxthreads) ? C + k : C;
184
179
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
185
#ifdef _OPENMP
186
#pragma omp parallel for default(shared) private(i)
187
#endif
188
27.4k
    for(i = 0; i < n; ++i) { SA[i] = 0; }
189
27.2k
    for(i = n - 2, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
190
27.0k
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
191
8.76k
      else if(c != 0) { SA[--B[c1]] = i + 1, c = 0; }
192
27.0k
    }
193
179
    induceSA(T, SA, C, B, n, k);
194
179
    delete [] C;
195
6.67k
  } else {
196
6.67k
    sarray_type C, B;
197
6.67k
    C = SA + n;
198
6.67k
    B = ((1 < maxthreads) || (k <= (fs - k))) ? C + k : C;
199
6.67k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
200
#ifdef _OPENMP
201
#pragma omp parallel for default(shared) private(i)
202
#endif
203
1.82M
    for(i = 0; i < n; ++i) { SA[i] = 0; }
204
1.81M
    for(i = n - 2, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
205
1.80M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
206
891k
      else if(c != 0) { SA[--B[c1]] = i + 1, c = 0; }
207
1.80M
    }
208
6.67k
    induceSA(T, SA, C, B, n, k);
209
6.67k
  }
210
211
  /* compact all the sorted substrings into the first m items of SA
212
     2*m must be not larger than n (proveable) */
213
#ifdef _OPENMP
214
#pragma omp parallel for default(shared) private(i, j, p, c0, c1)
215
  for(i = 0; i < n; ++i) {
216
    p = SA[i];
217
    if((0 < p) && (T[p - 1] > (c0 = T[p]))) {
218
      for(j = p + 1; (j < n) && (c0 == (c1 = T[j])); ++j) { }
219
      if((j < n) && (c0 < c1)) { SA[i] = ~p; }
220
    }
221
  }
222
  for(i = 0, m = 0; i < n; ++i) { if((p = SA[i]) < 0) { SA[m++] = ~p; } }
223
#else
224
1.84M
  for(i = 0, m = 0; i < n; ++i) {
225
1.84M
    p = SA[i];
226
1.84M
    if((0 < p) && (T[p - 1] > (c0 = T[p]))) {
227
930k
      for(j = p + 1; (j < n) && (c0 == (c1 = T[j])); ++j) { }
228
876k
      if((j < n) && (c0 < c1)) { SA[m++] = p; }
229
876k
    }
230
1.84M
  }
231
6.85k
#endif
232
6.85k
  j = m + (n >> 1);
233
#ifdef _OPENMP
234
#pragma omp parallel for default(shared) private(i)
235
#endif
236
925k
  for(i = m; i < j; ++i) { SA[i] = 0; } /* init the name array buffer */
237
  /* store the length of all substrings */
238
1.84M
  for(i = n - 2, j = n, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
239
1.83M
    if((c0 = T[i]) < (c1 + c)) { c = 1; }
240
899k
    else if(c != 0) { SA[m + ((i + 1) >> 1)] = j - i - 1; j = i + 1; c = 0; }
241
1.83M
  }
242
  /* find the lexicographic names of all substrings */
243
577k
  for(i = 0, name = 0, q = n, qlen = 0; i < m; ++i) {
244
571k
    p = SA[i], plen = SA[m + (p >> 1)], diff = true;
245
571k
    if(plen == qlen) {
246
526k
      for(j = 0; (j < plen) && (T[p + j] == T[q + j]); ++j) { }
247
224k
      if(j == plen) { diff = false; }
248
224k
    }
249
571k
    if(diff != false) { ++name, q = p, qlen = plen; }
250
571k
    SA[m + (p >> 1)] = name;
251
571k
  }
252
253
  /* stage 2: solve the reduced problem
254
     recurse if names are not yet unique */
255
6.85k
  if(name < m) {
256
3.04k
    RA = SA + n + fs - m;
257
735k
    for(i = m + (n >> 1) - 1, j = m - 1; m <= i; --i) {
258
732k
      if(SA[i] != 0) { RA[j--] = SA[i] - 1; }
259
732k
    }
260
3.04k
    if(suffixsort(RA, SA, fs + n - m * 2, m, name, false) != 0) { return -2; }
261
1.46M
    for(i = n - 2, j = m - 1, c = 0, c1 = T[n - 1]; 0 <= i; --i, c1 = c0) {
262
1.46M
      if((c0 = T[i]) < (c1 + c)) { c = 1; }
263
715k
      else if(c != 0) { RA[j--] = i + 1, c = 0; } /* get p1 */
264
1.46M
    }
265
#ifdef _OPENMP
266
#pragma omp parallel for default(shared) private(i)
267
#endif
268
458k
    for(i = 0; i < m; ++i) { SA[i] = RA[SA[i]]; } /* get index in s */
269
3.04k
  }
270
271
  /* stage 3: induce the result for the original problem */
272
6.85k
  if(fs < (maxthreads * k)) {
273
179
    index_type *B, *C;
274
179
    C = new index_type[maxthreads * k];
275
179
    B = (1 < maxthreads) ? C + k : C;
276
    /* put all left-most S characters into their buckets */
277
179
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
278
#ifdef _OPENMP
279
#pragma omp parallel for default(shared) private(i)
280
#endif
281
22.8k
    for(i = m; i < n; ++i) { SA[i] = 0; } /* init SA[m..n-1] */
282
4.72k
    for(i = m - 1; 0 <= i; --i) {
283
4.55k
      j = SA[i], SA[i] = 0;
284
4.55k
      SA[--B[T[j]]] = j;
285
4.55k
    }
286
179
    if(isbwt == false) { induceSA(T, SA, C, B, n, k); }
287
0
    else { pidx = computeBWT(T, SA, C, B, n, k); }
288
179
    delete [] C;
289
6.67k
  } else {
290
6.67k
    sarray_type C, B;
291
6.67k
    C = SA + n;
292
6.67k
    B = ((1 < maxthreads) || (k <= (fs - k))) ? C + k : C;
293
    /* put all left-most S characters into their buckets */
294
6.67k
    getCounts(T, C, n, k); getBuckets(C, B, k, true); /* find ends of buckets */
295
#ifdef _OPENMP
296
#pragma omp parallel for default(shared) private(i)
297
#endif
298
1.25M
    for(i = m; i < n; ++i) { SA[i] = 0; } /* init SA[m..n-1] */
299
573k
    for(i = m - 1; 0 <= i; --i) {
300
566k
      j = SA[i], SA[i] = 0;
301
566k
      SA[--B[T[j]]] = j;
302
566k
    }
303
6.67k
    if(isbwt == false) { induceSA(T, SA, C, B, n, k); }
304
0
    else { pidx = computeBWT(T, SA, C, B, n, k); }
305
6.67k
  }
306
307
6.85k
  return pidx;
308
6.85k
#ifndef _OPENMP
309
6.85k
# undef maxthreads
310
6.85k
#endif
311
6.85k
}
312
313
} /* namespace saisxx_private */
314
315
316
/**
317
 * @brief Constructs the suffix array of a given string in linear time.
318
 * @param T[0..n-1] The input string. (random access iterator)
319
 * @param SA[0..n-1] The output array of suffixes. (random access iterator)
320
 * @param n The length of the given string.
321
 * @param k The alphabet size.
322
 * @return 0 if no error occurred, -1 or -2 otherwise.
323
 */
324
template<typename string_type, typename sarray_type, typename index_type>
325
int
326
6.17k
saisxx(string_type T, sarray_type SA, index_type n, index_type k = 256) {
327
6.17k
  int err;
328
6.17k
  if((n < 0) || (k <= 0)) { return -1; }
329
6.17k
  if(n <= 1) { if(n == 1) { SA[0] = 0; } return 0; }
330
6.17k
  try { err = saisxx_private::suffixsort(T, SA, index_type(0), n, k, false); }
331
6.17k
  catch(...) { err = -2; }
332
6.17k
  return err;
333
6.17k
}
Unexecuted instantiation: int saisxx<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<long*>, long, long)
int saisxx<std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int>(std::__1::__wrap_iter<unsigned int*>, std::__1::__wrap_iter<int*>, int, int)
Line
Count
Source
326
6.17k
saisxx(string_type T, sarray_type SA, index_type n, index_type k = 256) {
327
6.17k
  int err;
328
6.17k
  if((n < 0) || (k <= 0)) { return -1; }
329
6.17k
  if(n <= 1) { if(n == 1) { SA[0] = 0; } return 0; }
330
6.17k
  try { err = saisxx_private::suffixsort(T, SA, index_type(0), n, k, false); }
331
6.17k
  catch(...) { err = -2; }
332
6.17k
  return err;
333
6.17k
}
334
335
/**
336
 * @brief Constructs the burrows-wheeler transformed string of a given string in linear time.
337
 * @param T[0..n-1] The input string. (random access iterator)
338
 * @param U[0..n-1] The output string. (random access iterator)
339
 * @param A[0..n-1] The temporary array. (random access iterator)
340
 * @param n The length of the given string.
341
 * @param k The alphabet size.
342
 * @return The primary index if no error occurred, -1 or -2 otherwise.
343
 */
344
template<typename string_type, typename sarray_type, typename index_type>
345
index_type
346
saisxx_bwt(string_type T, string_type U, sarray_type A, index_type n, index_type k = 256) {
347
typedef typename std::iterator_traits<string_type>::value_type char_type;
348
  index_type i, pidx;
349
  if((n < 0) || (k <= 0)) { return -1; }
350
  if(n <= 1) { if(n == 1) { U[0] = T[0]; } return n; }
351
  try {
352
    pidx = saisxx_private::suffixsort(T, A, 0, n, k, true);
353
    if(0 <= pidx) {
354
      U[0] = T[n - 1];
355
      for(i = 0; i < pidx; ++i) { U[i + 1] = (char_type)A[i]; }
356
      for(i += 1; i < n; ++i) { U[i] = (char_type)A[i]; }
357
      pidx += 1;
358
    }
359
  } catch(...) { pidx = -2; }
360
  return pidx;
361
}
362
363
364
#endif /* __cplusplus */
365
#endif /* _SAIS_HXX */