Showing preview only (1,671K chars total). Download the full file or copy to clipboard to get everything.
Repository: IlyaGrebnov/libsais
Branch: master
Commit: b6e52ef33fe1
Files: 14
Total size: 1.6 MB
Directory structure:
gitextract__tus48nc/
├── Benchmarks.md
├── CHANGES
├── CMakeLists.txt
├── LICENSE
├── README.md
├── VERSION
├── include/
│ ├── libsais.h
│ ├── libsais16.h
│ ├── libsais16x64.h
│ └── libsais64.h
└── src/
├── libsais.c
├── libsais16.c
├── libsais16x64.c
└── libsais64.c
================================================
FILE CONTENTS
================================================
================================================
FILE: Benchmarks.md
================================================
# Specifications
* OS: Windows 11 Pro (64-bit)
* CPU: AMD Ryzen 9 9950X3D (16C / 32T, 128MB L3 cache, PBO +200Mhz, CO -10 all-core)
* RAM: 2 x 48 GB DDR5-6000 (28-36-36-60)
* Compiler: clang 19.1.5 '-O3 -march=znver5 -fopenmp -DLIBSAIS_OPENMP -DNDEBUG'
The times reflect the median of 15 runs for suffix array construction, reported in both **single-threaded (ST)** and **multi-threaded (MT)** modes. For optimal performance, libsais was limited to 12 threads, while divsufsort was limited to 16 threads.
### [Silesia Corpus](https://www.data-compression.info/Corpora/SilesiaCorpus/index.html) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| dickens | 10192446 | 0.108 sec ( 94.52 MB/s) | 0.297 sec ( 34.33 MB/s) |**+175.35%**| 0.059 sec ( 173.57 MB/s) | 0.195 sec ( 52.21 MB/s) |**+232.45%**|
| mozilla | 51220480 | 0.542 sec ( 94.55 MB/s) | 1.163 sec ( 44.04 MB/s) |**+114.70%**| 0.318 sec ( 161.13 MB/s) | 0.725 sec ( 70.69 MB/s) |**+127.94%**|
| mr | 9970564 | 0.095 sec ( 104.55 MB/s) | 0.239 sec ( 41.66 MB/s) |**+150.96%**| 0.069 sec ( 145.10 MB/s) | 0.163 sec ( 61.28 MB/s) |**+136.81%**|
| nci | 33553445 | 0.274 sec ( 122.48 MB/s) | 0.682 sec ( 49.20 MB/s) |**+148.97%**| 0.142 sec ( 235.87 MB/s) | 0.605 sec ( 55.43 MB/s) |**+325.56%**|
| ooffice | 6152192 | 0.072 sec ( 85.36 MB/s) | 0.130 sec ( 47.18 MB/s) | **+80.94%**| 0.052 sec ( 119.34 MB/s) | 0.081 sec ( 76.34 MB/s) | **+56.32%**|
| osdb | 10085684 | 0.110 sec ( 91.44 MB/s) | 0.214 sec ( 47.04 MB/s) | **+94.40%**| 0.073 sec ( 138.57 MB/s) | 0.168 sec ( 60.01 MB/s) |**+130.91%**|
| reymont | 6627202 | 0.069 sec ( 95.98 MB/s) | 0.173 sec ( 38.36 MB/s) |**+150.23%**| 0.042 sec ( 157.05 MB/s) | 0.129 sec ( 51.38 MB/s) |**+205.66%**|
| samba | 21606400 | 0.208 sec ( 103.82 MB/s) | 0.440 sec ( 49.15 MB/s) |**+111.24%**| 0.133 sec ( 163.02 MB/s) | 0.304 sec ( 71.01 MB/s) |**+129.56%**|
| sao | 7251944 | 0.107 sec ( 67.75 MB/s) | 0.154 sec ( 47.08 MB/s) | **+43.89%**| 0.079 sec ( 91.84 MB/s) | 0.095 sec ( 75.99 MB/s) | **+20.85%**|
| webster | 41458703 | 0.445 sec ( 93.24 MB/s) | 1.335 sec ( 31.04 MB/s) |**+200.33%**| 0.243 sec ( 170.50 MB/s) | 0.944 sec ( 43.93 MB/s) |**+288.10%**|
| x-ray | 8474240 | 0.139 sec ( 60.85 MB/s) | 0.219 sec ( 38.61 MB/s) | **+57.62%**| 0.093 sec ( 91.56 MB/s) | 0.106 sec ( 80.02 MB/s) | **+14.43%**|
| xml | 5345280 | 0.044 sec ( 122.71 MB/s) | 0.097 sec ( 55.15 MB/s) |**+122.52%**| 0.029 sec ( 182.47 MB/s) | 0.077 sec ( 69.57 MB/s) |**+162.29%**|
### [Large Canterbury Corpus](https://www.data-compression.info/Corpora/CanterburyCorpus/) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| bible.txt | 4047392 | 0.040 sec ( 100.99 MB/s) | 0.106 sec ( 38.15 MB/s) |**+164.69%**| 0.026 sec ( 156.84 MB/s) | 0.075 sec ( 53.85 MB/s) |**+191.28%**|
| E.coli | 4638690 | 0.052 sec ( 89.05 MB/s) | 0.156 sec ( 29.70 MB/s) |**+199.79%**| 0.024 sec ( 192.42 MB/s) | 0.123 sec ( 37.71 MB/s) |**+410.27%**|
| world192.txt | 2473400 | 0.023 sec ( 108.73 MB/s) | 0.056 sec ( 43.92 MB/s) |**+147.54%**| 0.017 sec ( 149.17 MB/s) | 0.037 sec ( 66.84 MB/s) |**+123.17%**|
### [Manzini Corpus](https://people.unipmn.it/manzini/lightweight/corpus/) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| chr22.dna | 34553758 | 0.400 sec ( 86.39 MB/s) | 1.252 sec ( 27.61 MB/s) |**+212.96%**| 0.177 sec ( 195.37 MB/s) | 1.024 sec ( 33.73 MB/s) |**+479.24%**|
| etext99 | 105277340 | 1.341 sec ( 78.51 MB/s) | 4.171 sec ( 25.24 MB/s) |**+211.02%**| 0.776 sec ( 135.69 MB/s) | 2.855 sec ( 36.87 MB/s) |**+268.00%**|
| gcc-3.0.tar | 86630400 | 0.909 sec ( 95.30 MB/s) | 2.332 sec ( 37.15 MB/s) |**+156.53%**| 0.529 sec ( 163.65 MB/s) | 1.614 sec ( 53.67 MB/s) |**+204.93%**|
| howto | 39422105 | 0.435 sec ( 90.63 MB/s) | 1.235 sec ( 31.91 MB/s) |**+183.99%**| 0.237 sec ( 166.57 MB/s) | 0.794 sec ( 49.66 MB/s) |**+235.45%**|
| jdk13c | 69728899 | 0.692 sec ( 100.74 MB/s) | 1.864 sec ( 37.40 MB/s) |**+169.37%**| 0.412 sec ( 169.13 MB/s) | 1.495 sec ( 46.63 MB/s) |**+262.72%**|
| linux-2.4.5.tar | 116254720 | 1.281 sec ( 90.74 MB/s) | 3.380 sec ( 34.39 MB/s) |**+163.81%**| 0.898 sec ( 129.48 MB/s) | 2.409 sec ( 48.26 MB/s) |**+168.31%**|
| rctail96 | 114711151 | 1.314 sec ( 87.30 MB/s) | 3.790 sec ( 30.27 MB/s) |**+188.41%**| 0.935 sec ( 122.65 MB/s) | 2.945 sec ( 38.95 MB/s) |**+214.89%**|
| rfc | 116421901 | 1.269 sec ( 91.75 MB/s) | 3.601 sec ( 32.33 MB/s) |**+183.84%**| 0.887 sec ( 131.32 MB/s) | 2.626 sec ( 44.33 MB/s) |**+196.21%**|
| sprot34.dat | 109617186 | 1.242 sec ( 88.26 MB/s) | 3.739 sec ( 29.32 MB/s) |**+201.01%**| 0.848 sec ( 129.27 MB/s) | 2.532 sec ( 43.30 MB/s) |**+198.56%**|
| w3c2 | 104201579 | 1.083 sec ( 96.21 MB/s) | 2.848 sec ( 36.59 MB/s) |**+162.95%**| 0.809 sec ( 128.80 MB/s) | 2.326 sec ( 44.80 MB/s) |**+187.50%**|
### [Large Text Compression Benchmark Corpus](https://www.mattmahoney.net/dc/textdata.html) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| enwik8 | 100000000 | 1.224 sec ( 81.69 MB/s) | 3.785 sec ( 26.42 MB/s) |**+209.19%**| 0.827 sec ( 120.98 MB/s) | 2.568 sec ( 38.94 MB/s) |**+210.67%**|
| enwik9 | 1000000000 | 13.633 sec ( 73.35 MB/s) | 42.792 sec ( 23.37 MB/s) |**+213.88%**| 9.410 sec ( 106.27 MB/s) | 29.223 sec ( 34.22 MB/s) |**+210.56%**|
### [The Gauntlet Corpus](https://github.com/michaelmaniscalco/gauntlet_corpus) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| abac | 200000 | 0.002 sec ( 120.88 MB/s) | 0.001 sec ( 156.91 MB/s) | -22.97% | 0.001 sec ( 193.69 MB/s) | 0.001 sec ( 151.70 MB/s) | **+27.68%**|
| abba | 10500596 | 0.070 sec ( 150.70 MB/s) | 0.267 sec ( 39.27 MB/s) |**+283.78%**| 0.046 sec ( 228.50 MB/s) | 0.297 sec ( 35.37 MB/s) |**+546.11%**|
| book1x20 | 15375420 | 0.138 sec ( 111.81 MB/s) | 0.477 sec ( 32.21 MB/s) |**+247.16%**| 0.086 sec ( 178.20 MB/s) | 0.330 sec ( 46.62 MB/s) |**+282.23%**|
| fib_s14930352 | 14930352 | 0.122 sec ( 122.45 MB/s) | 0.537 sec ( 27.79 MB/s) |**+340.60%**| 0.082 sec ( 183.15 MB/s) | 0.594 sec ( 25.14 MB/s) |**+628.64%**|
| fss10 | 12078908 | 0.091 sec ( 133.24 MB/s) | 0.406 sec ( 29.73 MB/s) |**+348.11%**| 0.063 sec ( 192.55 MB/s) | 0.463 sec ( 26.10 MB/s) |**+637.75%**|
| fss9 | 2851443 | 0.026 sec ( 109.23 MB/s) | 0.098 sec ( 29.10 MB/s) |**+275.34%**| 0.015 sec ( 192.40 MB/s) | 0.104 sec ( 27.47 MB/s) |**+600.49%**|
| houston | 3839141 | 0.023 sec ( 165.51 MB/s) | 0.018 sec ( 212.46 MB/s) | -22.10% | 0.012 sec ( 333.62 MB/s) | 0.018 sec ( 219.29 MB/s) | **+52.14%**|
| paper5x80 | 956322 | 0.009 sec ( 105.78 MB/s) | 0.018 sec ( 53.26 MB/s) | **+98.60%**| 0.006 sec ( 173.22 MB/s) | 0.014 sec ( 67.59 MB/s) |**+156.27%**|
| test1 | 2097152 | 0.026 sec ( 81.67 MB/s) | 0.042 sec ( 50.29 MB/s) | **+62.39%**| 0.014 sec ( 147.02 MB/s) | 0.041 sec ( 51.48 MB/s) |**+185.60%**|
| test2 | 2097152 | 0.026 sec ( 81.80 MB/s) | 0.032 sec ( 66.13 MB/s) | **+23.70%**| 0.014 sec ( 149.18 MB/s) | 0.032 sec ( 66.40 MB/s) |**+124.69%**|
| test3 | 2097088 | 0.023 sec ( 91.81 MB/s) | 0.034 sec ( 62.20 MB/s) | **+47.61%**| 0.024 sec ( 87.59 MB/s) | 0.038 sec ( 55.21 MB/s) | **+58.65%**|
### [Pizza & Chilli Corpus](https://pizzachili.dcc.uchile.cl/texts.html) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| dblp.xml | 296135874 | 3.422 sec ( 86.54 MB/s) | 9.243 sec ( 32.04 MB/s) |**+170.10%**| 2.568 sec ( 115.33 MB/s) | 7.178 sec ( 41.26 MB/s) |**+179.53%**|
| dna | 403927746 | 5.691 sec ( 70.98 MB/s) | 19.028 sec ( 21.23 MB/s) |**+234.35%**| 3.476 sec ( 116.21 MB/s) | 16.365 sec ( 24.68 MB/s) |**+370.82%**|
| english.1024MB | 1073741824 | 16.110 sec ( 66.65 MB/s) | 52.004 sec ( 20.65 MB/s) |**+222.81%**| 11.219 sec ( 95.71 MB/s) | 37.177 sec ( 28.88 MB/s) |**+231.37%**|
| pitches | 55832855 | 0.690 sec ( 80.96 MB/s) | 1.656 sec ( 33.71 MB/s) |**+140.12%**| 0.462 sec ( 120.98 MB/s) | 1.024 sec ( 54.51 MB/s) |**+121.96%**|
| proteins | 1184051855 | 18.368 sec ( 64.46 MB/s) | 66.699 sec ( 17.75 MB/s) |**+263.13%**| 12.717 sec ( 93.10 MB/s) | 35.746 sec ( 33.12 MB/s) |**+181.08%**|
| sources | 210866607 | 2.469 sec ( 85.40 MB/s) | 6.702 sec ( 31.46 MB/s) |**+171.45%**| 1.780 sec ( 118.43 MB/s) | 4.741 sec ( 44.48 MB/s) |**+166.27%**|
### [Pizza & Chilli Repetitive Corpus](https://pizzachili.dcc.uchile.cl/repcorpus.html) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| cere | 461286644 | 5.356 sec ( 86.12 MB/s) | 19.154 sec ( 24.08 MB/s) |**+257.61%**| 3.597 sec ( 128.23 MB/s) | 16.417 sec ( 28.10 MB/s) |**+356.39%**|
| coreutils | 205281778 | 2.181 sec ( 94.11 MB/s) | 6.814 sec ( 30.13 MB/s) |**+212.39%**| 1.626 sec ( 126.26 MB/s) | 5.216 sec ( 39.36 MB/s) |**+220.81%**|
| einstein.de.txt | 92758441 | 0.926 sec ( 100.22 MB/s) | 2.676 sec ( 34.66 MB/s) |**+189.17%**| 0.635 sec ( 146.08 MB/s) | 2.167 sec ( 42.81 MB/s) |**+241.27%**|
| einstein.en.txt | 467626544 | 5.480 sec ( 85.33 MB/s) | 15.822 sec ( 29.56 MB/s) |**+188.72%**| 3.885 sec ( 120.36 MB/s) | 12.593 sec ( 37.13 MB/s) |**+224.13%**|
|Escherichia_Coli | 112689515 | 1.272 sec ( 88.61 MB/s) | 4.562 sec ( 24.70 MB/s) |**+258.72%**| 0.864 sec ( 130.37 MB/s) | 3.827 sec ( 29.44 MB/s) |**+342.80%**|
| influenza | 154808555 | 1.588 sec ( 97.51 MB/s) | 5.325 sec ( 29.07 MB/s) |**+235.42%**| 1.159 sec ( 133.60 MB/s) | 4.619 sec ( 33.51 MB/s) |**+298.67%**|
| kernel | 257961616 | 2.747 sec ( 93.90 MB/s) | 8.993 sec ( 28.69 MB/s) |**+227.33%**| 2.030 sec ( 127.09 MB/s) | 6.614 sec ( 39.00 MB/s) |**+225.88%**|
| para | 429265758 | 5.129 sec ( 83.69 MB/s) | 18.302 sec ( 23.45 MB/s) |**+256.81%**| 3.444 sec ( 124.63 MB/s) | 15.618 sec ( 27.49 MB/s) |**+353.45%**|
| world_leaders | 46968181 | 0.338 sec ( 138.85 MB/s) | 0.758 sec ( 62.00 MB/s) |**+123.96%**| 0.202 sec ( 232.62 MB/s) | 0.637 sec ( 73.76 MB/s) |**+215.37%**|
|dblp.xml.00001.1 | 104857600 | 1.944 sec ( 53.94 MB/s) | 3.809 sec ( 27.53 MB/s) | **+95.95%**| 0.848 sec ( 123.66 MB/s) | 3.339 sec ( 31.40 MB/s) |**+293.78%**|
|dblp.xml.00001.2 | 104857600 | 1.922 sec ( 54.57 MB/s) | 3.825 sec ( 27.42 MB/s) | **+99.02%**| 0.845 sec ( 124.11 MB/s) | 3.358 sec ( 31.22 MB/s) |**+297.49%**|
| dblp.xml.0001.1 | 104857600 | 1.876 sec ( 55.89 MB/s) | 3.753 sec ( 27.94 MB/s) |**+100.03%**| 0.845 sec ( 124.08 MB/s) | 3.272 sec ( 32.05 MB/s) |**+287.18%**|
| dblp.xml.0001.2 | 104857600 | 1.840 sec ( 56.98 MB/s) | 3.743 sec ( 28.01 MB/s) |**+103.42%**| 0.844 sec ( 124.26 MB/s) | 3.242 sec ( 32.35 MB/s) |**+284.16%**|
| dna.001.1 | 104857600 | 1.957 sec ( 53.59 MB/s) | 4.475 sec ( 23.43 MB/s) |**+128.73%**| 0.785 sec ( 133.57 MB/s) | 3.835 sec ( 27.34 MB/s) |**+388.49%**|
| english.001.2 | 104857600 | 2.035 sec ( 51.53 MB/s) | 4.360 sec ( 24.05 MB/s) |**+114.26%**| 0.914 sec ( 114.76 MB/s) | 3.242 sec ( 32.35 MB/s) |**+254.80%**|
| proteins.001.1 | 104857600 | 2.001 sec ( 52.41 MB/s) | 4.486 sec ( 23.37 MB/s) |**+124.24%**| 0.871 sec ( 120.43 MB/s) | 2.880 sec ( 36.40 MB/s) |**+230.82%**|
| sources.001.2 | 104857600 | 1.777 sec ( 59.02 MB/s) | 3.649 sec ( 28.74 MB/s) |**+105.40%**| 0.847 sec ( 123.79 MB/s) | 2.940 sec ( 35.67 MB/s) |**+247.04%**|
| fib41 | 267914296 | 3.362 sec ( 79.68 MB/s) | 16.837 sec ( 15.91 MB/s) |**+400.76%**| 2.082 sec ( 128.66 MB/s) | 17.004 sec ( 15.76 MB/s) |**+716.58%**|
| rs.13 | 216747218 | 2.292 sec ( 94.57 MB/s) | 13.105 sec ( 16.54 MB/s) |**+471.82%**| 1.671 sec ( 129.71 MB/s) | 13.311 sec ( 16.28 MB/s) |**+696.59%**|
| tm29 | 268435456 | 8.414 sec ( 31.90 MB/s) | 19.460 sec ( 13.79 MB/s) |**+131.29%**| 2.407 sec ( 111.51 MB/s) | 20.004 sec ( 13.42 MB/s) |**+730.96%**|
### [Skyline Corpus](http://panthema.net/2012/1119-eSAIS-Inducing-Suffix-and-LCP-Arrays-in-External-Memory/eSAIS-DC3-LCP-0.5.0/src/input/skyline.h.html) ###
| file | size | libsais 2.10.4 (ST) | divsufsort 2.0.2 (ST) |speedup (ST)| libsais 2.10.4 (MT) | divsufsort 2.0.2 (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| skyline20.txt | 1048575 | 0.016 sec ( 64.17 MB/s) | 0.055 sec ( 18.92 MB/s) |**+239.18%**| 0.011 sec ( 97.18 MB/s) | 0.055 sec ( 19.15 MB/s) |**+407.38%**|
| skyline22.txt | 4194303 | 0.068 sec ( 61.81 MB/s) | 0.260 sec ( 16.16 MB/s) |**+282.46%**| 0.033 sec ( 127.33 MB/s) | 0.276 sec ( 15.20 MB/s) |**+737.65%**|
| skyline24.txt | 16777215 | 0.375 sec ( 44.76 MB/s) | 1.355 sec ( 12.38 MB/s) |**+261.57%**| 0.140 sec ( 119.44 MB/s) | 1.376 sec ( 12.19 MB/s) |**+879.45%**|
| skyline26.txt | 67108863 | 2.862 sec ( 23.45 MB/s) | 7.519 sec ( 8.93 MB/s) |**+162.71%**| 0.772 sec ( 86.97 MB/s) | 7.566 sec ( 8.87 MB/s) |**+880.50%**|
| skyline28.txt | 268435455 | 12.159 sec ( 22.08 MB/s) | 36.970 sec ( 7.26 MB/s) |**+204.06%**| 3.827 sec ( 70.15 MB/s) | 36.876 sec ( 7.28 MB/s) |**+863.64%**|
## Additional memory
The libsais reuses the space allocated for the suffix array during construction. In rare cases, this space is not large enough for the fastest algorithm and libsais will need to fallback to less efficient one (libsais has 4 algorithms at different break-points point: 6k, 4k, 2k and 1k; where k is alphabet size). To improve performance for those cases you could allocating additional space at the end of suffix array.
| file | size | libsais + O(n) (ST) | libsais + O(1) (ST) |speedup (ST)| libsais + O(n) (MT) | libsais + O(1) (MT) |speedup (MT)|
|:---------------:|:-----------:|:--------------------------:|:--------------------------:|:----------:|:--------------------------:|:--------------------------:|:----------:|
| osdb | 10085684 | 0.100 sec ( 100.68 MB/s) | 0.107 sec ( 94.43 MB/s) | **+6.61%**| 0.071 sec ( 142.67 MB/s) | 0.078 sec ( 128.57 MB/s) | **+10.96%**|
| x-ray | 8474240 | 0.112 sec ( 75.75 MB/s) | 0.138 sec ( 61.20 MB/s) | **+23.77%**| 0.070 sec ( 121.65 MB/s) | 0.093 sec ( 91.46 MB/s) | **+33.01%**|
| sao | 7251944 | 0.091 sec ( 80.02 MB/s) | 0.106 sec ( 68.19 MB/s) | **+17.35%**| 0.068 sec ( 107.05 MB/s) | 0.080 sec ( 90.48 MB/s) | **+18.32%**|
| ooffice | 6152192 | 0.065 sec ( 94.39 MB/s) | 0.071 sec ( 86.20 MB/s) | **+9.49%**| 0.048 sec ( 127.93 MB/s) | 0.055 sec ( 111.39 MB/s) | **+14.85%**|
| test3 | 2097088 | 0.017 sec ( 125.08 MB/s) | 0.019 sec ( 109.88 MB/s) | **+13.83%**| 0.015 sec ( 135.61 MB/s) | 0.018 sec ( 114.18 MB/s) | **+18.76%**|
> * All other files from [Benchmarks](#benchmarks) above do not suffer from this fallbacks.
================================================
FILE: CHANGES
================================================
Changes in 2.10.4 (September 1, 2025)
- Tuned prefetch distance for improved throughput.
Changes in 2.10.3 (August 12, 2025)
- No functional changes, added CMake install and export package rules.
Changes in 2.10.2 (June 10, 2025)
- Improved performance of suffix array and burrows wheeler transform construction on degenerate inputs.
Changes in 2.10.1 (May 11, 2025)
- No functional changes, slightly improved performance.
Changes in 2.10.0 (April 12, 2025)
- Improved performance, with noticeable gains on ARM architecture.
- Fixed compiler warnings and addressed undefined behavior.
Changes in 2.9.1 (March 19, 2025)
- No functional changes, resolved compiler warnings & undefined behavior.
Changes in 2.9.0 (March 16, 2025)
- Support for generalized suffix array (GSA) construction.
- Support for longest common prefix array (LCP) construction for generalized suffix array (GSA).
Changes in 2.8.7 (January 16, 2025)
- Restore the input array after suffix array construction (libsais64 & libsais16x64).
Changes in 2.8.6 (November 18, 2024)
- Fixed out-of-bound memory access issue for large inputs.
Changes in 2.8.5 (July 31, 2024)
- Miscellaneous changes to reduce compiler warnings about implicit functions.
Changes in 2.8.4 (June 13, 2024)
- Additional OpenMP acceleration (libsais16 & libsais16x64).
Changes in 2.8.3 (June 11, 2024)
- Implemented suffix array construction of a long 16-bit array (libsais16x64).
Changes in 2.8.2 (May 27, 2024)
- Implemented suffix array construction of a long 64-bit array (libsais64).
Changes in 2.8.1 (April 5, 2024)
- Fixed out-of-bound memory access issue for large inputs (libsais64).
Changes in 2.8.0 (March 3, 2024)
- Implemented permuted longest common prefix array (PLCP) construction of an integer array.
- Fixed compilation error when compiling the library with OpenMP enabled.
Changes in 2.7.5 (February 26, 2024)
- Improved performance of suffix array and burrows wheeler transform construction on degenerate inputs.
Changes in 2.7.4 (February 23, 2024)
- Resolved strict aliasing violation resulted in invalid code generation by Intel compiler.
Changes in 2.7.3 (April 21, 2023)
- CMake script for library build and integration with other projects.
Changes in 2.7.2 (April 18, 2023)
- Fixed out-of-bound memory access issue for large inputs (libsais64).
Changes in 2.7.1 (June 19, 2022)
- Improved cache coherence for ARMv8 architecture.
Changes in 2.7.0 (April 12, 2022)
- Support for longest common prefix array (LCP) construction.
Changes in 2.6.5 (January 1, 2022)
- Exposed functions to construct suffix array of a given integer array.
- Improved detection of various compiler intrinsics.
- Capped free space parameter to avoid crashing due to 32-bit integer overflow.
Changes in 2.6.0 (October 21, 2021)
- libsais16 for 16-bit inputs.
Changes in 2.5.0 (October 15, 2021)
- Support for optional symbol frequency tables.
Changes in 2.4.0 (July 14, 2021)
- Reverse Burrows-Wheeler transform.
Changes in 2.3.0 (June 23, 2021)
- Burrows-Wheeler transform with auxiliary indexes.
Changes in 2.2.0 (April 27, 2021)
- libsais64 for inputs larger than 2GB.
Changes in 2.1.0 (April 19, 2021)
- Additional OpenMP acceleration.
Changes in 2.0.0 (April 4, 2021)
- OpenMP acceleration.
Changes in 1.0.0 (February 23, 2021)
- Initial Release.
================================================
FILE: CMakeLists.txt
================================================
cmake_minimum_required(VERSION 3.10)
project(
libsais
VERSION 2.10.4
LANGUAGES C
DESCRIPTION "The libsais library provides fast linear-time construction of suffix array (SA), generalized suffix array (GSA), longest common prefix (LCP) array, permuted LCP (PLCP) array, Burrows-Wheeler transform (BWT) and inverse BWT based on the induced sorting algorithm with optional OpenMP support for multi-core parallel construction."
)
include(GNUInstallDirs)
include(CMakePackageConfigHelpers)
set(CMAKE_C_STANDARD 99)
set(CMAKE_C_STANDARD_REQUIRED ON)
set(CMAKE_C_EXTENSIONS OFF)
option(LIBSAIS_USE_OPENMP "Use OpenMP for parallelization" OFF)
option(LIBSAIS_BUILD_SHARED_LIB "Build libsais as a shared library" OFF)
if(LIBSAIS_BUILD_SHARED_LIB)
set(LIBSAIS_LIBRARY_TYPE SHARED)
else()
set(LIBSAIS_LIBRARY_TYPE STATIC)
endif()
add_library(libsais ${LIBSAIS_LIBRARY_TYPE})
set_target_properties(libsais PROPERTIES
PREFIX ""
IMPORT_PREFIX ""
VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
POSITION_INDEPENDENT_CODE ON
)
target_sources(libsais PRIVATE
include/libsais.h
include/libsais16.h
include/libsais16x64.h
include/libsais64.h
src/libsais.c
src/libsais16.c
src/libsais16x64.c
src/libsais64.c
)
if(LIBSAIS_USE_OPENMP)
find_package(OpenMP REQUIRED)
endif()
if(LIBSAIS_USE_OPENMP AND OpenMP_C_FOUND)
target_compile_definitions(libsais PUBLIC LIBSAIS_OPENMP)
target_link_libraries(libsais PUBLIC OpenMP::OpenMP_C)
endif()
if(LIBSAIS_BUILD_SHARED_LIB)
target_compile_definitions(libsais PUBLIC LIBSAIS_SHARED)
target_compile_definitions(libsais PRIVATE LIBSAIS_EXPORTS)
endif()
target_include_directories(libsais PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:include>
)
install(
TARGETS libsais
EXPORT libsaisTargets
RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
INCLUDES DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/include/
DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}
)
install(
EXPORT libsaisTargets
FILE libsaisConfig.cmake
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libsais
)
write_basic_package_version_file(
"${CMAKE_CURRENT_BINARY_DIR}/libsaisConfigVersion.cmake"
VERSION ${PROJECT_VERSION}
COMPATIBILITY SameMajorVersion
)
install(
FILES "${CMAKE_CURRENT_BINARY_DIR}/libsaisConfigVersion.cmake"
DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/libsais
)
================================================
FILE: LICENSE
================================================
Apache License
Version 2.0, January 2004
http://www.apache.org/licenses/
TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
1. Definitions.
"License" shall mean the terms and conditions for use, reproduction,
and distribution as defined by Sections 1 through 9 of this document.
"Licensor" shall mean the copyright owner or entity authorized by
the copyright owner that is granting the License.
"Legal Entity" shall mean the union of the acting entity and all
other entities that control, are controlled by, or are under common
control with that entity. For the purposes of this definition,
"control" means (i) the power, direct or indirect, to cause the
direction or management of such entity, whether by contract or
otherwise, or (ii) ownership of fifty percent (50%) or more of the
outstanding shares, or (iii) beneficial ownership of such entity.
"You" (or "Your") shall mean an individual or Legal Entity
exercising permissions granted by this License.
"Source" form shall mean the preferred form for making modifications,
including but not limited to software source code, documentation
source, and configuration files.
"Object" form shall mean any form resulting from mechanical
transformation or translation of a Source form, including but
not limited to compiled object code, generated documentation,
and conversions to other media types.
"Work" shall mean the work of authorship, whether in Source or
Object form, made available under the License, as indicated by a
copyright notice that is included in or attached to the work
(an example is provided in the Appendix below).
"Derivative Works" shall mean any work, whether in Source or Object
form, that is based on (or derived from) the Work and for which the
editorial revisions, annotations, elaborations, or other modifications
represent, as a whole, an original work of authorship. For the purposes
of this License, Derivative Works shall not include works that remain
separable from, or merely link (or bind by name) to the interfaces of,
the Work and Derivative Works thereof.
"Contribution" shall mean any work of authorship, including
the original version of the Work and any modifications or additions
to that Work or Derivative Works thereof, that is intentionally
submitted to Licensor for inclusion in the Work by the copyright owner
or by an individual or Legal Entity authorized to submit on behalf of
the copyright owner. For the purposes of this definition, "submitted"
means any form of electronic, verbal, or written communication sent
to the Licensor or its representatives, including but not limited to
communication on electronic mailing lists, source code control systems,
and issue tracking systems that are managed by, or on behalf of, the
Licensor for the purpose of discussing and improving the Work, but
excluding communication that is conspicuously marked or otherwise
designated in writing by the copyright owner as "Not a Contribution."
"Contributor" shall mean Licensor and any individual or Legal Entity
on behalf of whom a Contribution has been received by Licensor and
subsequently incorporated within the Work.
2. Grant of Copyright License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
copyright license to reproduce, prepare Derivative Works of,
publicly display, publicly perform, sublicense, and distribute the
Work and such Derivative Works in Source or Object form.
3. Grant of Patent License. Subject to the terms and conditions of
this License, each Contributor hereby grants to You a perpetual,
worldwide, non-exclusive, no-charge, royalty-free, irrevocable
(except as stated in this section) patent license to make, have made,
use, offer to sell, sell, import, and otherwise transfer the Work,
where such license applies only to those patent claims licensable
by such Contributor that are necessarily infringed by their
Contribution(s) alone or by combination of their Contribution(s)
with the Work to which such Contribution(s) was submitted. If You
institute patent litigation against any entity (including a
cross-claim or counterclaim in a lawsuit) alleging that the Work
or a Contribution incorporated within the Work constitutes direct
or contributory patent infringement, then any patent licenses
granted to You under this License for that Work shall terminate
as of the date such litigation is filed.
4. Redistribution. You may reproduce and distribute copies of the
Work or Derivative Works thereof in any medium, with or without
modifications, and in Source or Object form, provided that You
meet the following conditions:
(a) You must give any other recipients of the Work or
Derivative Works a copy of this License; and
(b) You must cause any modified files to carry prominent notices
stating that You changed the files; and
(c) You must retain, in the Source form of any Derivative Works
that You distribute, all copyright, patent, trademark, and
attribution notices from the Source form of the Work,
excluding those notices that do not pertain to any part of
the Derivative Works; and
(d) If the Work includes a "NOTICE" text file as part of its
distribution, then any Derivative Works that You distribute must
include a readable copy of the attribution notices contained
within such NOTICE file, excluding those notices that do not
pertain to any part of the Derivative Works, in at least one
of the following places: within a NOTICE text file distributed
as part of the Derivative Works; within the Source form or
documentation, if provided along with the Derivative Works; or,
within a display generated by the Derivative Works, if and
wherever such third-party notices normally appear. The contents
of the NOTICE file are for informational purposes only and
do not modify the License. You may add Your own attribution
notices within Derivative Works that You distribute, alongside
or as an addendum to the NOTICE text from the Work, provided
that such additional attribution notices cannot be construed
as modifying the License.
You may add Your own copyright statement to Your modifications and
may provide additional or different license terms and conditions
for use, reproduction, or distribution of Your modifications, or
for any such Derivative Works as a whole, provided Your use,
reproduction, and distribution of the Work otherwise complies with
the conditions stated in this License.
5. Submission of Contributions. Unless You explicitly state otherwise,
any Contribution intentionally submitted for inclusion in the Work
by You to the Licensor shall be under the terms and conditions of
this License, without any additional terms or conditions.
Notwithstanding the above, nothing herein shall supersede or modify
the terms of any separate license agreement you may have executed
with Licensor regarding such Contributions.
6. Trademarks. This License does not grant permission to use the trade
names, trademarks, service marks, or product names of the Licensor,
except as required for reasonable and customary use in describing the
origin of the Work and reproducing the content of the NOTICE file.
7. Disclaimer of Warranty. Unless required by applicable law or
agreed to in writing, Licensor provides the Work (and each
Contributor provides its Contributions) on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
implied, including, without limitation, any warranties or conditions
of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
PARTICULAR PURPOSE. You are solely responsible for determining the
appropriateness of using or redistributing the Work and assume any
risks associated with Your exercise of permissions under this License.
8. Limitation of Liability. In no event and under no legal theory,
whether in tort (including negligence), contract, or otherwise,
unless required by applicable law (such as deliberate and grossly
negligent acts) or agreed to in writing, shall any Contributor be
liable to You for damages, including any direct, indirect, special,
incidental, or consequential damages of any character arising as a
result of this License or out of the use or inability to use the
Work (including but not limited to damages for loss of goodwill,
work stoppage, computer failure or malfunction, or any and all
other commercial damages or losses), even if such Contributor
has been advised of the possibility of such damages.
9. Accepting Warranty or Additional Liability. While redistributing
the Work or Derivative Works thereof, You may choose to offer,
and charge a fee for, acceptance of support, warranty, indemnity,
or other liability obligations and/or rights consistent with this
License. However, in accepting such obligations, You may act only
on Your own behalf and on Your sole responsibility, not on behalf
of any other Contributor, and only if You agree to indemnify,
defend, and hold each Contributor harmless for any liability
incurred by, or claims asserted against, such Contributor by reason
of your accepting any such warranty or additional liability.
END OF TERMS AND CONDITIONS
APPENDIX: How to apply the Apache License to your work.
To apply the Apache License to your work, attach the following
boilerplate notice, with the fields enclosed by brackets "[]"
replaced with your own identifying information. (Don't include
the brackets!) The text should be enclosed in the appropriate
comment syntax for the file format. We also recommend that a
file or class name and description of purpose be included on the
same "printed page" as the copyright notice for easier
identification within third-party archives.
Copyright [yyyy] [name of copyright owner]
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
================================================
FILE: README.md
================================================
# libsais
The libsais library provides fast (see [Benchmarks](#benchmarks) below) linear-time construction of suffix array (SA), generalized suffix array (GSA), longest common prefix (LCP) array, permuted LCP (PLCP) array, Burrows-Wheeler transform (BWT) and inverse BWT, based on the induced sorting algorithm described in the following papers (with optional OpenMP support for multi-threaded parallel construction):
* Ge Nong, Sen Zhang, Wai Hong Chan *Two Efficient Algorithms for Linear Suffix Array Construction*, 2009
* Juha Karkkainen, Giovanni Manzini, Simon J. Puglisi *Permuted Longest-Common-Prefix Array*, 2009
* Nataliya Timoshevskaya, Wu-chun Feng *SAIS-OPT: On the characterization and optimization of the SA-IS algorithm for suffix array construction*, 2014
* Jing Yi Xie, Ge Nong, Bin Lao, Wentao Xu *Scalable Suffix Sorting on a Multicore Machine*, 2020
Copyright (c) 2021-2025 Ilya Grebnov <ilya.grebnov@gmail.com>
>The libsais is inspired by [libdivsufsort](https://github.com/y-256/libdivsufsort), [sais](https://sites.google.com/site/yuta256/sais) libraries by Yuta Mori and [msufsort](https://github.com/michaelmaniscalco/msufsort) by Michael Maniscalco.
## libcubwt
If you are looking for even faster construction times, you can try [libcubwt](https://github.com/IlyaGrebnov/libcubwt) a library for GPU-based suffix array, inverse suffix array and Burrows-Wheeler transform construction.
## Introduction
The libsais provides simple C99 API to construct suffix array and Burrows-Wheeler transformed string from a given string over constant-size alphabet. The algorithm runs in a linear time using typically only ~16KB of extra memory (with 2n bytes as absolute worst-case; where n is the length of the string). OpenMP acceleration uses 200KB of addition memory per thread.
> * The libsais works with compilers from GNU, Microsoft and Intel, but I recommend Clang for best performance.
> * The libsais is sensitive to fast memory and software prefetching and might not be suitable for some workloads. Please benchmark yourself.
## License
The libsais is released under the [Apache License Version 2.0](LICENSE "Apache license")
## Multi-threading
The libsais is memory-bound, so performance scales primarily with memory bandwidth and concurrency, not raw compute. The optimal number of threads for suffix array construction depends on CPU and memory architecture, as different systems (DDR4 vs DDR5, Intel vs AMD, single- vs multi-CCD) saturate memory at different points with maximum throughput generally following the number of memory channels rather than total core count. The x86-64 dual-channel systems typically saturate near 8 threads, but in practice may show good scaling at 6, 12 or even 16 threads.
## Changes
_For the full changelog, see [CHANGES](CHANGES)._
* September 1, 2025 (2.10.4)
* Tuned prefetch distance for improved throughput.
* August 12, 2025 (2.10.3)
* No functional changes, added CMake install and export package rules.
* June 10, 2025 (2.10.2)
* Improved performance of suffix array and burrows wheeler transform construction on degenerate inputs.
* May 11, 2025 (2.10.1)
* No functional changes, slightly improved performance.
* April 12, 2025 (2.10.0)
* Improved performance, with noticeable gains on ARM architecture.
* Fixed compiler warnings and addressed undefined behavior.
* March 19, 2025 (2.9.1)
* No functional changes, resolved compiler warnings & undefined behavior.
* March 16, 2025 (2.9.0)
* Support for generalized suffix array (GSA) construction.
* Support for longest common prefix array (LCP) construction for generalized suffix array (GSA).
## Versions of the libsais
* [libsais.c](src/libsais.c) (and corresponding [libsais.h](include/libsais.h)) is for suffix array, GSA, PLCP, LCP, forward BWT and reverse BWT construction over 8-bit inputs smaller than 2GB (2147483648 bytes).
* [libsais64.c](src/libsais64.c) (and corresponding [libsais64.h](include/libsais64.h)) is optional extension of the library for inputs larger or equlas to 2GB (2147483648 bytes).
* This versions of the library could also be used to construct suffix array of an integer array (with a caveat that input array must be mutable).
* [libsais16.c](src/libsais16.c) + [libsais16x64.c](src/libsais16x64.c) (and corresponding [libsais16.h](include/libsais16.h) + [libsais16x64.h](include/libsais16x64.h)) is independent version of the library for 16-bit inputs.
* This version of the library could also be used to construct suffix array and BWT of a set of strings by adding a unique end-of-string symbol to each string and then computing the result for the concatenated string.
## Examples of APIs (see [libsais.h](include/libsais.h), [libsais16.h](include/libsais16.h), [libsais16x64.h](include/libsais16x64.h) and [libsais64.h](include/libsais64.h) for complete APIs list)
```c
/**
* Constructs the suffix array of a given string.
* @param T [0..n-1] The input string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
int32_t libsais(const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the suffix array of a given integer array.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
int32_t libsais_int(int32_t * T, int32_t * SA, int32_t n, int32_t k, int32_t fs);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
int32_t libsais_bwt(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with primary index.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
int32_t libsais_unbwt(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string and a suffix array.
* @param T [0..n-1] The input string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
int32_t libsais_plcp(const uint8_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
```
## Example installation using [CPM](https://github.com/cpm-cmake/CPM.cmake)
```cmake
CPMAddPackage(
NAME libsais
GITHUB_REPOSITORY IlyaGrebnov/libsais
GIT_TAG v2.10.4
OPTIONS
"LIBSAIS_USE_OPENMP OFF"
"LIBSAIS_BUILD_SHARED_LIB OFF"
)
target_link_libraries(<your target> libsais)
```
# Algorithm description
The libsais uses the SA-IS (Suffix Array Induced Sorting) algorithm to construct both the suffix array and the Burrows-Wheeler transform through recursive decomposition and induced sorting:
* Initially, the algorithm classifies each position in a string as either an S-type or an L-type, based on whether the suffix starting at that position is lexicographically smaller or larger than the suffix at the adjacent right position. Positions identified as S-type, which have an adjacent left L-type position, are further categorized as LMS-type (Leftmost S-type) positions. Next, the algorithm splits the input string into LMS substrings, which start at an LMS-type position and extend up to the next adjacent LMS-type position. These LMS substrings are then lexicographically sorted through induced sorting and subsequently replaced in the input string with their corresponding sorted ranks, thus forming a new, compacted string. This compacted string reduces the problem size, enabling the algorithm to perform a recursive decomposition in which it is reapplied to construct the suffix array for the compacted string. And at the end of the recursive call, the suffix array for the input string is constructed from the suffix array of the compacted string using another round of induced sorting.
* The induced sorting is a core mechanic of the SA-IS algorithm and is employed twice during each recursive call: initially before the recursive call to establish the order of LMS substrings, and subsequently after the recursive call to finalize the order of the suffixes of the string. This process involves two sequential scans: a left-to-right scan that determines the order of L-type positions based on the LMS-type positions, followed by a right-to-left scan that establishes the order of S-type positions based on L-type positions. These scans efficiently extend the ordering from LMS-type positions to all positions in the string.
The SA-IS algorithm is quite elegant, yet implementing it efficiently presents multiple challenges. The primary challenge is that the SA-IS algorithm exhibits random memory access patterns, which can significantly decrease efficiency due to cache misses. Another significant challenge is that the SA-IS algorithm is not a lightweight construction algorithm; it requires additional memory to support positions classification, induced sorting, compacted string representations, and recursive decomposition. To circumvent this, the libsais implements careful optimizations that are worth highlighting:
* The libsais is meticulously designed from the ground up to leverage the capabilities of modern microprocessors, aiming to minimize various stalls and enhance throughput through instruction-level parallelism. The library employs sophisticated techniques such as manual loop unrolling, software prefetching, and branch elimination to achieve this goal. Moreover, it strives to minimize the number of passes over the data by combining multiple operations into a single function. A prime example of these techniques could be observed in the initialization phase of the SA-IS algorithm. In this phase, the entire logic required to classify positions, count symbols into various buckets, and segment the string into LMS substrings is executed through a single, completely branch-less loop:
```c
for (i = m - 1, j = omp_block_start + prefetch_distance + 3; i >= j; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 0], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 1], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 2], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 3], 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 0); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i - 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 2); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
```
* To sort LMS substrings lexicographically and compute their ranks, the libsais algorithm begins by gathering LMS-type positions as they appear in the string, placing them at the end of the suffix array. The library then employs two passes of induced sorting, which concludes with these same LMS-type positions ordered lexicographically at the beginning of the suffix array. Once all LMS-type positions are sorted, the ranks of the LMS substrings are computed by inspecting each pair of adjacent positions to determine if the corresponding LMS substrings are identical. If they are the same, they receive the same rank; otherwise, the rank is incremented by one.
* The first challenge of induced sorting is that, during passes over the suffix array, we need to examine each value to determine if it represents a valid position or an empty space, whether this position is not the beginning of the string (and thus could induce another position), and if the induced position is going to be of the necessary type (for example, during a left-to-right scan, we are only inducing L-type positions). This process can cause branch mispredictions and corresponding microprocessor stalls. To address this challenge, libsais employs following techniques. Firstly, the library uses two pointers per induction bucket, each pointing to different sections of the suffix array depending on the type of positions these positions will be inducing next. This approach allows for the separation of LS-type (meaning S-type, which induces L-type; this is the same as LMS-type) and LL-type positions needed for the left-to-right scan from SL-type and SS-type positions needed for the right-to-left scan. Secondly, by understanding the distribution of symbols based on their position types and the types they induce (i.e., SS, SL, LS, LL), we can pre-calculate pointers for each bucket, leaving no empty spaces. And thirdly, by removing the first LMS position and all positions left of it from the initial gathering and distribution, we eliminate the need to check whether a position is not the beginning of the string. These techniques not only result in a completely branch-less loop for each induction sorting pass but also eliminate redundant scanning and the final gathering of LMS-type positions at the beginning of the suffix array.
* The second challenge arises after induced sorting when we need to compute the ranks of LMS substrings. To accomplish this, we must first calculate and store the lengths of LMS substrings and then inspect each pair of adjacent LMS-type positions to determine if the corresponding LMS substrings are identical. This comparison starts with their lengths, and if they are the same, proceeds to compare the substrings themselves. Such operations exhibits random memory access patterns, which can significantly decrease efficiency due to cache misses. However, libsais avoids this inefficient logic by incorporating the ranking of LMS substrings as part of the induced sorting process itself. The library achieves this by marking the most significant bit (MSB) of positions in the suffix array that start new ranking groups. Each time a position is processed during induced sorting, the library checks the MSB and increments the current rank if the beginning of a new ranking group is encountered. Additionally, for each pointer in an induction bucket, the rank of the previous induced position is maintained. Whenever another position is induced, this previous rank is used to determine whether to mark the newly induced position as the beginning of a new rank group. All the logic to update the ranks and mark the beginnings of new ranking groups is implemented using bit manipulation and is completely branch-less.
```c
for (i = omp_block_start, j = omp_block_start + omp_block_size - 2 * prefetch_distance - 1; i < j; i += 2)
{
libsais_prefetchr(&SA[i + 3 * prefetch_distance]);
libsais_prefetchr(&T[SA[i + 2 * prefetch_distance + 0] & SAINT_MAX] - 1);
libsais_prefetchr(&T[SA[i + 2 * prefetch_distance + 0] & SAINT_MAX] - 2);
libsais_prefetchr(&T[SA[i + 2 * prefetch_distance + 1] & SAINT_MAX] - 1);
libsais_prefetchr(&T[SA[i + 2 * prefetch_distance + 1] & SAINT_MAX] - 2);
sa_sint_t p0 = SA[i + prefetch_distance + 0] & SAINT_MAX; sa_sint_t v0 = BUCKETS_INDEX4(T[p0 - (p0 > 0)], 0); libsais_prefetchw(&buckets[v0]);
sa_sint_t p1 = SA[i + prefetch_distance + 1] & SAINT_MAX; sa_sint_t v1 = BUCKETS_INDEX4(T[p1 - (p1 > 0)], 0); libsais_prefetchw(&buckets[v1]);
sa_sint_t p2 = SA[i + 0]; d += (p2 < 0); p2 &= SAINT_MAX; sa_sint_t v2 = BUCKETS_INDEX4(T[p2 - 1], T[p2 - 2] >= T[p2 - 1]);
SA[buckets[v2]++] = (p2 - 1) | (sa_sint_t)((sa_uint_t)(buckets[2 + v2] != d) << (SAINT_BIT - 1)); buckets[2 + v2] = d;
sa_sint_t p3 = SA[i + 1]; d += (p3 < 0); p3 &= SAINT_MAX; sa_sint_t v3 = BUCKETS_INDEX4(T[p3 - 1], T[p3 - 2] >= T[p3 - 1]);
SA[buckets[v3]++] = (p3 - 1) | (sa_sint_t)((sa_uint_t)(buckets[2 + v3] != d) << (SAINT_BIT - 1)); buckets[2 + v3] = d;
}
```
* In the SA-IS algorithm, after induced sorting, the ranks of LMS substrings are computed in suffix order. These ranks then need to be scattered to reorder them in string order before being gathered again to form the compacted string for recursion. At this point, some LMS substrings may be unique, meaning they don't share their rank with any other LMS substring. Being unique, these substrings are essentially already sorted, and their position relative to other LMS substrings is already determined. However, these unique LMS substrings may still be necessary for sorting other, non-unique LMS substrings during recursion-unless a unique LMS substring is immediately followed by another unique LMS substring in the string. In such cases, the rank of any subsequent unique LMS substrings becomes redundant in the compacted string, as it will not be utilized. Leveraging this insight, libsais employs a strategy to further reduce the size of the compacted string by omitting such redundant LMS substring ranks. This process involves a few steps. First, unique LMS substrings are identified by looking ahead while scanning LMS-positions in the suffix array during the ranking and scattering phase. When scattering LMS substring ranks to form the compacted string, the most significant bit (MSB) of the rank is used to mark that this rank is unique. Next, as the library scans the ranks in string order and detects tandems of unique ranks using the MSB, it then recalculates the MSB for ranks which are redundant, thus markign them for removal from the compacted string. Subsequently, the libsais rescans the LMS-positions in suffix order to recompute the ranks, now focusing only on the ranks of the remaining LMS substrings. The library also uses MSB of first symbol of LMS substrings to mark that LMS substring is removed from the compacted string. Finally, the library builds the compacted string based on the newly recalculated ranks for the remaining LMS substrings, while also saving the final positions for the removed LMS substrings before proceeding with recursion. This reduction process not only further decreases the size of the compacted string but also reduces the alphabet size of the reduced string and creates additional free space in the suffix array, which can be utilized during recursion.
* The SA-IS algorithm, while robust for suffix array construction, is not considered lightweight due to its need for additional memory for tasks such as position classification, induced sorting, the creation of compacted string representations, and recursive decomposition. To mitigate this, libsais optimizes memory usage by not storing position classifications and striving to reuse the memory space allocated for the suffix array for induced sorting, compacted string representations, and recursive decomposition processes. Since position classifications are not stored, the library recalculates them as needed, typically involving checks of adjacent symbols for a given position. Although this approach may seem straightforward, it introduces the challenge of random memory access. Nevertheless, libsais manages these accesses in a manner that either avoids unnecessary memory fetches or minimizes cache penalties. In situations where avoiding cache penalties is unfeasible, the library leverages the most significant bit (MSB) bits for computations, as branch mispredictions on modern microprocessors generally incur lower penalties than cache misses. Memory reuse for the suffix array, despite appearing straightforward, also presents hidden challenges related to implementation complexity. In certain cases, the available space in the suffix array may not suffice for the most optimal algorithm implementation mentioned above. Although such instances are rare, the library aims to deliver optimal performance without additional memory allocation by resorting to a less efficient variant of induced sorting. To accommodate various scenarios, libsais includes four distinct implementations tailored to different breakpoints based on alphabet size (denoted by 'k'): 6k, 4k, 2k, and 1k, with each implementation optimized to ensure performance efficiency. Extensive efforts have been dedicated to refining these implementations, including significant time invested in using various sanitizers to confirm the correctness of the algorithms. Ultimately, while there are specific inputs under which libsais might require additional memory-most of which tend to be synthetic tests designed specifically to challenge the SA-IS algorithm-such instances are relatively rare. In these exceptional cases, the library is designed to allocate only the minimum necessary amount of memory while still delivering the best possible performance.
* The libsais library, initially was developed for constructing suffix arrays, but has broadened its scope to include the calculation of the longest common prefix (LCP) and both the forward and inverse Burrows-Wheeler Transform (BWT) with considerable efforts has been dedicated to refining these algorithms to ensure they deliver maximum performance and maintain the correctness. An illustrative example is the forward BWT, which performance is nearly identical to that of its suffix array construction which is achieved by integrating a modified version of the induced sorting implementation within the final stage of the SA-IS algorithm. Rather than inducing suffix positions at this stage, the library induces the Burrows-Wheeler Transform directly. This approach also supports in-place transformation, maintaining a memory usage of 5n, making it an sutable for data compression applications. Similarly, the inverse BWT is fine-tuned to operate in-place, adhering to the same memory efficiency of 5n with an additional optimization of a bi-gram LF-mapping technique, which allows for the decoding of two symbols simultaneously effectively reduces the number of cache misses during the inversion of the Burrows-Wheeler Transform.
# Benchmarks
Full list of benchmarks are moved to own [Benchmarks.md](Benchmarks.md) file.
================================================
FILE: VERSION
================================================
2.10.4
================================================
FILE: include/libsais.h
================================================
/*--
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2025 Ilya Grebnov <ilya.grebnov@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Please see the file LICENSE for full copyright information.
--*/
#ifndef LIBSAIS_H
#define LIBSAIS_H 1
#define LIBSAIS_VERSION_MAJOR 2
#define LIBSAIS_VERSION_MINOR 10
#define LIBSAIS_VERSION_PATCH 4
#define LIBSAIS_VERSION_STRING "2.10.4"
#ifdef _WIN32
#ifdef LIBSAIS_SHARED
#ifdef LIBSAIS_EXPORTS
#define LIBSAIS_API __declspec(dllexport)
#else
#define LIBSAIS_API __declspec(dllimport)
#endif
#else
#define LIBSAIS_API
#endif
#else
#define LIBSAIS_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* Creates the libsais context that allows reusing allocated memory with each libsais operation.
* In multi-threaded environments, use one context per thread for parallel executions.
* @return the libsais context, NULL otherwise.
*/
LIBSAIS_API void * libsais_create_ctx(void);
#if defined(LIBSAIS_OPENMP)
/**
* Creates the libsais context that allows reusing allocated memory with each parallel libsais operation using OpenMP.
* In multi-threaded environments, use one context per thread for parallel executions.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return the libsais context, NULL otherwise.
*/
LIBSAIS_API void * libsais_create_ctx_omp(int32_t threads);
#endif
/**
* Destroys the libsass context and free previusly allocated memory.
* @param ctx The libsais context (can be NULL).
*/
LIBSAIS_API void libsais_free_ctx(void * ctx);
/**
* Constructs the suffix array of a given string.
* @param T [0..n-1] The input string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais(const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the generalized suffix array (GSA) of given string set.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_gsa(const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the suffix array of a given integer array.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_int(int32_t * T, int32_t * SA, int32_t n, int32_t k, int32_t fs);
/**
* Constructs the suffix array of a given string using libsais context.
* @param ctx The libsais context.
* @param T [0..n-1] The input string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_ctx(const void * ctx, const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the generalized suffix array (GSA) of given string set using libsais context.
* @param ctx The libsais context.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_gsa_ctx(const void * ctx, const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the suffix array of a given string in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_omp(const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
/**
* Constructs the generalized suffix array (GSA) of given string set in parallel using OpenMP.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_gsa_omp(const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
/**
* Constructs the suffix array of a given integer array in parallel using OpenMP.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_int_omp(int32_t * T, int32_t * SA, int32_t n, int32_t k, int32_t fs, int32_t threads);
#endif
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_bwt(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string with auxiliary indexes.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_bwt_aux(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string using libsais context.
* @param ctx The libsais context.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_bwt_ctx(const void * ctx, const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string with auxiliary indexes using libsais context.
* @param ctx The libsais context.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_bwt_aux_ctx(const void * ctx, const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_bwt_omp(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_bwt_aux_omp(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I, int32_t threads);
#endif
/**
* Creates the libsais reverse BWT context that allows reusing allocated memory with each libsais_unbwt_* operation.
* In multi-threaded environments, use one context per thread for parallel executions.
* @return the libsais context, NULL otherwise.
*/
LIBSAIS_API void * libsais_unbwt_create_ctx(void);
#if defined(LIBSAIS_OPENMP)
/**
* Creates the libsais reverse BWT context that allows reusing allocated memory with each parallel libsais_unbwt_* operation using OpenMP.
* In multi-threaded environments, use one context per thread for parallel executions.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return the libsais context, NULL otherwise.
*/
LIBSAIS_API void * libsais_unbwt_create_ctx_omp(int32_t threads);
#endif
/**
* Destroys the libsass reverse BWT context and free previusly allocated memory.
* @param ctx The libsais context (can be NULL).
*/
LIBSAIS_API void libsais_unbwt_free_ctx(void * ctx);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with primary index.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_unbwt(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with primary index using libsais reverse BWT context.
* @param ctx The libsais reverse BWT context.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_unbwt_ctx(const void * ctx, const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with auxiliary indexes.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_unbwt_aux(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with auxiliary indexes using libsais reverse BWT context.
* @param ctx The libsais reverse BWT context.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_unbwt_aux_ctx(const void * ctx, const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with primary index in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param i The primary index.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_unbwt_omp(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i, int32_t threads);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS_API int32_t libsais_unbwt_aux_omp(const uint8_t * T, uint8_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I, int32_t threads);
#endif
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string and a suffix array.
* @param T [0..n-1] The input string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_plcp(const uint8_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string set and a generalized suffix array (GSA).
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_plcp_gsa(const uint8_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
/**
* Constructs the permuted longest common prefix array (PLCP) of a integer array and a suffix array.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the integer array and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_plcp_int(const int32_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_lcp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string and a suffix array in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_plcp_omp(const uint8_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string set and a generalized suffix array (GSA) in parallel using OpenMP.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_plcp_gsa_omp(const uint8_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given integer array and a suffix array in parallel using OpenMP.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the integer array and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_plcp_int_omp(const int32_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array in parallel using OpenMP.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS_API int32_t libsais_lcp_omp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n, int32_t threads);
#endif
#ifdef __cplusplus
}
#endif
#endif
================================================
FILE: include/libsais16.h
================================================
/*--
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2025 Ilya Grebnov <ilya.grebnov@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Please see the file LICENSE for full copyright information.
--*/
#ifndef LIBSAIS16_H
#define LIBSAIS16_H 1
#define LIBSAIS16_VERSION_MAJOR 2
#define LIBSAIS16_VERSION_MINOR 10
#define LIBSAIS16_VERSION_PATCH 4
#define LIBSAIS16_VERSION_STRING "2.10.4"
#ifdef _WIN32
#ifdef LIBSAIS_SHARED
#ifdef LIBSAIS_EXPORTS
#define LIBSAIS16_API __declspec(dllexport)
#else
#define LIBSAIS16_API __declspec(dllimport)
#endif
#else
#define LIBSAIS16_API
#endif
#else
#define LIBSAIS16_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* Creates the libsais16 context that allows reusing allocated memory with each libsais16 operation.
* In multi-threaded environments, use one context per thread for parallel executions.
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS16_API void * libsais16_create_ctx(void);
#if defined(LIBSAIS_OPENMP)
/**
* Creates the libsais16 context that allows reusing allocated memory with each parallel libsais16 operation using OpenMP.
* In multi-threaded environments, use one context per thread for parallel executions.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS16_API void * libsais16_create_ctx_omp(int32_t threads);
#endif
/**
* Destroys the libsass context and free previusly allocated memory.
* @param ctx The libsais16 context (can be NULL).
*/
LIBSAIS16_API void libsais16_free_ctx(void * ctx);
/**
* Constructs the suffix array of a given 16-bit string.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the generalized suffix array (GSA) of given 16-bit string set.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_gsa(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the suffix array of a given integer array.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_int(int32_t * T, int32_t * SA, int32_t n, int32_t k, int32_t fs);
/**
* Constructs the suffix array of a given 16-bit string using libsais16 context.
* @param ctx The libsais16 context.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_ctx(const void * ctx, const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the generalized suffix array (GSA) of given 16-bit string set using libsais16 context.
* @param ctx The libsais16 context.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_gsa_ctx(const void * ctx, const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the suffix array of a given 16-bit string in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_omp(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
/**
* Constructs the generalized suffix array (GSA) of given 16-bit string set in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_gsa_omp(const uint16_t * T, int32_t * SA, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
/**
* Constructs the suffix array of a given integer array in parallel using OpenMP.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_int_omp(int32_t * T, int32_t * SA, int32_t n, int32_t k, int32_t fs, int32_t threads);
#endif
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_bwt(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_bwt_aux(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string using libsais16 context.
* @param ctx The libsais16 context.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_bwt_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq);
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes using libsais16 context.
* @param ctx The libsais16 context.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_bwt_aux_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_bwt_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t threads);
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_bwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, int32_t fs, int32_t * freq, int32_t r, int32_t * I, int32_t threads);
#endif
/**
* Creates the libsais16 reverse BWT context that allows reusing allocated memory with each libsais16_unbwt_* operation.
* In multi-threaded environments, use one context per thread for parallel executions.
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS16_API void * libsais16_unbwt_create_ctx(void);
#if defined(LIBSAIS_OPENMP)
/**
* Creates the libsais16 reverse BWT context that allows reusing allocated memory with each parallel libsais16_unbwt_* operation using OpenMP.
* In multi-threaded environments, use one context per thread for parallel executions.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return the libsais16 context, NULL otherwise.
*/
LIBSAIS16_API void * libsais16_unbwt_create_ctx_omp(int32_t threads);
#endif
/**
* Destroys the libsass reverse BWT context and free previusly allocated memory.
* @param ctx The libsais16 context (can be NULL).
*/
LIBSAIS16_API void libsais16_unbwt_free_ctx(void * ctx);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_unbwt(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index using libsais16 reverse BWT context.
* @param ctx The libsais16 reverse BWT context.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_unbwt_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_unbwt_aux(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes using libsais16 reverse BWT context.
* @param ctx The libsais16 reverse BWT context.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_unbwt_aux_ctx(const void * ctx, const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param i The primary index.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_unbwt_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t i, int32_t threads);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16_API int32_t libsais16_unbwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t * A, int32_t n, const int32_t * freq, int32_t r, const int32_t * I, int32_t threads);
#endif
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string and a suffix array.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the 16-bit string and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16_API int32_t libsais16_plcp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string set and a generalized suffix array (GSA).
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16_API int32_t libsais16_plcp_gsa(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16_API int32_t libsais16_lcp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string and a suffix array in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the 16-bit string and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16_API int32_t libsais16_plcp_omp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string set and a generalized suffix array (GSA) in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16_API int32_t libsais16_plcp_gsa_omp(const uint16_t * T, const int32_t * SA, int32_t * PLCP, int32_t n, int32_t threads);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array in parallel using OpenMP.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16_API int32_t libsais16_lcp_omp(const int32_t * PLCP, const int32_t * SA, int32_t * LCP, int32_t n, int32_t threads);
#endif
#ifdef __cplusplus
}
#endif
#endif
================================================
FILE: include/libsais16x64.h
================================================
/*--
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2025 Ilya Grebnov <ilya.grebnov@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Please see the file LICENSE for full copyright information.
--*/
#ifndef LIBSAIS16X64_H
#define LIBSAIS16X64_H 1
#define LIBSAIS16X64_VERSION_MAJOR 2
#define LIBSAIS16X64_VERSION_MINOR 10
#define LIBSAIS16X64_VERSION_PATCH 4
#define LIBSAIS16X64_VERSION_STRING "2.10.4"
#ifdef _WIN32
#ifdef LIBSAIS_SHARED
#ifdef LIBSAIS_EXPORTS
#define LIBSAIS16X64_API __declspec(dllexport)
#else
#define LIBSAIS16X64_API __declspec(dllimport)
#endif
#else
#define LIBSAIS16X64_API
#endif
#else
#define LIBSAIS16X64_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* Constructs the suffix array of a given 16-bit string.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64(const uint16_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq);
/**
* Constructs the generalized suffix array (GSA) of a given 16-bit string set.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_gsa(const uint16_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq);
/**
* Constructs the suffix array of a given integer array.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_long(int64_t * T, int64_t * SA, int64_t n, int64_t k, int64_t fs);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the suffix array of a given 16-bit string in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_omp(const uint16_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq, int64_t threads);
/**
* Constructs the generalized suffix array (GSA) of a given 16-bit string set in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given 16-bit string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_gsa_omp(const uint16_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq, int64_t threads);
/**
* Constructs the suffix array of a given integer array in parallel using OpenMP.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_long_omp(int64_t * T, int64_t * SA, int64_t n, int64_t k, int64_t fs, int64_t threads);
#endif
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_bwt(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq);
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_bwt_aux(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq, int64_t r, int64_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_bwt_omp(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq, int64_t threads);
/**
* Constructs the burrows-wheeler transformed 16-bit string (BWT) of a given 16-bit string with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given 16-bit string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..65535] The output 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_bwt_aux_omp(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq, int64_t r, int64_t * I, int64_t threads);
#endif
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_unbwt(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t i);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_unbwt_aux(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t r, const int64_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with primary index in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param i The primary index.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_unbwt_omp(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t i, int64_t threads);
/**
* Constructs the original 16-bit string from a given burrows-wheeler transformed 16-bit string (BWT) with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param U [0..n-1] The output 16-bit string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given 16-bit string.
* @param freq [0..65535] The input 16-bit symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_unbwt_aux_omp(const uint16_t * T, uint16_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t r, const int64_t * I, int64_t threads);
#endif
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string and a suffix array.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the 16-bit string and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_plcp(const uint16_t * T, const int64_t * SA, int64_t * PLCP, int64_t n);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string set and a generalized suffix array (GSA).
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_plcp_gsa(const uint16_t * T, const int64_t * SA, int64_t * PLCP, int64_t n);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_lcp(const int64_t * PLCP, const int64_t * SA, int64_t * LCP, int64_t n);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string and a suffix array in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the 16-bit string and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_plcp_omp(const uint16_t * T, const int64_t * SA, int64_t * PLCP, int64_t n, int64_t threads);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given 16-bit string set and a generalized suffix array (GSA) in parallel using OpenMP.
* @param T [0..n-1] The input 16-bit string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_plcp_gsa_omp(const uint16_t * T, const int64_t * SA, int64_t * PLCP, int64_t n, int64_t threads);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array in parallel using OpenMP.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS16X64_API int64_t libsais16x64_lcp_omp(const int64_t * PLCP, const int64_t * SA, int64_t * LCP, int64_t n, int64_t threads);
#endif
#ifdef __cplusplus
}
#endif
#endif
================================================
FILE: include/libsais64.h
================================================
/*--
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2025 Ilya Grebnov <ilya.grebnov@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Please see the file LICENSE for full copyright information.
--*/
#ifndef LIBSAIS64_H
#define LIBSAIS64_H 1
#define LIBSAIS64_VERSION_MAJOR 2
#define LIBSAIS64_VERSION_MINOR 10
#define LIBSAIS64_VERSION_PATCH 4
#define LIBSAIS64_VERSION_STRING "2.10.4"
#ifdef _WIN32
#ifdef LIBSAIS_SHARED
#ifdef LIBSAIS_EXPORTS
#define LIBSAIS64_API __declspec(dllexport)
#else
#define LIBSAIS64_API __declspec(dllimport)
#endif
#else
#define LIBSAIS64_API
#endif
#else
#define LIBSAIS64_API
#endif
#ifdef __cplusplus
extern "C" {
#endif
#include <stdint.h>
/**
* Constructs the suffix array of a given string.
* @param T [0..n-1] The input string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64(const uint8_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq);
/**
* Constructs the generalized suffix array (GSA) of given string set.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_gsa(const uint8_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq);
/**
* Constructs the suffix array of a given integer array.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_long(int64_t * T, int64_t * SA, int64_t n, int64_t k, int64_t fs);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the suffix array of a given string in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_omp(const uint8_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq, int64_t threads);
/**
* Constructs the generalized suffix array (GSA) of given string set in parallel using OpenMP.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the given string set.
* @param fs The extra space available at the end of SA array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_gsa_omp(const uint8_t * T, int64_t * SA, int64_t n, int64_t fs, int64_t * freq, int64_t threads);
/**
* Constructs the suffix array of a given integer array in parallel using OpenMP.
* Note, during construction input array will be modified, but restored at the end if no errors occurred.
* @param T [0..n-1] The input integer array.
* @param SA [0..n-1+fs] The output array of suffixes.
* @param n The length of the integer array.
* @param k The alphabet size of the input integer array.
* @param fs Extra space available at the end of SA array (can be 0, but 4k or better 6k is recommended for optimal performance).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_long_omp(int64_t * T, int64_t * SA, int64_t n, int64_t k, int64_t fs, int64_t threads);
#endif
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_bwt(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string with auxiliary indexes.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_bwt_aux(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq, int64_t r, int64_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return The primary index if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_bwt_omp(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq, int64_t threads);
/**
* Constructs the burrows-wheeler transformed string (BWT) of a given string with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n-1+fs] The temporary array.
* @param n The length of the given string.
* @param fs The extra space available at the end of A array (0 should be enough for most cases).
* @param freq [0..255] The output symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The output auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_bwt_aux_omp(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, int64_t fs, int64_t * freq, int64_t r, int64_t * I, int64_t threads);
#endif
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with primary index.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param i The primary index.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_unbwt(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t i);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with auxiliary indexes.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_unbwt_aux(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t r, const int64_t * I);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with primary index in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param i The primary index.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_unbwt_omp(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t i, int64_t threads);
/**
* Constructs the original string from a given burrows-wheeler transformed string (BWT) with auxiliary indexes in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param U [0..n-1] The output string (can be T).
* @param A [0..n] The temporary array (NOTE, temporary array must be n + 1 size).
* @param n The length of the given string.
* @param freq [0..255] The input symbol frequency table (can be NULL).
* @param r The sampling rate for auxiliary indexes (must be power of 2).
* @param I [0..(n-1)/r] The input auxiliary indexes.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 or -2 otherwise.
*/
LIBSAIS64_API int64_t libsais64_unbwt_aux_omp(const uint8_t * T, uint8_t * U, int64_t * A, int64_t n, const int64_t * freq, int64_t r, const int64_t * I, int64_t threads);
#endif
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string and a suffix array.
* @param T [0..n-1] The input string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS64_API int64_t libsais64_plcp(const uint8_t * T, const int64_t * SA, int64_t * PLCP, int64_t n);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string set and a generalized suffix array (GSA).
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS64_API int64_t libsais64_plcp_gsa(const uint8_t * T, const int64_t * SA, int64_t * PLCP, int64_t n);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS64_API int64_t libsais64_lcp(const int64_t * PLCP, const int64_t * SA, int64_t * LCP, int64_t n);
#if defined(LIBSAIS_OPENMP)
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string and a suffix array in parallel using OpenMP.
* @param T [0..n-1] The input string.
* @param SA [0..n-1] The input suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS64_API int64_t libsais64_plcp_omp(const uint8_t * T, const int64_t * SA, int64_t * PLCP, int64_t n, int64_t threads);
/**
* Constructs the permuted longest common prefix array (PLCP) of a given string set and a generalized suffix array (GSA) in parallel using OpenMP.
* @param T [0..n-1] The input string set using 0 as separators (T[n-1] must be 0).
* @param SA [0..n-1] The input generalized suffix array.
* @param PLCP [0..n-1] The output permuted longest common prefix array.
* @param n The length of the string set and the generalized suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS64_API int64_t libsais64_plcp_gsa_omp(const uint8_t * T, const int64_t * SA, int64_t * PLCP, int64_t n, int64_t threads);
/**
* Constructs the longest common prefix array (LCP) of a given permuted longest common prefix array (PLCP) and a suffix array in parallel using OpenMP.
* @param PLCP [0..n-1] The input permuted longest common prefix array.
* @param SA [0..n-1] The input suffix array or generalized suffix array (GSA).
* @param LCP [0..n-1] The output longest common prefix array (can be SA).
* @param n The length of the permuted longest common prefix array and the suffix array.
* @param threads The number of OpenMP threads to use (can be 0 for OpenMP default).
* @return 0 if no error occurred, -1 otherwise.
*/
LIBSAIS64_API int64_t libsais64_lcp_omp(const int64_t * PLCP, const int64_t * SA, int64_t * LCP, int64_t n, int64_t threads);
#endif
#ifdef __cplusplus
}
#endif
#endif
================================================
FILE: src/libsais.c
================================================
/*--
This file is a part of libsais, a library for linear time suffix array,
longest common prefix array and burrows wheeler transform construction.
Copyright (c) 2021-2025 Ilya Grebnov <ilya.grebnov@gmail.com>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
Please see the file LICENSE for full copyright information.
--*/
#include "libsais.h"
#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <limits.h>
#if defined(LIBSAIS_OPENMP)
#include <omp.h>
#else
#define UNUSED(_x) (void)(_x)
#endif
typedef int32_t sa_sint_t;
typedef uint32_t sa_uint_t;
typedef ptrdiff_t fast_sint_t;
typedef size_t fast_uint_t;
#define SAINT_BIT (32)
#define SAINT_MAX INT32_MAX
#define SAINT_MIN INT32_MIN
#define ALPHABET_SIZE (1 << CHAR_BIT)
#define UNBWT_FASTBITS (17)
#define SUFFIX_GROUP_BIT (SAINT_BIT - 1)
#define SUFFIX_GROUP_MARKER (((sa_sint_t)1) << (SUFFIX_GROUP_BIT - 1))
#define BUCKETS_INDEX2(_c, _s) (((_c) << 1) + (_s))
#define BUCKETS_INDEX4(_c, _s) (((_c) << 2) + (_s))
#define LIBSAIS_LOCAL_BUFFER_SIZE (2000)
#define LIBSAIS_PER_THREAD_CACHE_SIZE (24576)
#define LIBSAIS_FLAGS_NONE (0)
#define LIBSAIS_FLAGS_BWT (1)
#define LIBSAIS_FLAGS_GSA (2)
typedef struct LIBSAIS_THREAD_CACHE
{
sa_sint_t symbol;
sa_sint_t index;
} LIBSAIS_THREAD_CACHE;
typedef union LIBSAIS_THREAD_STATE
{
struct
{
fast_sint_t position;
fast_sint_t count;
fast_sint_t m;
fast_sint_t last_lms_suffix;
sa_sint_t * buckets;
LIBSAIS_THREAD_CACHE * cache;
} state;
uint8_t padding[64];
} LIBSAIS_THREAD_STATE;
typedef struct LIBSAIS_CONTEXT
{
sa_sint_t * buckets;
LIBSAIS_THREAD_STATE * thread_state;
fast_sint_t threads;
} LIBSAIS_CONTEXT;
typedef struct LIBSAIS_UNBWT_CONTEXT
{
sa_uint_t * bucket2;
uint16_t * fastbits;
sa_uint_t * buckets;
fast_sint_t threads;
} LIBSAIS_UNBWT_CONTEXT;
#if defined(__GNUC__) || defined(__clang__)
#define RESTRICT __restrict__
#elif defined(_MSC_VER) || defined(__INTEL_COMPILER)
#define RESTRICT __restrict
#else
#error Your compiler, configuration or platform is not supported.
#endif
#if defined(__has_builtin)
#if __has_builtin(__builtin_prefetch)
#define HAS_BUILTIN_PREFETCH
#endif
#elif defined(__GNUC__) && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 2)) || (__GNUC__ >= 4))
#define HAS_BUILTIN_PREFETCH
#endif
#if defined(__has_builtin)
#if __has_builtin(__builtin_bswap16)
#define HAS_BUILTIN_BSWAP16
#endif
#elif defined(__GNUC__) && (((__GNUC__ == 4) && (__GNUC_MINOR__ >= 8)) || (__GNUC__ >= 5))
#define HAS_BUILTIN_BSWAP16
#endif
#if defined(HAS_BUILTIN_PREFETCH)
#define libsais_prefetchr(address) __builtin_prefetch((const void *)(address), 0, 3)
#define libsais_prefetchw(address) __builtin_prefetch((const void *)(address), 1, 3)
#elif defined (_M_IX86) || defined (_M_AMD64)
#include <intrin.h>
#define libsais_prefetchr(address) _mm_prefetch((const void *)(address), _MM_HINT_T0)
#define libsais_prefetchw(address) _m_prefetchw((const void *)(address))
#elif defined (_M_ARM)
#include <intrin.h>
#define libsais_prefetchr(address) __prefetch((const void *)(address))
#define libsais_prefetchw(address) __prefetchw((const void *)(address))
#elif defined (_M_ARM64)
#include <intrin.h>
#define libsais_prefetchr(address) __prefetch2((const void *)(address), 0)
#define libsais_prefetchw(address) __prefetch2((const void *)(address), 16)
#else
#error Your compiler, configuration or platform is not supported.
#endif
#if !defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
#if defined(_LITTLE_ENDIAN) \
|| (defined(BYTE_ORDER) && defined(LITTLE_ENDIAN) && BYTE_ORDER == LITTLE_ENDIAN) \
|| (defined(_BYTE_ORDER) && defined(_LITTLE_ENDIAN) && _BYTE_ORDER == _LITTLE_ENDIAN) \
|| (defined(__BYTE_ORDER) && defined(__LITTLE_ENDIAN) && __BYTE_ORDER == __LITTLE_ENDIAN) \
|| (defined(__BYTE_ORDER__) && defined(__ORDER_LITTLE_ENDIAN__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
#define __LITTLE_ENDIAN__
#elif defined(_BIG_ENDIAN) \
|| (defined(BYTE_ORDER) && defined(BIG_ENDIAN) && BYTE_ORDER == BIG_ENDIAN) \
|| (defined(_BYTE_ORDER) && defined(_BIG_ENDIAN) && _BYTE_ORDER == _BIG_ENDIAN) \
|| (defined(__BYTE_ORDER) && defined(__BIG_ENDIAN) && __BYTE_ORDER == __BIG_ENDIAN) \
|| (defined(__BYTE_ORDER__) && defined(__ORDER_BIG_ENDIAN__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__)
#define __BIG_ENDIAN__
#elif defined(_WIN32)
#define __LITTLE_ENDIAN__
#endif
#endif
#if defined(__LITTLE_ENDIAN__) && !defined(__BIG_ENDIAN__)
#if defined(HAS_BUILTIN_BSWAP16)
#define libsais_bswap16(x) (__builtin_bswap16(x))
#elif defined(_MSC_VER) && !defined(__INTEL_COMPILER)
#define libsais_bswap16(x) (_byteswap_ushort(x))
#else
#define libsais_bswap16(x) ((uint16_t)(x >> 8) | (uint16_t)(x << 8))
#endif
#elif !defined(__LITTLE_ENDIAN__) && defined(__BIG_ENDIAN__)
#define libsais_bswap16(x) (x)
#else
#error Your compiler, configuration or platform is not supported.
#endif
static void * libsais_align_up(const void * address, size_t alignment)
{
return (void *)((((ptrdiff_t)address) + ((ptrdiff_t)alignment) - 1) & (-((ptrdiff_t)alignment)));
}
static void * libsais_alloc_aligned(size_t size, size_t alignment)
{
void * address = malloc(size + sizeof(short) + alignment - 1);
if (address != NULL)
{
void * aligned_address = libsais_align_up((void *)((ptrdiff_t)address + (ptrdiff_t)(sizeof(short))), alignment);
((short *)aligned_address)[-1] = (short)((ptrdiff_t)aligned_address - (ptrdiff_t)address);
return aligned_address;
}
return NULL;
}
static void libsais_free_aligned(void * aligned_address)
{
if (aligned_address != NULL)
{
free((void *)((ptrdiff_t)aligned_address - ((short *)aligned_address)[-1]));
}
}
static LIBSAIS_THREAD_STATE * libsais_alloc_thread_state(sa_sint_t threads)
{
LIBSAIS_THREAD_STATE * RESTRICT thread_state = (LIBSAIS_THREAD_STATE *)libsais_alloc_aligned((size_t)threads * sizeof(LIBSAIS_THREAD_STATE), 4096);
sa_sint_t * RESTRICT thread_buckets = (sa_sint_t *)libsais_alloc_aligned((size_t)threads * 4 * ALPHABET_SIZE * sizeof(sa_sint_t), 4096);
LIBSAIS_THREAD_CACHE * RESTRICT thread_cache = (LIBSAIS_THREAD_CACHE *)libsais_alloc_aligned((size_t)threads * LIBSAIS_PER_THREAD_CACHE_SIZE * sizeof(LIBSAIS_THREAD_CACHE), 4096);
if (thread_state != NULL && thread_buckets != NULL && thread_cache != NULL)
{
fast_sint_t t;
for (t = 0; t < threads; ++t)
{
thread_state[t].state.buckets = thread_buckets; thread_buckets += 4 * ALPHABET_SIZE;
thread_state[t].state.cache = thread_cache; thread_cache += LIBSAIS_PER_THREAD_CACHE_SIZE;
}
return thread_state;
}
libsais_free_aligned(thread_cache);
libsais_free_aligned(thread_buckets);
libsais_free_aligned(thread_state);
return NULL;
}
static void libsais_free_thread_state(LIBSAIS_THREAD_STATE * thread_state)
{
if (thread_state != NULL)
{
libsais_free_aligned(thread_state[0].state.cache);
libsais_free_aligned(thread_state[0].state.buckets);
libsais_free_aligned(thread_state);
}
}
static LIBSAIS_CONTEXT * libsais_create_ctx_main(sa_sint_t threads)
{
LIBSAIS_CONTEXT * RESTRICT ctx = (LIBSAIS_CONTEXT *)libsais_alloc_aligned(sizeof(LIBSAIS_CONTEXT), 64);
sa_sint_t * RESTRICT buckets = (sa_sint_t *)libsais_alloc_aligned((size_t)8 * ALPHABET_SIZE * sizeof(sa_sint_t), 4096);
LIBSAIS_THREAD_STATE * RESTRICT thread_state = threads > 1 ? libsais_alloc_thread_state(threads) : NULL;
if (ctx != NULL && buckets != NULL && (thread_state != NULL || threads == 1))
{
ctx->buckets = buckets;
ctx->threads = threads;
ctx->thread_state = thread_state;
return ctx;
}
libsais_free_thread_state(thread_state);
libsais_free_aligned(buckets);
libsais_free_aligned(ctx);
return NULL;
}
static void libsais_free_ctx_main(LIBSAIS_CONTEXT * ctx)
{
if (ctx != NULL)
{
libsais_free_thread_state(ctx->thread_state);
libsais_free_aligned(ctx->buckets);
libsais_free_aligned(ctx);
}
}
#if defined(LIBSAIS_OPENMP)
static sa_sint_t libsais_count_negative_marked_suffixes(sa_sint_t * RESTRICT SA, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
sa_sint_t count = 0;
fast_sint_t i; for (i = omp_block_start; i < omp_block_start + omp_block_size; ++i) { count += (SA[i] < 0); }
return count;
}
static sa_sint_t libsais_count_zero_marked_suffixes(sa_sint_t * RESTRICT SA, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
sa_sint_t count = 0;
fast_sint_t i; for (i = omp_block_start; i < omp_block_start + omp_block_size; ++i) { count += (SA[i] == 0); }
return count;
}
static void libsais_place_cached_suffixes(sa_sint_t * RESTRICT SA, LIBSAIS_THREAD_CACHE * RESTRICT cache, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
const fast_sint_t prefetch_distance = 64;
fast_sint_t i, j;
for (i = omp_block_start, j = omp_block_start + omp_block_size - prefetch_distance - 3; i < j; i += 4)
{
libsais_prefetchr(&cache[i + 2 * prefetch_distance]);
libsais_prefetchw(&SA[cache[i + prefetch_distance + 0].symbol]);
libsais_prefetchw(&SA[cache[i + prefetch_distance + 1].symbol]);
libsais_prefetchw(&SA[cache[i + prefetch_distance + 2].symbol]);
libsais_prefetchw(&SA[cache[i + prefetch_distance + 3].symbol]);
SA[cache[i + 0].symbol] = cache[i + 0].index;
SA[cache[i + 1].symbol] = cache[i + 1].index;
SA[cache[i + 2].symbol] = cache[i + 2].index;
SA[cache[i + 3].symbol] = cache[i + 3].index;
}
for (j += prefetch_distance + 3; i < j; i += 1)
{
SA[cache[i].symbol] = cache[i].index;
}
}
static void libsais_compact_and_place_cached_suffixes(sa_sint_t * RESTRICT SA, LIBSAIS_THREAD_CACHE * RESTRICT cache, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
const fast_sint_t prefetch_distance = 64;
fast_sint_t i, j, l;
for (i = omp_block_start, j = omp_block_start + omp_block_size - 3, l = omp_block_start; i < j; i += 4)
{
libsais_prefetchw(&cache[i + prefetch_distance]);
cache[l] = cache[i + 0]; l += cache[l].symbol >= 0;
cache[l] = cache[i + 1]; l += cache[l].symbol >= 0;
cache[l] = cache[i + 2]; l += cache[l].symbol >= 0;
cache[l] = cache[i + 3]; l += cache[l].symbol >= 0;
}
for (j += 3; i < j; i += 1)
{
cache[l] = cache[i]; l += cache[l].symbol >= 0;
}
libsais_place_cached_suffixes(SA, cache, omp_block_start, l - omp_block_start);
}
static void libsais_accumulate_counts_s32_2(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s]; }
}
static void libsais_accumulate_counts_s32_3(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s]; }
}
static void libsais_accumulate_counts_s32_4(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
sa_sint_t * RESTRICT bucket03 = bucket02 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s] + bucket03[s]; }
}
static void libsais_accumulate_counts_s32_5(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
sa_sint_t * RESTRICT bucket03 = bucket02 - bucket_stride;
sa_sint_t * RESTRICT bucket04 = bucket03 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s] + bucket03[s] + bucket04[s]; }
}
static void libsais_accumulate_counts_s32_6(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
sa_sint_t * RESTRICT bucket03 = bucket02 - bucket_stride;
sa_sint_t * RESTRICT bucket04 = bucket03 - bucket_stride;
sa_sint_t * RESTRICT bucket05 = bucket04 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s] + bucket03[s] + bucket04[s] + bucket05[s]; }
}
static void libsais_accumulate_counts_s32_7(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
sa_sint_t * RESTRICT bucket03 = bucket02 - bucket_stride;
sa_sint_t * RESTRICT bucket04 = bucket03 - bucket_stride;
sa_sint_t * RESTRICT bucket05 = bucket04 - bucket_stride;
sa_sint_t * RESTRICT bucket06 = bucket05 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s] + bucket03[s] + bucket04[s] + bucket05[s] + bucket06[s]; }
}
static void libsais_accumulate_counts_s32_8(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
sa_sint_t * RESTRICT bucket03 = bucket02 - bucket_stride;
sa_sint_t * RESTRICT bucket04 = bucket03 - bucket_stride;
sa_sint_t * RESTRICT bucket05 = bucket04 - bucket_stride;
sa_sint_t * RESTRICT bucket06 = bucket05 - bucket_stride;
sa_sint_t * RESTRICT bucket07 = bucket06 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s] + bucket03[s] + bucket04[s] + bucket05[s] + bucket06[s] + bucket07[s]; }
}
static void libsais_accumulate_counts_s32_9(sa_sint_t * RESTRICT bucket00, fast_sint_t bucket_size, fast_sint_t bucket_stride)
{
sa_sint_t * RESTRICT bucket01 = bucket00 - bucket_stride;
sa_sint_t * RESTRICT bucket02 = bucket01 - bucket_stride;
sa_sint_t * RESTRICT bucket03 = bucket02 - bucket_stride;
sa_sint_t * RESTRICT bucket04 = bucket03 - bucket_stride;
sa_sint_t * RESTRICT bucket05 = bucket04 - bucket_stride;
sa_sint_t * RESTRICT bucket06 = bucket05 - bucket_stride;
sa_sint_t * RESTRICT bucket07 = bucket06 - bucket_stride;
sa_sint_t * RESTRICT bucket08 = bucket07 - bucket_stride;
fast_sint_t s; for (s = 0; s < bucket_size; s += 1) { bucket00[s] = bucket00[s] + bucket01[s] + bucket02[s] + bucket03[s] + bucket04[s] + bucket05[s] + bucket06[s] + bucket07[s] + bucket08[s]; }
}
static void libsais_accumulate_counts_s32(sa_sint_t * RESTRICT buckets, fast_sint_t bucket_size, fast_sint_t bucket_stride, fast_sint_t num_buckets)
{
while (num_buckets >= 9)
{
libsais_accumulate_counts_s32_9(buckets - (num_buckets - 9) * bucket_stride, bucket_size, bucket_stride); num_buckets -= 8;
}
switch (num_buckets)
{
case 1: break;
case 2: libsais_accumulate_counts_s32_2(buckets, bucket_size, bucket_stride); break;
case 3: libsais_accumulate_counts_s32_3(buckets, bucket_size, bucket_stride); break;
case 4: libsais_accumulate_counts_s32_4(buckets, bucket_size, bucket_stride); break;
case 5: libsais_accumulate_counts_s32_5(buckets, bucket_size, bucket_stride); break;
case 6: libsais_accumulate_counts_s32_6(buckets, bucket_size, bucket_stride); break;
case 7: libsais_accumulate_counts_s32_7(buckets, bucket_size, bucket_stride); break;
case 8: libsais_accumulate_counts_s32_8(buckets, bucket_size, bucket_stride); break;
default: break;
}
}
#endif
static void libsais_flip_suffix_markers_omp(sa_sint_t * RESTRICT SA, sa_sint_t l, sa_sint_t threads)
{
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(threads) if(threads > 1 && l >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(threads);
fast_sint_t omp_thread_num = 0;
fast_sint_t omp_num_threads = 1;
#endif
fast_sint_t omp_block_stride = (l / omp_num_threads) & (-16);
fast_sint_t omp_block_start = omp_thread_num * omp_block_stride;
fast_sint_t omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : l - omp_block_start;
fast_sint_t i; for (i = omp_block_start; i < omp_block_start + omp_block_size; ++i) { SA[i] ^= SAINT_MIN; }
}
}
static void libsais_gather_lms_suffixes_8u(const uint8_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, fast_sint_t m, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
if (omp_block_size > 0)
{
const fast_sint_t prefetch_distance = 256;
fast_sint_t i, j = omp_block_start + omp_block_size, c0 = T[omp_block_start + omp_block_size - 1], c1 = -1;
while (j < n && (c1 = T[j]) == c0) { ++j; }
fast_uint_t f0 = c0 >= c1, f1 = 0;
for (i = omp_block_start + omp_block_size - 2, j = omp_block_start + 3; i >= j; i -= 4)
{
libsais_prefetchr(&T[i - prefetch_distance]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 0); m -= (f0 & ~f1);
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i - 1); m -= (f1 & ~f0);
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 2); m -= (f0 & ~f1);
}
for (j -= 3; i >= j; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i + 1); m -= (f0 & ~f1);
}
SA[m] = (sa_sint_t)(i + 1);
}
}
static void libsais_gather_lms_suffixes_8u_omp(const uint8_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(threads) if(threads > 1 && n >= 65536 && omp_get_dynamic() == 0)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(threads); UNUSED(thread_state);
fast_sint_t omp_thread_num = 0;
fast_sint_t omp_num_threads = 1;
#endif
fast_sint_t omp_block_stride = (n / omp_num_threads) & (-16);
fast_sint_t omp_block_start = omp_thread_num * omp_block_stride;
fast_sint_t omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : n - omp_block_start;
if (omp_num_threads == 1)
{
libsais_gather_lms_suffixes_8u(T, SA, n, (fast_sint_t)n - 1, omp_block_start, omp_block_size);
}
#if defined(LIBSAIS_OPENMP)
else
{
fast_sint_t t, m = 0; for (t = omp_num_threads - 1; t > omp_thread_num; --t) { m += thread_state[t].state.m; }
libsais_gather_lms_suffixes_8u(T, SA, n, (fast_sint_t)n - 1 - m, omp_block_start, omp_block_size);
#pragma omp barrier
if (thread_state[omp_thread_num].state.m > 0)
{
SA[(fast_sint_t)n - 1 - m] = (sa_sint_t)thread_state[omp_thread_num].state.last_lms_suffix;
}
}
#endif
}
}
static sa_sint_t libsais_gather_lms_suffixes_32s(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n)
{
const fast_sint_t prefetch_distance = 64;
sa_sint_t i = n - 2;
sa_sint_t m = n - 1;
fast_uint_t f0 = 1;
fast_uint_t f1 = 0;
fast_sint_t c0 = T[n - 1];
fast_sint_t c1 = 0;
for (; i >= 3; i -= 4)
{
libsais_prefetchr(&T[i - prefetch_distance]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = i + 1; m -= (sa_sint_t)(f1 & ~f0);
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = i - 0; m -= (sa_sint_t)(f0 & ~f1);
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = i - 1; m -= (sa_sint_t)(f1 & ~f0);
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = i - 2; m -= (sa_sint_t)(f0 & ~f1);
}
for (; i >= 0; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = i + 1; m -= (sa_sint_t)(f0 & ~f1);
}
return n - 1 - m;
}
static sa_sint_t libsais_gather_compacted_lms_suffixes_32s(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n)
{
const fast_sint_t prefetch_distance = 64;
sa_sint_t i = n - 2;
sa_sint_t m = n - 1;
fast_uint_t f0 = 1;
fast_uint_t f1 = 0;
fast_sint_t c0 = T[n - 1];
fast_sint_t c1 = 0;
for (; i >= 3; i -= 4)
{
libsais_prefetchr(&T[i - prefetch_distance]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = i + 1; m -= (sa_sint_t)(f1 & ~f0 & (c0 >= 0));
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = i - 0; m -= (sa_sint_t)(f0 & ~f1 & (c1 >= 0));
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = i - 1; m -= (sa_sint_t)(f1 & ~f0 & (c0 >= 0));
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = i - 2; m -= (sa_sint_t)(f0 & ~f1 & (c1 >= 0));
}
for (; i >= 0; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = i + 1; m -= (sa_sint_t)(f0 & ~f1 & (c1 >= 0));
}
return n - 1 - m;
}
#if defined(LIBSAIS_OPENMP)
static void libsais_count_lms_suffixes_32s_4k(const sa_sint_t * RESTRICT T, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets)
{
const fast_sint_t prefetch_distance = 64;
memset(buckets, 0, 4 * (size_t)k * sizeof(sa_sint_t));
sa_sint_t i = n - 2;
fast_uint_t f0 = 1;
fast_uint_t f1 = 0;
fast_sint_t c0 = T[n - 1];
fast_sint_t c1 = 0;
for (; i >= prefetch_distance + 3; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 0], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 1], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 2], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 3], 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0)));
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0)));
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
for (; i >= 0; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0)]++;
}
#endif
static void libsais_count_lms_suffixes_32s_2k(const sa_sint_t * RESTRICT T, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets)
{
const fast_sint_t prefetch_distance = 64;
memset(buckets, 0, 2 * (size_t)k * sizeof(sa_sint_t));
sa_sint_t i = n - 2;
fast_uint_t f0 = 1;
fast_uint_t f1 = 0;
fast_sint_t c0 = T[n - 1];
fast_sint_t c1 = 0;
for (; i >= prefetch_distance + 3; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 0], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 1], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 2], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 3], 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0)));
buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0)));
buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
for (; i >= 0; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
buckets[BUCKETS_INDEX2((fast_uint_t)c0, 0)]++;
}
#if defined(LIBSAIS_OPENMP)
static void libsais_count_compacted_lms_suffixes_32s_2k(const sa_sint_t * RESTRICT T, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets)
{
const fast_sint_t prefetch_distance = 64;
memset(buckets, 0, 2 * (size_t)k * sizeof(sa_sint_t));
sa_sint_t i = n - 2;
fast_uint_t f0 = 1;
fast_uint_t f1 = 0;
fast_sint_t c0 = T[n - 1];
fast_sint_t c1 = 0;
for (; i >= prefetch_distance + 3; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 0] & SAINT_MAX, 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 1] & SAINT_MAX, 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 2] & SAINT_MAX, 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 3] & SAINT_MAX, 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0)));
c0 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
c1 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0)));
c0 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
c1 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
for (; i >= 0; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1)));
c1 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
c0 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c0, 0)]++;
}
#endif
static sa_sint_t libsais_count_and_gather_lms_suffixes_8u(const uint8_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t * RESTRICT buckets, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
memset(buckets, 0, (size_t)4 * ALPHABET_SIZE * sizeof(sa_sint_t));
fast_sint_t m = omp_block_start + omp_block_size - 1;
if (omp_block_size > 0)
{
const fast_sint_t prefetch_distance = 256;
fast_sint_t i, j = m + 1, c0 = T[m], c1 = -1;
while (j < n && (c1 = T[j]) == c0) { ++j; }
fast_uint_t f0 = c0 >= c1, f1 = 0;
for (i = m - 1, j = omp_block_start + 3; i >= j; i -= 4)
{
libsais_prefetchr(&T[i - prefetch_distance]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 0); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i - 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 2); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
for (j -= 3; i >= j; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i + 1); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
c1 = (i >= 0) ? T[i] : -1; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
}
return (sa_sint_t)(omp_block_start + omp_block_size - 1 - m);
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_8u_omp(const uint8_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t * RESTRICT buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
sa_sint_t m = 0;
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(threads) if(threads > 1 && n >= 65536 && omp_get_dynamic() == 0)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(threads); UNUSED(thread_state);
fast_sint_t omp_thread_num = 0;
fast_sint_t omp_num_threads = 1;
#endif
fast_sint_t omp_block_stride = (n / omp_num_threads) & (-16);
fast_sint_t omp_block_start = omp_thread_num * omp_block_stride;
fast_sint_t omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : n - omp_block_start;
if (omp_num_threads == 1)
{
m = libsais_count_and_gather_lms_suffixes_8u(T, SA, n, buckets, omp_block_start, omp_block_size);
}
#if defined(LIBSAIS_OPENMP)
else
{
{
thread_state[omp_thread_num].state.position = omp_block_start + omp_block_size;
thread_state[omp_thread_num].state.m = libsais_count_and_gather_lms_suffixes_8u(T, SA, n, thread_state[omp_thread_num].state.buckets, omp_block_start, omp_block_size);
if (thread_state[omp_thread_num].state.m > 0)
{
thread_state[omp_thread_num].state.last_lms_suffix = SA[thread_state[omp_thread_num].state.position - 1];
}
}
#pragma omp barrier
#pragma omp master
{
memset(buckets, 0, (size_t)4 * ALPHABET_SIZE * sizeof(sa_sint_t));
fast_sint_t t;
for (t = omp_num_threads - 1; t >= 0; --t)
{
m += (sa_sint_t)thread_state[t].state.m;
if (t != omp_num_threads - 1 && thread_state[t].state.m > 0)
{
memcpy(&SA[n - m], &SA[thread_state[t].state.position - thread_state[t].state.m], (size_t)thread_state[t].state.m * sizeof(sa_sint_t));
}
{
sa_sint_t * RESTRICT temp_bucket = thread_state[t].state.buckets;
fast_sint_t s; for (s = 0; s < 4 * ALPHABET_SIZE; s += 1) { sa_sint_t A = buckets[s], B = temp_bucket[s]; buckets[s] = A + B; temp_bucket[s] = A; }
}
}
}
}
#endif
}
return m;
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
memset(buckets, 0, 4 * (size_t)k * sizeof(sa_sint_t));
fast_sint_t m = omp_block_start + omp_block_size - 1;
if (omp_block_size > 0)
{
const fast_sint_t prefetch_distance = 64;
fast_sint_t i, j = m + 1, c0 = T[m], c1 = -1;
while (j < n && (c1 = T[j]) == c0) { ++j; }
fast_uint_t f0 = c0 >= c1, f1 = 0;
for (i = m - 1, j = omp_block_start + prefetch_distance + 3; i >= j; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 0], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 1], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 2], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX4(T[i - prefetch_distance - 3], 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 0); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i - 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 2); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
for (j -= prefetch_distance + 3; i >= j; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i + 1); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX4((fast_uint_t)c1, f1 + f1 + f0)]++;
}
c1 = (i >= 0) ? T[i] : -1; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX4((fast_uint_t)c0, f0 + f0 + f1)]++;
}
return (sa_sint_t)(omp_block_start + omp_block_size - 1 - m);
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
memset(buckets, 0, 2 * (size_t)k * sizeof(sa_sint_t));
fast_sint_t m = omp_block_start + omp_block_size - 1;
if (omp_block_size > 0)
{
const fast_sint_t prefetch_distance = 64;
fast_sint_t i, j = m + 1, c0 = T[m], c1 = -1;
while (j < n && (c1 = T[j]) == c0) { ++j; }
fast_uint_t f0 = c0 >= c1, f1 = 0;
for (i = m - 1, j = omp_block_start + prefetch_distance + 3; i >= j; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 0], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 1], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 2], 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 3], 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 0); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i - 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 2); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
for (j -= prefetch_distance + 3; i >= j; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i + 1); m -= (f0 & ~f1);
buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
c1 = (i >= 0) ? T[i] : -1; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0);
buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
}
return (sa_sint_t)(omp_block_start + omp_block_size - 1 - m);
}
static sa_sint_t libsais_count_and_gather_compacted_lms_suffixes_32s_2k(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, fast_sint_t omp_block_start, fast_sint_t omp_block_size)
{
memset(buckets, 0, 2 * (size_t)k * sizeof(sa_sint_t));
fast_sint_t m = omp_block_start + omp_block_size - 1;
if (omp_block_size > 0)
{
const fast_sint_t prefetch_distance = 64;
fast_sint_t i, j = m + 1, c0 = T[m], c1 = -1;
while (j < n && (c1 = T[j]) == c0) { ++j; }
fast_uint_t f0 = c0 >= c1, f1 = 0;
for (i = m - 1, j = omp_block_start + prefetch_distance + 3; i >= j; i -= 4)
{
libsais_prefetchr(&T[i - 2 * prefetch_distance]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 0] & SAINT_MAX, 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 1] & SAINT_MAX, 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 2] & SAINT_MAX, 0)]);
libsais_prefetchw(&buckets[BUCKETS_INDEX2(T[i - prefetch_distance - 3] & SAINT_MAX, 0)]);
c1 = T[i - 0]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0 & (c0 >= 0));
c0 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 1]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 0); m -= (f0 & ~f1 & (c1 >= 0));
c1 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
c1 = T[i - 2]; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i - 1); m -= (f1 & ~f0 & (c0 >= 0));
c0 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
c0 = T[i - 3]; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i - 2); m -= (f0 & ~f1 & (c1 >= 0));
c1 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
for (j -= prefetch_distance + 3; i >= j; i -= 1)
{
c1 = c0; c0 = T[i]; f1 = f0; f0 = (fast_uint_t)(c0 > (c1 - (fast_sint_t)(f1))); SA[m] = (sa_sint_t)(i + 1); m -= (f0 & ~f1 & (c1 >= 0));
c1 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c1, (f0 & ~f1))]++;
}
c1 = (i >= 0) ? T[i] : -1; f1 = (fast_uint_t)(c1 > (c0 - (fast_sint_t)(f0))); SA[m] = (sa_sint_t)(i + 1); m -= (f1 & ~f0 & (c0 >= 0));
c0 &= SAINT_MAX; buckets[BUCKETS_INDEX2((fast_uint_t)c0, (f1 & ~f0))]++;
}
return (sa_sint_t)(omp_block_start + omp_block_size - 1 - m);
}
#if defined(LIBSAIS_OPENMP)
static fast_sint_t libsais_get_bucket_stride(fast_sint_t free_space, fast_sint_t bucket_size, fast_sint_t num_buckets)
{
fast_sint_t bucket_size_1024 = (bucket_size + 1023) & (-1024); if (free_space / (num_buckets - 1) >= bucket_size_1024) { return bucket_size_1024; }
fast_sint_t bucket_size_16 = (bucket_size + 15) & (-16); if (free_space / (num_buckets - 1) >= bucket_size_16) { return bucket_size_16; }
return bucket_size;
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k_fs_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t local_buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
sa_sint_t m = 0;
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(threads) if(threads > 1 && n >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(local_buckets); UNUSED(threads); UNUSED(thread_state);
fast_sint_t omp_thread_num = 0;
fast_sint_t omp_num_threads = 1;
#endif
fast_sint_t omp_block_stride = (n / omp_num_threads) & (-16);
fast_sint_t omp_block_start = omp_thread_num * omp_block_stride;
fast_sint_t omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : n - omp_block_start;
if (omp_num_threads == 1)
{
m = libsais_count_and_gather_lms_suffixes_32s_4k(T, SA, n, k, buckets, omp_block_start, omp_block_size);
}
#if defined(LIBSAIS_OPENMP)
else
{
fast_sint_t bucket_size = 4 * (fast_sint_t)k;
fast_sint_t free_space = local_buckets ? LIBSAIS_LOCAL_BUFFER_SIZE : (buckets - &SA[n]);
fast_sint_t bucket_stride = libsais_get_bucket_stride(free_space, bucket_size, omp_num_threads);
{
thread_state[omp_thread_num].state.position = omp_block_start + omp_block_size;
thread_state[omp_thread_num].state.count = libsais_count_and_gather_lms_suffixes_32s_4k(T, SA, n, k, buckets - (omp_thread_num * bucket_stride), omp_block_start, omp_block_size);
}
#pragma omp barrier
if (omp_thread_num == omp_num_threads - 1)
{
fast_sint_t t;
for (t = omp_num_threads - 1; t >= 0; --t)
{
m += (sa_sint_t)thread_state[t].state.count;
if (t != omp_num_threads - 1 && thread_state[t].state.count > 0)
{
memcpy(&SA[n - m], &SA[thread_state[t].state.position - thread_state[t].state.count], (size_t)thread_state[t].state.count * sizeof(sa_sint_t));
}
}
}
else
{
omp_num_threads = omp_num_threads - 1;
omp_block_stride = (bucket_size / omp_num_threads) & (-16);
omp_block_start = omp_thread_num * omp_block_stride;
omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : bucket_size - omp_block_start;
libsais_accumulate_counts_s32(buckets + omp_block_start, omp_block_size, bucket_stride, omp_num_threads + 1);
}
}
#endif
}
return m;
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k_fs_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t local_buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
sa_sint_t m = 0;
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(threads) if(threads > 1 && n >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(local_buckets); UNUSED(threads); UNUSED(thread_state);
fast_sint_t omp_thread_num = 0;
fast_sint_t omp_num_threads = 1;
#endif
fast_sint_t omp_block_stride = (n / omp_num_threads) & (-16);
fast_sint_t omp_block_start = omp_thread_num * omp_block_stride;
fast_sint_t omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : n - omp_block_start;
if (omp_num_threads == 1)
{
m = libsais_count_and_gather_lms_suffixes_32s_2k(T, SA, n, k, buckets, omp_block_start, omp_block_size);
}
#if defined(LIBSAIS_OPENMP)
else
{
fast_sint_t bucket_size = 2 * (fast_sint_t)k;
fast_sint_t free_space = local_buckets ? LIBSAIS_LOCAL_BUFFER_SIZE : (buckets - &SA[n]);
fast_sint_t bucket_stride = libsais_get_bucket_stride(free_space, bucket_size, omp_num_threads);
{
thread_state[omp_thread_num].state.position = omp_block_start + omp_block_size;
thread_state[omp_thread_num].state.count = libsais_count_and_gather_lms_suffixes_32s_2k(T, SA, n, k, buckets - (omp_thread_num * bucket_stride), omp_block_start, omp_block_size);
}
#pragma omp barrier
if (omp_thread_num == omp_num_threads - 1)
{
fast_sint_t t;
for (t = omp_num_threads - 1; t >= 0; --t)
{
m += (sa_sint_t)thread_state[t].state.count;
if (t != omp_num_threads - 1 && thread_state[t].state.count > 0)
{
memcpy(&SA[n - m], &SA[thread_state[t].state.position - thread_state[t].state.count], (size_t)thread_state[t].state.count * sizeof(sa_sint_t));
}
}
}
else
{
omp_num_threads = omp_num_threads - 1;
omp_block_stride = (bucket_size / omp_num_threads) & (-16);
omp_block_start = omp_thread_num * omp_block_stride;
omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : bucket_size - omp_block_start;
libsais_accumulate_counts_s32(buckets + omp_block_start, omp_block_size, bucket_stride, omp_num_threads + 1);
}
}
#endif
}
return m;
}
static void libsais_count_and_gather_compacted_lms_suffixes_32s_2k_fs_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t local_buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(threads) if(threads > 1 && n >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(local_buckets); UNUSED(threads); UNUSED(thread_state);
fast_sint_t omp_thread_num = 0;
fast_sint_t omp_num_threads = 1;
#endif
fast_sint_t omp_block_stride = (n / omp_num_threads) & (-16);
fast_sint_t omp_block_start = omp_thread_num * omp_block_stride;
fast_sint_t omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : n - omp_block_start;
if (omp_num_threads == 1)
{
libsais_count_and_gather_compacted_lms_suffixes_32s_2k(T, SA, n, k, buckets, omp_block_start, omp_block_size);
}
#if defined(LIBSAIS_OPENMP)
else
{
fast_sint_t bucket_size = 2 * (fast_sint_t)k;
fast_sint_t free_space = local_buckets ? LIBSAIS_LOCAL_BUFFER_SIZE : (buckets - &SA[(fast_sint_t)n + (fast_sint_t)n]);
fast_sint_t bucket_stride = libsais_get_bucket_stride(free_space, bucket_size, omp_num_threads);
{
thread_state[omp_thread_num].state.position = omp_block_start + omp_block_size;
thread_state[omp_thread_num].state.count = libsais_count_and_gather_compacted_lms_suffixes_32s_2k(T, SA + n, n, k, buckets - (omp_thread_num * bucket_stride), omp_block_start, omp_block_size);
}
#pragma omp barrier
{
fast_sint_t t, m = 0; for (t = omp_num_threads - 1; t >= omp_thread_num; --t) { m += (sa_sint_t)thread_state[t].state.count; }
if (thread_state[omp_thread_num].state.count > 0)
{
memcpy(&SA[n - m], &SA[n + thread_state[omp_thread_num].state.position - thread_state[omp_thread_num].state.count], (size_t)thread_state[omp_thread_num].state.count * sizeof(sa_sint_t));
}
}
{
omp_block_stride = (bucket_size / omp_num_threads) & (-16);
omp_block_start = omp_thread_num * omp_block_stride;
omp_block_size = omp_thread_num < omp_num_threads - 1 ? omp_block_stride : bucket_size - omp_block_start;
libsais_accumulate_counts_s32(buckets + omp_block_start, omp_block_size, bucket_stride, omp_num_threads);
}
}
#endif
}
}
#endif
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k_nofs_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t threads)
{
sa_sint_t m = 0;
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(2) if(threads > 1 && n >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(threads);
fast_sint_t omp_num_threads = 1;
#endif
if (omp_num_threads == 1)
{
m = libsais_count_and_gather_lms_suffixes_32s_4k(T, SA, n, k, buckets, 0, n);
}
#if defined(LIBSAIS_OPENMP)
else if (omp_thread_num == 0)
{
libsais_count_lms_suffixes_32s_4k(T, n, k, buckets);
}
else
{
m = libsais_gather_lms_suffixes_32s(T, SA, n);
}
#endif
}
return m;
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k_nofs_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t threads)
{
sa_sint_t m = 0;
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(2) if(threads > 1 && n >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(threads);
fast_sint_t omp_num_threads = 1;
#endif
if (omp_num_threads == 1)
{
m = libsais_count_and_gather_lms_suffixes_32s_2k(T, SA, n, k, buckets, 0, n);
}
#if defined(LIBSAIS_OPENMP)
else if (omp_thread_num == 0)
{
libsais_count_lms_suffixes_32s_2k(T, n, k, buckets);
}
else
{
m = libsais_gather_lms_suffixes_32s(T, SA, n);
}
#endif
}
return m;
}
static sa_sint_t libsais_count_and_gather_compacted_lms_suffixes_32s_2k_nofs_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t threads)
{
sa_sint_t m = 0;
#if defined(LIBSAIS_OPENMP)
#pragma omp parallel num_threads(2) if(threads > 1 && n >= 65536)
#endif
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t omp_thread_num = omp_get_thread_num();
fast_sint_t omp_num_threads = omp_get_num_threads();
#else
UNUSED(threads);
fast_sint_t omp_num_threads = 1;
#endif
if (omp_num_threads == 1)
{
m = libsais_count_and_gather_compacted_lms_suffixes_32s_2k(T, SA, n, k, buckets, 0, n);
}
#if defined(LIBSAIS_OPENMP)
else if (omp_thread_num == 0)
{
libsais_count_compacted_lms_suffixes_32s_2k(T, n, k, buckets);
}
else
{
m = libsais_gather_compacted_lms_suffixes_32s(T, SA, n);
}
#endif
}
return m;
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t local_buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
sa_sint_t m;
#if defined(LIBSAIS_OPENMP)
fast_sint_t free_space = local_buckets ? LIBSAIS_LOCAL_BUFFER_SIZE : (buckets - &SA[n]);
sa_sint_t max_threads = (sa_sint_t)(free_space / ((4 * (fast_sint_t)k + 15) & (-16))); if (max_threads > threads) { max_threads = threads; }
if (max_threads > 1 && n >= 65536 && n / k >= 2)
{
if (max_threads > n / 16 / k) { max_threads = n / 16 / k; }
m = libsais_count_and_gather_lms_suffixes_32s_4k_fs_omp(T, SA, n, k, buckets, local_buckets, max_threads > 2 ? max_threads : 2, thread_state);
}
else
#else
UNUSED(local_buckets); UNUSED(thread_state);
#endif
{
m = libsais_count_and_gather_lms_suffixes_32s_4k_nofs_omp(T, SA, n, k, buckets, threads);
}
return m;
}
static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t local_buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
sa_sint_t m;
#if defined(LIBSAIS_OPENMP)
fast_sint_t free_space = local_buckets ? LIBSAIS_LOCAL_BUFFER_SIZE : (buckets - &SA[n]);
sa_sint_t max_threads = (sa_sint_t)(free_space / ((2 * (fast_sint_t)k + 15) & (-16))); if (max_threads > threads) { max_threads = threads; }
if (max_threads > 1 && n >= 65536 && n / k >= 2)
{
if (max_threads > n / 8 / k) { max_threads = n / 8 / k; }
m = libsais_count_and_gather_lms_suffixes_32s_2k_fs_omp(T, SA, n, k, buckets, local_buckets, max_threads > 2 ? max_threads : 2, thread_state);
}
else
#else
UNUSED(local_buckets); UNUSED(thread_state);
#endif
{
m = libsais_count_and_gather_lms_suffixes_32s_2k_nofs_omp(T, SA, n, k, buckets, threads);
}
return m;
}
static void libsais_count_and_gather_compacted_lms_suffixes_32s_2k_omp(const sa_sint_t * RESTRICT T, sa_sint_t * RESTRICT SA, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets, sa_sint_t local_buckets, sa_sint_t threads, LIBSAIS_THREAD_STATE * RESTRICT thread_state)
{
#if defined(LIBSAIS_OPENMP)
fast_sint_t free_space = local_buckets ? LIBSAIS_LOCAL_BUFFER_SIZE : (buckets - &SA[(fast_sint_t)n + (fast_sint_t)n]);
sa_sint_t max_threads = (sa_sint_t)(free_space / ((2 * (fast_sint_t)k + 15) & (-16))); if (max_threads > threads) { max_threads = threads; }
if (!local_buckets && max_threads > 1 && n >= 65536 && n / k >= 2)
{
if (max_threads > n / 8 / k) { max_threads = n / 8 / k; }
libsais_count_and_gather_compacted_lms_suffixes_32s_2k_fs_omp(T, SA, n, k, buckets, local_buckets, max_threads > 2 ? max_threads : 2, thread_state);
}
else
#else
UNUSED(local_buckets); UNUSED(thread_state);
#endif
{
libsais_count_and_gather_compacted_lms_suffixes_32s_2k_nofs_omp(T, SA, n, k, buckets, threads);
}
}
static void libsais_count_suffixes_32s(const sa_sint_t * RESTRICT T, sa_sint_t n, sa_sint_t k, sa_sint_t * RESTRICT buckets)
{
const fast_sint_t prefetch_distance = 64;
memset(buckets, 0, (size_t)k * sizeof(sa_sint_t));
fast_sint_t i, j;
for (i = 0, j = (fast_sint_t)n - 7; i < j; i += 8)
{
libsais_prefetchr(&T[i + prefetch_distance]);
buckets[T[i + 0]]++;
buckets[T[i + 1]]++;
buckets[T[i + 2]]++;
buckets[T[i + 3]]++;
buckets[T[i + 4]]++;
buckets[T[i + 5]]++;
buckets[T[i + 6]]++;
buckets[T[i + 7]]++;
}
for (j += 7; i < j; i += 1)
{
buckets[T[i]]++;
}
}
static sa_sint_t libsais_initialize_buckets_start_and_end_8u(sa_sint_t * RESTRICT buckets, sa_sint_t * RESTRICT freq)
{
sa_sint_t * RESTRICT bucket_start = &buckets[6 * ALPHABET_SIZE];
sa_sint_t * RESTRICT bucket_end = &buckets[7 * ALPHABET_SIZE];
fast_sint_t k = -1;
if (freq != NULL)
{
fast_sint_t i, j; sa_sint_t sum = 0;
for (i = BUCKETS_INDEX4(0, 0), j = 0; i <= BUCKETS_INDEX4(ALPHABET_SIZE - 1, 0); i += BUCKETS_INDEX4(1, 0), j += 1)
{
sa_sint_t total = buckets[i + BUCKETS_INDEX4(0, 0)] + buckets[i + BUCKETS_INDEX4(0, 1)] + buckets[i + BUCKETS_INDEX4(0, 2)] + buckets[i + BUCKETS_INDEX4(0, 3)];
bucket_start[j] = sum; sum += total; bucket_end[j] = sum; k = total > 0 ? j : k; freq[j] = total;
}
}
else
{
fast_sint_t i, j; sa_sint_t sum = 0;
for (i = BUCKETS_INDEX4(0, 0), j = 0; i <= BUCKETS_INDEX4(ALPHABET_SIZE - 1, 0); i += BUCKETS_INDEX4(1, 0), j += 1)
{
sa_sint_t total = buckets[i + BUCKETS_INDEX4(0, 0)] + buckets[i + BUCKETS_INDEX4(0, 1)] + buckets[i + BUCKETS_INDEX4(0, 2)] + buckets[i + BUCKETS_INDEX4(0, 3)];
bucket_start[j] = sum; sum += total; bucket_end[j] = sum; k = total > 0 ? j : k;
}
}
return (sa_sint_t)(k + 1);
}
static void libsais_initialize_buckets_start_and_end_32s_6k(sa_sint_t k, sa
gitextract__tus48nc/
├── Benchmarks.md
├── CHANGES
├── CMakeLists.txt
├── LICENSE
├── README.md
├── VERSION
├── include/
│ ├── libsais.h
│ ├── libsais16.h
│ ├── libsais16x64.h
│ └── libsais64.h
└── src/
├── libsais.c
├── libsais16.c
├── libsais16x64.c
└── libsais64.c
SYMBOL INDEX (1118 symbols across 4 files) FILE: src/libsais.c type sa_sint_t (line 38) | typedef int32_t sa_sint_t; type sa_uint_t (line 39) | typedef uint32_t sa_uint_t; type fast_sint_t (line 40) | typedef ptrdiff_t fast_sint_t; type fast_uint_t (line 41) | typedef size_t fast_uint_t; type LIBSAIS_THREAD_CACHE (line 63) | typedef struct LIBSAIS_THREAD_CACHE type LIBSAIS_THREAD_STATE (line 69) | typedef union LIBSAIS_THREAD_STATE type LIBSAIS_CONTEXT (line 86) | typedef struct LIBSAIS_CONTEXT type LIBSAIS_UNBWT_CONTEXT (line 93) | typedef struct LIBSAIS_UNBWT_CONTEXT function libsais_free_aligned (line 195) | static void libsais_free_aligned(void * aligned_address) function LIBSAIS_THREAD_STATE (line 203) | static LIBSAIS_THREAD_STATE * libsais_alloc_thread_state(sa_sint_t threads) function libsais_free_thread_state (line 227) | static void libsais_free_thread_state(LIBSAIS_THREAD_STATE * thread_state) function LIBSAIS_CONTEXT (line 237) | static LIBSAIS_CONTEXT * libsais_create_ctx_main(sa_sint_t threads) function libsais_free_ctx_main (line 258) | static void libsais_free_ctx_main(LIBSAIS_CONTEXT * ctx) function sa_sint_t (line 270) | static sa_sint_t libsais_count_negative_marked_suffixes(sa_sint_t * REST... function sa_sint_t (line 279) | static sa_sint_t libsais_count_zero_marked_suffixes(sa_sint_t * RESTRICT... function libsais_place_cached_suffixes (line 288) | static void libsais_place_cached_suffixes(sa_sint_t * RESTRICT SA, LIBSA... function libsais_compact_and_place_cached_suffixes (line 314) | static void libsais_compact_and_place_cached_suffixes(sa_sint_t * RESTRI... function libsais_accumulate_counts_s32_2 (line 337) | static void libsais_accumulate_counts_s32_2(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_3 (line 343) | static void libsais_accumulate_counts_s32_3(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_4 (line 350) | static void libsais_accumulate_counts_s32_4(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_5 (line 358) | static void libsais_accumulate_counts_s32_5(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_6 (line 367) | static void libsais_accumulate_counts_s32_6(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_7 (line 377) | static void libsais_accumulate_counts_s32_7(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_8 (line 388) | static void libsais_accumulate_counts_s32_8(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32_9 (line 400) | static void libsais_accumulate_counts_s32_9(sa_sint_t * RESTRICT bucket0... function libsais_accumulate_counts_s32 (line 413) | static void libsais_accumulate_counts_s32(sa_sint_t * RESTRICT buckets, ... function libsais_flip_suffix_markers_omp (line 436) | static void libsais_flip_suffix_markers_omp(sa_sint_t * RESTRICT SA, sa_... function libsais_gather_lms_suffixes_8u (line 459) | static void libsais_gather_lms_suffixes_8u(const uint8_t * RESTRICT T, s... function libsais_gather_lms_suffixes_8u_omp (line 490) | static void libsais_gather_lms_suffixes_8u_omp(const uint8_t * RESTRICT ... function sa_sint_t (line 531) | static sa_sint_t libsais_gather_lms_suffixes_32s(const sa_sint_t * RESTR... function sa_sint_t (line 560) | static sa_sint_t libsais_gather_compacted_lms_suffixes_32s(const sa_sint... function libsais_count_lms_suffixes_32s_4k (line 591) | static void libsais_count_lms_suffixes_32s_4k(const sa_sint_t * RESTRICT... function libsais_count_lms_suffixes_32s_2k (line 636) | static void libsais_count_lms_suffixes_32s_2k(const sa_sint_t * RESTRICT... function libsais_count_compacted_lms_suffixes_32s_2k (line 681) | static void libsais_count_compacted_lms_suffixes_32s_2k(const sa_sint_t ... function sa_sint_t (line 726) | static sa_sint_t libsais_count_and_gather_lms_suffixes_8u(const uint8_t ... function sa_sint_t (line 772) | static sa_sint_t libsais_count_and_gather_lms_suffixes_8u_omp(const uint... function sa_sint_t (line 839) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k(const sa_s... function sa_sint_t (line 890) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k(const sa_s... function sa_sint_t (line 941) | static sa_sint_t libsais_count_and_gather_compacted_lms_suffixes_32s_2k(... function fast_sint_t (line 994) | static fast_sint_t libsais_get_bucket_stride(fast_sint_t free_space, fas... function sa_sint_t (line 1002) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k_fs_omp(con... function sa_sint_t (line 1070) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k_fs_omp(con... function libsais_count_and_gather_compacted_lms_suffixes_32s_2k_fs_omp (line 1138) | static void libsais_count_and_gather_compacted_lms_suffixes_32s_2k_fs_om... function sa_sint_t (line 1198) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k_nofs_omp(c... function sa_sint_t (line 1233) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k_nofs_omp(c... function sa_sint_t (line 1268) | static sa_sint_t libsais_count_and_gather_compacted_lms_suffixes_32s_2k_... function sa_sint_t (line 1303) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_4k_omp(const ... function sa_sint_t (line 1327) | static sa_sint_t libsais_count_and_gather_lms_suffixes_32s_2k_omp(const ... function libsais_count_and_gather_compacted_lms_suffixes_32s_2k_omp (line 1351) | static void libsais_count_and_gather_compacted_lms_suffixes_32s_2k_omp(c... function libsais_count_suffixes_32s (line 1371) | static void libsais_count_suffixes_32s(const sa_sint_t * RESTRICT T, sa_... function sa_sint_t (line 1398) | static sa_sint_t libsais_initialize_buckets_start_and_end_8u(sa_sint_t *... function libsais_initialize_buckets_start_and_end_32s_6k (line 1429) | static void libsais_initialize_buckets_start_and_end_32s_6k(sa_sint_t k,... function libsais_initialize_buckets_start_and_end_32s_4k (line 1443) | static void libsais_initialize_buckets_start_and_end_32s_4k(sa_sint_t k,... function libsais_initialize_buckets_end_32s_2k (line 1457) | static void libsais_initialize_buckets_end_32s_2k(sa_sint_t k, sa_sint_t... function libsais_initialize_buckets_start_and_end_32s_2k (line 1466) | static void libsais_initialize_buckets_start_and_end_32s_2k(sa_sint_t k,... function libsais_initialize_buckets_start_32s_1k (line 1477) | static void libsais_initialize_buckets_start_32s_1k(sa_sint_t k, sa_sint... function libsais_initialize_buckets_end_32s_1k (line 1483) | static void libsais_initialize_buckets_end_32s_1k(sa_sint_t k, sa_sint_t... function sa_sint_t (line 1489) | static sa_sint_t libsais_initialize_buckets_for_lms_suffixes_radix_sort_... function libsais_initialize_buckets_for_lms_suffixes_radix_sort_32s_2k (line 1519) | static void libsais_initialize_buckets_for_lms_suffixes_radix_sort_32s_2... function sa_sint_t (line 1535) | static sa_sint_t libsais_initialize_buckets_for_lms_suffixes_radix_sort_... function libsais_initialize_buckets_for_radix_and_partial_sorting_32s_4k (line 1565) | static void libsais_initialize_buckets_for_radix_and_partial_sorting_32s... function libsais_radix_sort_lms_suffixes_8u (line 1586) | static void libsais_radix_sort_lms_suffixes_8u(const uint8_t * RESTRICT ... function libsais_radix_sort_lms_suffixes_8u_omp (line 1612) | static void libsais_radix_sort_lms_suffixes_8u_omp(const uint8_t * RESTR... function libsais_radix_sort_lms_suffixes_32s_6k (line 1662) | static void libsais_radix_sort_lms_suffixes_32s_6k(const sa_sint_t * RES... function libsais_radix_sort_lms_suffixes_32s_2k (line 1693) | static void libsais_radix_sort_lms_suffixes_32s_2k(const sa_sint_t * RES... function libsais_radix_sort_lms_suffixes_32s_block_gather (line 1726) | static void libsais_radix_sort_lms_suffixes_32s_block_gather(const sa_si... function libsais_radix_sort_lms_suffixes_32s_6k_block_sort (line 1754) | static void libsais_radix_sort_lms_suffixes_32s_6k_block_sort(sa_sint_t ... function libsais_radix_sort_lms_suffixes_32s_2k_block_sort (line 1780) | static void libsais_radix_sort_lms_suffixes_32s_2k_block_sort(sa_sint_t ... function libsais_radix_sort_lms_suffixes_32s_6k_block_omp (line 1806) | static void libsais_radix_sort_lms_suffixes_32s_6k_block_omp(const sa_si... function libsais_radix_sort_lms_suffixes_32s_2k_block_omp (line 1855) | static void libsais_radix_sort_lms_suffixes_32s_2k_block_omp(const sa_si... function libsais_radix_sort_lms_suffixes_32s_6k_omp (line 1906) | static void libsais_radix_sort_lms_suffixes_32s_6k_omp(const sa_sint_t *... function libsais_radix_sort_lms_suffixes_32s_2k_omp (line 1928) | static void libsais_radix_sort_lms_suffixes_32s_2k_omp(const sa_sint_t *... function sa_sint_t (line 1950) | static sa_sint_t libsais_radix_sort_lms_suffixes_32s_1k(const sa_sint_t ... function libsais_radix_sort_set_markers_32s_6k (line 1998) | static void libsais_radix_sort_set_markers_32s_6k(sa_sint_t * RESTRICT S... function libsais_radix_sort_set_markers_32s_4k (line 2024) | static void libsais_radix_sort_set_markers_32s_4k(sa_sint_t * RESTRICT S... function libsais_radix_sort_set_markers_32s_6k_omp (line 2050) | static void libsais_radix_sort_set_markers_32s_6k_omp(sa_sint_t * RESTRI... function libsais_radix_sort_set_markers_32s_4k_omp (line 2073) | static void libsais_radix_sort_set_markers_32s_4k_omp(sa_sint_t * RESTRI... function libsais_initialize_buckets_for_partial_sorting_8u (line 2096) | static void libsais_initialize_buckets_for_partial_sorting_8u(const uint... function libsais_initialize_buckets_for_partial_sorting_32s_6k (line 2115) | static void libsais_initialize_buckets_for_partial_sorting_32s_6k(const ... function sa_sint_t (line 2157) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_8u(const uin... function libsais_partial_sorting_scan_left_to_right_8u_block_prepare (line 2192) | static void libsais_partial_sorting_scan_left_to_right_8u_block_prepare(... function libsais_partial_sorting_scan_left_to_right_8u_block_place (line 2225) | static void libsais_partial_sorting_scan_left_to_right_8u_block_place(sa... function sa_sint_t (line 2251) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_8u_block_omp... function sa_sint_t (line 2318) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_8u_omp(const... function sa_sint_t (line 2369) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_6k(const... function sa_sint_t (line 2402) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_4k(const... function libsais_partial_sorting_scan_left_to_right_32s_1k (line 2447) | static void libsais_partial_sorting_scan_left_to_right_32s_1k(const sa_s... function libsais_partial_sorting_scan_left_to_right_32s_6k_block_gather (line 2473) | static void libsais_partial_sorting_scan_left_to_right_32s_6k_block_gath... function libsais_partial_sorting_scan_left_to_right_32s_4k_block_gather (line 2499) | static void libsais_partial_sorting_scan_left_to_right_32s_4k_block_gath... function libsais_partial_sorting_scan_left_to_right_32s_1k_block_gather (line 2523) | static void libsais_partial_sorting_scan_left_to_right_32s_1k_block_gath... function sa_sint_t (line 2547) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_6k_block... function sa_sint_t (line 2575) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_4k_block... function libsais_partial_sorting_scan_left_to_right_32s_1k_block_sort (line 2618) | static void libsais_partial_sorting_scan_left_to_right_32s_1k_block_sort... function sa_sint_t (line 2656) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_6k_block... function sa_sint_t (line 2707) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_4k_block... function libsais_partial_sorting_scan_left_to_right_32s_1k_block_omp (line 2758) | static void libsais_partial_sorting_scan_left_to_right_32s_1k_block_omp(... function sa_sint_t (line 2809) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_6k_omp(c... function sa_sint_t (line 2836) | static sa_sint_t libsais_partial_sorting_scan_left_to_right_32s_4k_omp(c... function libsais_partial_sorting_scan_left_to_right_32s_1k_omp (line 2866) | static void libsais_partial_sorting_scan_left_to_right_32s_1k_omp(const ... function libsais_partial_sorting_shift_markers_8u_omp (line 2890) | static void libsais_partial_sorting_shift_markers_8u_omp(sa_sint_t * RES... function libsais_partial_sorting_shift_markers_32s_6k_omp (line 2923) | static void libsais_partial_sorting_shift_markers_32s_6k_omp(sa_sint_t *... function libsais_partial_sorting_shift_markers_32s_4k (line 2956) | static void libsais_partial_sorting_shift_markers_32s_4k(sa_sint_t * RES... function libsais_partial_sorting_shift_buckets_32s_6k (line 2977) | static void libsais_partial_sorting_shift_buckets_32s_6k(sa_sint_t k, sa... function sa_sint_t (line 2989) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_8u(const uin... function sa_sint_t (line 3022) | static sa_sint_t libsais_partial_gsa_scan_right_to_left_8u(const uint8_t... function libsais_partial_sorting_scan_right_to_left_8u_block_prepare (line 3058) | static void libsais_partial_sorting_scan_right_to_left_8u_block_prepare(... function libsais_partial_sorting_scan_right_to_left_8u_block_place (line 3091) | static void libsais_partial_sorting_scan_right_to_left_8u_block_place(sa... function libsais_partial_gsa_scan_right_to_left_8u_block_place (line 3117) | static void libsais_partial_gsa_scan_right_to_left_8u_block_place(sa_sin... function sa_sint_t (line 3143) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_8u_block_omp... function sa_sint_t (line 3208) | static sa_sint_t libsais_partial_gsa_scan_right_to_left_8u_block_omp(con... function libsais_partial_sorting_scan_right_to_left_8u_omp (line 3275) | static void libsais_partial_sorting_scan_right_to_left_8u_omp(const uint... function libsais_partial_gsa_scan_right_to_left_8u_omp (line 3324) | static void libsais_partial_gsa_scan_right_to_left_8u_omp(const uint8_t ... function sa_sint_t (line 3373) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_6k(const... function sa_sint_t (line 3406) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_4k(const... function libsais_partial_sorting_scan_right_to_left_32s_1k (line 3451) | static void libsais_partial_sorting_scan_right_to_left_32s_1k(const sa_s... function libsais_partial_sorting_scan_right_to_left_32s_6k_block_gather (line 3477) | static void libsais_partial_sorting_scan_right_to_left_32s_6k_block_gath... function libsais_partial_sorting_scan_right_to_left_32s_4k_block_gather (line 3503) | static void libsais_partial_sorting_scan_right_to_left_32s_4k_block_gath... function libsais_partial_sorting_scan_right_to_left_32s_1k_block_gather (line 3527) | static void libsais_partial_sorting_scan_right_to_left_32s_1k_block_gath... function sa_sint_t (line 3551) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_6k_block... function sa_sint_t (line 3579) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_4k_block... function libsais_partial_sorting_scan_right_to_left_32s_1k_block_sort (line 3622) | static void libsais_partial_sorting_scan_right_to_left_32s_1k_block_sort... function sa_sint_t (line 3660) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_6k_block... function sa_sint_t (line 3711) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_4k_block... function libsais_partial_sorting_scan_right_to_left_32s_1k_block_omp (line 3762) | static void libsais_partial_sorting_scan_right_to_left_32s_1k_block_omp(... function sa_sint_t (line 3813) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_6k_omp(c... function sa_sint_t (line 3840) | static sa_sint_t libsais_partial_sorting_scan_right_to_left_32s_4k_omp(c... function libsais_partial_sorting_scan_right_to_left_32s_1k_omp (line 3864) | static void libsais_partial_sorting_scan_right_to_left_32s_1k_omp(const ... function fast_sint_t (line 3886) | static fast_sint_t libsais_partial_sorting_gather_lms_suffixes_32s_4k(sa... function fast_sint_t (line 3909) | static fast_sint_t libsais_partial_sorting_gather_lms_suffixes_32s_1k(sa... function libsais_partial_sorting_gather_lms_suffixes_32s_4k_omp (line 3932) | static void libsais_partial_sorting_gather_lms_suffixes_32s_4k_omp(sa_si... function libsais_partial_sorting_gather_lms_suffixes_32s_1k_omp (line 3983) | static void libsais_partial_sorting_gather_lms_suffixes_32s_1k_omp(sa_si... function libsais_induce_partial_order_8u_omp (line 4034) | static void libsais_induce_partial_order_8u_omp(const uint8_t * RESTRICT... function libsais_induce_partial_order_32s_6k_omp (line 4065) | static void libsais_induce_partial_order_32s_6k_omp(const sa_sint_t * RE... function libsais_induce_partial_order_32s_4k_omp (line 4073) | static void libsais_induce_partial_order_32s_4k_omp(const sa_sint_t * RE... function libsais_induce_partial_order_32s_2k_omp (line 4083) | static void libsais_induce_partial_order_32s_2k_omp(const sa_sint_t * RE... function libsais_induce_partial_order_32s_1k_omp (line 4090) | static void libsais_induce_partial_order_32s_1k_omp(const sa_sint_t * RE... function sa_sint_t (line 4103) | static sa_sint_t libsais_renumber_lms_suffixes_8u(sa_sint_t * RESTRICT S... function fast_sint_t (line 4133) | static fast_sint_t libsais_gather_marked_lms_suffixes(sa_sint_t * RESTRI... function sa_sint_t (line 4160) | static sa_sint_t libsais_renumber_lms_suffixes_8u_omp(sa_sint_t * RESTRI... function libsais_gather_marked_lms_suffixes_omp (line 4211) | static void libsais_gather_marked_lms_suffixes_omp(sa_sint_t * RESTRICT ... function sa_sint_t (line 4270) | static sa_sint_t libsais_renumber_and_gather_lms_suffixes_omp(sa_sint_t ... function sa_sint_t (line 4287) | static sa_sint_t libsais_renumber_distinct_lms_suffixes_32s_4k(sa_sint_t... function libsais_mark_distinct_lms_suffixes_32s (line 4317) | static void libsais_mark_distinct_lms_suffixes_32s(sa_sint_t * RESTRICT ... function libsais_clamp_lms_suffixes_length_32s (line 4338) | static void libsais_clamp_lms_suffixes_length_32s(sa_sint_t * RESTRICT S... function sa_sint_t (line 4361) | static sa_sint_t libsais_renumber_distinct_lms_suffixes_32s_4k_omp(sa_si... function libsais_mark_distinct_lms_suffixes_32s_omp (line 4412) | static void libsais_mark_distinct_lms_suffixes_32s_omp(sa_sint_t * RESTR... function libsais_clamp_lms_suffixes_length_32s_omp (line 4434) | static void libsais_clamp_lms_suffixes_length_32s_omp(sa_sint_t * RESTRI... function sa_sint_t (line 4456) | static sa_sint_t libsais_renumber_and_mark_distinct_lms_suffixes_32s_4k_... function sa_sint_t (line 4469) | static sa_sint_t libsais_renumber_and_mark_distinct_lms_suffixes_32s_1k_... function libsais_reconstruct_lms_suffixes (line 4548) | static void libsais_reconstruct_lms_suffixes(sa_sint_t * RESTRICT SA, sa... function libsais_reconstruct_lms_suffixes_omp (line 4576) | static void libsais_reconstruct_lms_suffixes_omp(sa_sint_t * RESTRICT SA... function libsais_place_lms_suffixes_interval_8u (line 4599) | static void libsais_place_lms_suffixes_interval_8u(sa_sint_t * RESTRICT ... function libsais_place_lms_suffixes_interval_32s_4k (line 4628) | static void libsais_place_lms_suffixes_interval_32s_4k(sa_sint_t * RESTR... function libsais_place_lms_suffixes_interval_32s_2k (line 4651) | static void libsais_place_lms_suffixes_interval_32s_2k(sa_sint_t * RESTR... function libsais_place_lms_suffixes_interval_32s_1k (line 4677) | static void libsais_place_lms_suffixes_interval_32s_1k(const sa_sint_t *... function libsais_place_lms_suffixes_histogram_32s_6k (line 4705) | static void libsais_place_lms_suffixes_histogram_32s_6k(sa_sint_t * REST... function libsais_place_lms_suffixes_histogram_32s_4k (line 4728) | static void libsais_place_lms_suffixes_histogram_32s_4k(sa_sint_t * REST... function libsais_place_lms_suffixes_histogram_32s_2k (line 4751) | static void libsais_place_lms_suffixes_histogram_32s_2k(sa_sint_t * REST... function libsais_final_bwt_scan_left_to_right_8u (line 4777) | static void libsais_final_bwt_scan_left_to_right_8u(const uint8_t * REST... function libsais_final_bwt_aux_scan_left_to_right_8u (line 4799) | static void libsais_final_bwt_aux_scan_left_to_right_8u(const uint8_t * ... function libsais_final_sorting_scan_left_to_right_8u (line 4821) | static void libsais_final_sorting_scan_left_to_right_8u(const uint8_t * ... function libsais_final_sorting_scan_left_to_right_32s (line 4843) | static void libsais_final_sorting_scan_left_to_right_32s(const sa_sint_t... function fast_sint_t (line 4869) | static fast_sint_t libsais_final_bwt_scan_left_to_right_8u_block_prepare... function fast_sint_t (line 4895) | static fast_sint_t libsais_final_sorting_scan_left_to_right_8u_block_pre... function libsais_final_order_scan_left_to_right_8u_block_place (line 4921) | static void libsais_final_order_scan_left_to_right_8u_block_place(sa_sin... function libsais_final_bwt_aux_scan_left_to_right_8u_block_place (line 4942) | static void libsais_final_bwt_aux_scan_left_to_right_8u_block_place(sa_s... function libsais_final_sorting_scan_left_to_right_32s_block_gather (line 4963) | static void libsais_final_sorting_scan_left_to_right_32s_block_gather(co... function libsais_final_sorting_scan_left_to_right_32s_block_sort (line 4987) | static void libsais_final_sorting_scan_left_to_right_32s_block_sort(cons... function libsais_final_bwt_scan_left_to_right_8u_block_omp (line 5025) | static void libsais_final_bwt_scan_left_to_right_8u_block_omp(const uint... function libsais_final_bwt_aux_scan_left_to_right_8u_block_omp (line 5079) | static void libsais_final_bwt_aux_scan_left_to_right_8u_block_omp(const ... function libsais_final_sorting_scan_left_to_right_8u_block_omp (line 5133) | static void libsais_final_sorting_scan_left_to_right_8u_block_omp(const ... function libsais_final_sorting_scan_left_to_right_32s_block_omp (line 5187) | static void libsais_final_sorting_scan_left_to_right_32s_block_omp(const... function libsais_final_bwt_scan_left_to_right_8u_omp (line 5238) | static void libsais_final_bwt_scan_left_to_right_8u_omp(const uint8_t * ... function libsais_final_bwt_aux_scan_left_to_right_8u_omp (line 5282) | static void libsais_final_bwt_aux_scan_left_to_right_8u_omp(const uint8_... function libsais_final_sorting_scan_left_to_right_8u_omp (line 5328) | static void libsais_final_sorting_scan_left_to_right_8u_omp(const uint8_... function libsais_final_sorting_scan_left_to_right_32s_omp (line 5372) | static void libsais_final_sorting_scan_left_to_right_32s_omp(const sa_si... function sa_sint_t (line 5396) | static sa_sint_t libsais_final_bwt_scan_right_to_left_8u(const uint8_t *... function libsais_final_bwt_aux_scan_right_to_left_8u (line 5424) | static void libsais_final_bwt_aux_scan_right_to_left_8u(const uint8_t * ... function libsais_final_sorting_scan_right_to_left_8u (line 5450) | static void libsais_final_sorting_scan_right_to_left_8u(const uint8_t * ... function libsais_final_gsa_scan_right_to_left_8u (line 5472) | static void libsais_final_gsa_scan_right_to_left_8u(const uint8_t * REST... function libsais_final_sorting_scan_right_to_left_32s (line 5494) | static void libsais_final_sorting_scan_right_to_left_32s(const sa_sint_t... function fast_sint_t (line 5520) | static fast_sint_t libsais_final_bwt_scan_right_to_left_8u_block_prepare... function fast_sint_t (line 5546) | static fast_sint_t libsais_final_bwt_aux_scan_right_to_left_8u_block_pre... function fast_sint_t (line 5572) | static fast_sint_t libsais_final_sorting_scan_right_to_left_8u_block_pre... function libsais_final_order_scan_right_to_left_8u_block_place (line 5598) | static void libsais_final_order_scan_right_to_left_8u_block_place(sa_sin... function libsais_final_gsa_scan_right_to_left_8u_block_place (line 5619) | static void libsais_final_gsa_scan_right_to_left_8u_block_place(sa_sint_... function libsais_final_bwt_aux_scan_right_to_left_8u_block_place (line 5640) | static void libsais_final_bwt_aux_scan_right_to_left_8u_block_place(sa_s... function libsais_final_sorting_scan_right_to_left_32s_block_gather (line 5661) | static void libsais_final_sorting_scan_right_to_left_32s_block_gather(co... function libsais_final_sorting_scan_right_to_left_32s_block_sort (line 5685) | static void libsais_final_sorting_scan_right_to_left_32s_block_sort(cons... function libsais_final_bwt_scan_right_to_left_8u_block_omp (line 5723) | static void libsais_final_bwt_scan_right_to_left_8u_block_omp(const uint... function libsais_final_bwt_aux_scan_right_to_left_8u_block_omp (line 5777) | static void libsais_final_bwt_aux_scan_right_to_left_8u_block_omp(const ... function libsais_final_sorting_scan_right_to_left_8u_block_omp (line 5831) | static void libsais_final_sorting_scan_right_to_left_8u_block_omp(const ... function libsais_final_gsa_scan_right_to_left_8u_block_omp (line 5885) | static void libsais_final_gsa_scan_right_to_left_8u_block_omp(const uint... function libsais_final_sorting_scan_right_to_left_32s_block_omp (line 5939) | static void libsais_final_sorting_scan_right_to_left_32s_block_omp(const... function sa_sint_t (line 5990) | static sa_sint_t libsais_final_bwt_scan_right_to_left_8u_omp(const uint8... function libsais_final_bwt_aux_scan_right_to_left_8u_omp (line 6036) | static void libsais_final_bwt_aux_scan_right_to_left_8u_omp(const uint8_... function libsais_final_sorting_scan_right_to_left_8u_omp (line 6078) | static void libsais_final_sorting_scan_right_to_left_8u_omp(const uint8_... function libsais_final_gsa_scan_right_to_left_8u_omp (line 6120) | static void libsais_final_gsa_scan_right_to_left_8u_omp(const uint8_t * ... function libsais_final_sorting_scan_right_to_left_32s_omp (line 6162) | static void libsais_final_sorting_scan_right_to_left_32s_omp(const sa_si... function libsais_clear_lms_suffixes_omp (line 6184) | static void libsais_clear_lms_suffixes_omp(sa_sint_t * RESTRICT SA, sa_s... function sa_sint_t (line 6202) | static sa_sint_t libsais_induce_final_order_8u_omp(const uint8_t * RESTR... function libsais_induce_final_order_32s_6k (line 6238) | static void libsais_induce_final_order_32s_6k(const sa_sint_t * RESTRICT... function libsais_induce_final_order_32s_4k (line 6244) | static void libsais_induce_final_order_32s_4k(const sa_sint_t * RESTRICT... function libsais_induce_final_order_32s_2k (line 6250) | static void libsais_induce_final_order_32s_2k(const sa_sint_t * RESTRICT... function libsais_induce_final_order_32s_1k (line 6256) | static void libsais_induce_final_order_32s_1k(const sa_sint_t * RESTRICT... function sa_sint_t (line 6267) | static sa_sint_t libsais_renumber_unique_and_nonunique_lms_suffixes_32s(... function libsais_compact_unique_and_nonunique_lms_suffixes_32s (line 6302) | static void libsais_compact_unique_and_nonunique_lms_suffixes_32s(sa_sin... function sa_sint_t (line 6330) | static sa_sint_t libsais_count_unique_suffixes(sa_sint_t * RESTRICT SA, ... function sa_sint_t (line 6362) | static sa_sint_t libsais_renumber_unique_and_nonunique_lms_suffixes_32s_... function libsais_compact_unique_and_nonunique_lms_suffixes_32s_omp (line 6413) | static void libsais_compact_unique_and_nonunique_lms_suffixes_32s_omp(sa... function sa_sint_t (line 6482) | static sa_sint_t libsais_compact_lms_suffixes_32s_omp(sa_sint_t * RESTRI... function libsais_merge_unique_lms_suffixes_32s (line 6490) | static void libsais_merge_unique_lms_suffixes_32s(sa_sint_t * RESTRICT T... function libsais_merge_nonunique_lms_suffixes_32s (line 6513) | static void libsais_merge_nonunique_lms_suffixes_32s(sa_sint_t * RESTRIC... function libsais_merge_unique_lms_suffixes_32s_omp (line 6536) | static void libsais_merge_unique_lms_suffixes_32s_omp(sa_sint_t * RESTRI... function libsais_merge_nonunique_lms_suffixes_32s_omp (line 6578) | static void libsais_merge_nonunique_lms_suffixes_32s_omp(sa_sint_t * RES... function libsais_merge_compacted_lms_suffixes_32s_omp (line 6620) | static void libsais_merge_compacted_lms_suffixes_32s_omp(sa_sint_t * RES... function libsais_reconstruct_compacted_lms_suffixes_32s_2k_omp (line 6626) | static void libsais_reconstruct_compacted_lms_suffixes_32s_2k_omp(sa_sin... function libsais_reconstruct_compacted_lms_suffixes_32s_1k_omp (line 6647) | static void libsais_reconstruct_compacted_lms_suffixes_32s_1k_omp(sa_sin... function sa_sint_t (line 6668) | static sa_sint_t libsais_main_32s_recursion(sa_sint_t * RESTRICT T, sa_s... function sa_sint_t (line 6872) | static sa_sint_t libsais_main_32s_entry(sa_sint_t * RESTRICT T, sa_sint_... function sa_sint_t (line 6879) | static sa_sint_t libsais_main_8u(const uint8_t * T, sa_sint_t * SA, sa_s... function sa_sint_t (line 6925) | static sa_sint_t libsais_main(const uint8_t * T, sa_sint_t * SA, sa_sint... function sa_sint_t (line 6940) | static sa_sint_t libsais_main_int(sa_sint_t * T, sa_sint_t * SA, sa_sint... function sa_sint_t (line 6953) | static sa_sint_t libsais_main_ctx(const LIBSAIS_CONTEXT * ctx, const uin... function libsais_bwt_copy_8u (line 6960) | static void libsais_bwt_copy_8u(uint8_t * RESTRICT U, sa_sint_t * RESTRI... function libsais_bwt_copy_8u_omp (line 6985) | static void libsais_bwt_copy_8u_omp(uint8_t * RESTRICT U, sa_sint_t * RE... function libsais_free_ctx (line 7013) | void libsais_free_ctx(void * ctx) function libsais (line 7018) | int32_t libsais(const uint8_t * T, int32_t * SA, int32_t n, int32_t fs, ... function libsais_gsa (line 7034) | int32_t libsais_gsa(const uint8_t * T, int32_t * SA, int32_t n, int32_t ... function libsais_int (line 7050) | int32_t libsais_int(int32_t * T, int32_t * SA, int32_t n, int32_t k, int... function libsais_ctx (line 7065) | int32_t libsais_ctx(const void * ctx, const uint8_t * T, int32_t * SA, i... function libsais_gsa_ctx (line 7081) | int32_t libsais_gsa_ctx(const void * ctx, const uint8_t * T, int32_t * S... function libsais_bwt (line 7097) | int32_t libsais_bwt(const uint8_t * T, uint8_t * U, int32_t * A, int32_t... function libsais_bwt_aux (line 7123) | int32_t libsais_bwt_aux(const uint8_t * T, uint8_t * U, int32_t * A, int... function libsais_bwt_ctx (line 7148) | int32_t libsais_bwt_ctx(const void * ctx, const uint8_t * T, uint8_t * U... function libsais_bwt_aux_ctx (line 7174) | int32_t libsais_bwt_aux_ctx(const void * ctx, const uint8_t * T, uint8_t... function libsais_omp (line 7211) | int32_t libsais_omp(const uint8_t * T, int32_t * SA, int32_t n, int32_t ... function libsais_gsa_omp (line 7230) | int32_t libsais_gsa_omp(const uint8_t * T, int32_t * SA, int32_t n, int3... function libsais_int_omp (line 7249) | int32_t libsais_int_omp(int32_t * T, int32_t * SA, int32_t n, int32_t k,... function libsais_bwt_omp (line 7267) | int32_t libsais_bwt_omp(const uint8_t * T, uint8_t * U, int32_t * A, int... function libsais_bwt_aux_omp (line 7296) | int32_t libsais_bwt_aux_omp(const uint8_t * T, uint8_t * U, int32_t * A,... function LIBSAIS_UNBWT_CONTEXT (line 7326) | static LIBSAIS_UNBWT_CONTEXT * libsais_unbwt_create_ctx_main(sa_sint_t t... function libsais_unbwt_free_ctx_main (line 7351) | static void libsais_unbwt_free_ctx_main(LIBSAIS_UNBWT_CONTEXT * ctx) function libsais_unbwt_compute_histogram (line 7362) | static void libsais_unbwt_compute_histogram(const uint8_t * RESTRICT T, ... function libsais_unbwt_transpose_bucket2 (line 7431) | static void libsais_unbwt_transpose_bucket2(sa_uint_t * RESTRICT bucket2) function libsais_unbwt_compute_bigram_histogram_single (line 7472) | static void libsais_unbwt_compute_bigram_histogram_single(const uint8_t ... function libsais_unbwt_calculate_fastbits (line 7497) | static void libsais_unbwt_calculate_fastbits(sa_uint_t * RESTRICT bucket... function libsais_unbwt_calculate_biPSI (line 7515) | static void libsais_unbwt_calculate_biPSI(const uint8_t * RESTRICT T, sa... function libsais_unbwt_init_single (line 7550) | static void libsais_unbwt_init_single(const uint8_t * RESTRICT T, sa_uin... function libsais_unbwt_compute_bigram_histogram_parallel (line 7577) | static void libsais_unbwt_compute_bigram_histogram_parallel(const uint8_... function libsais_unbwt_init_parallel (line 7594) | static void libsais_unbwt_init_parallel(const uint8_t * RESTRICT T, sa_u... function libsais_unbwt_decode_1 (line 7714) | static void libsais_unbwt_decode_1(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_2 (line 7728) | static void libsais_unbwt_decode_2(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_3 (line 7744) | static void libsais_unbwt_decode_3(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_4 (line 7762) | static void libsais_unbwt_decode_4(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_5 (line 7782) | static void libsais_unbwt_decode_5(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_6 (line 7804) | static void libsais_unbwt_decode_6(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_7 (line 7828) | static void libsais_unbwt_decode_7(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode_8 (line 7854) | static void libsais_unbwt_decode_8(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais_unbwt_decode (line 7882) | static void libsais_unbwt_decode(uint8_t * RESTRICT U, sa_uint_t * RESTR... function libsais_unbwt_decode_omp (line 7943) | static void libsais_unbwt_decode_omp(const uint8_t * RESTRICT T, uint8_t... function sa_sint_t (line 7975) | static sa_sint_t libsais_unbwt_core(const uint8_t * RESTRICT T, uint8_t ... function sa_sint_t (line 7994) | static sa_sint_t libsais_unbwt_main(const uint8_t * T, uint8_t * U, sa_u... function sa_sint_t (line 8013) | static sa_sint_t libsais_unbwt_main_ctx(const LIBSAIS_UNBWT_CONTEXT * ct... function libsais_unbwt_free_ctx (line 8025) | void libsais_unbwt_free_ctx(void * ctx) function libsais_unbwt (line 8030) | int32_t libsais_unbwt(const uint8_t * T, uint8_t * U, int32_t * A, int32... function libsais_unbwt_ctx (line 8035) | int32_t libsais_unbwt_ctx(const void * ctx, const uint8_t * T, uint8_t *... function libsais_unbwt_aux (line 8040) | int32_t libsais_unbwt_aux(const uint8_t * T, uint8_t * U, int32_t * A, i... function libsais_unbwt_aux_ctx (line 8058) | int32_t libsais_unbwt_aux_ctx(const void * ctx, const uint8_t * T, uint8... function libsais_unbwt_omp (line 8088) | int32_t libsais_unbwt_omp(const uint8_t * T, uint8_t * U, int32_t * A, i... function libsais_unbwt_aux_omp (line 8093) | int32_t libsais_unbwt_aux_omp(const uint8_t * T, uint8_t * U, int32_t * ... function libsais_compute_phi (line 8116) | static void libsais_compute_phi(const sa_sint_t * RESTRICT SA, sa_sint_t... function libsais_compute_phi_omp (line 8144) | static void libsais_compute_phi_omp(const sa_sint_t * RESTRICT SA, sa_si... function libsais_compute_plcp (line 8167) | static void libsais_compute_plcp(const uint8_t * RESTRICT T, sa_sint_t *... function libsais_compute_plcp_omp (line 8192) | static void libsais_compute_plcp_omp(const uint8_t * RESTRICT T, sa_sint... function libsais_compute_plcp_gsa (line 8215) | static void libsais_compute_plcp_gsa(const uint8_t * RESTRICT T, sa_sint... function libsais_compute_plcp_gsa_omp (line 8240) | static void libsais_compute_plcp_gsa_omp(const uint8_t * RESTRICT T, sa_... function libsais_compute_plcp_int (line 8263) | static void libsais_compute_plcp_int(const int32_t * RESTRICT T, sa_sint... function libsais_compute_plcp_int_omp (line 8288) | static void libsais_compute_plcp_int_omp(const int32_t * RESTRICT T, sa_... function libsais_compute_lcp (line 8311) | static void libsais_compute_lcp(const sa_sint_t * RESTRICT PLCP, const s... function libsais_compute_lcp_omp (line 8340) | static void libsais_compute_lcp_omp(const sa_sint_t * RESTRICT PLCP, con... function libsais_plcp (line 8363) | int32_t libsais_plcp(const uint8_t * T, const int32_t * SA, int32_t * PL... function libsais_plcp_gsa (line 8381) | int32_t libsais_plcp_gsa(const uint8_t * T, const int32_t * SA, int32_t ... function libsais_plcp_int (line 8399) | int32_t libsais_plcp_int(const int32_t * T, const int32_t * SA, int32_t ... function libsais_lcp (line 8417) | int32_t libsais_lcp(const int32_t * PLCP, const int32_t * SA, int32_t * ... function libsais_plcp_omp (line 8436) | int32_t libsais_plcp_omp(const uint8_t * T, const int32_t * SA, int32_t ... function libsais_plcp_gsa_omp (line 8457) | int32_t libsais_plcp_gsa_omp(const uint8_t * T, const int32_t * SA, int3... function libsais_plcp_int_omp (line 8478) | int32_t libsais_plcp_int_omp(const int32_t * T, const int32_t * SA, int3... function libsais_lcp_omp (line 8499) | int32_t libsais_lcp_omp(const int32_t * PLCP, const int32_t * SA, int32_... FILE: src/libsais16.c type sa_sint_t (line 38) | typedef int32_t sa_sint_t; type sa_uint_t (line 39) | typedef uint32_t sa_uint_t; type fast_sint_t (line 40) | typedef ptrdiff_t fast_sint_t; type fast_uint_t (line 41) | typedef size_t fast_uint_t; type LIBSAIS_THREAD_CACHE (line 63) | typedef struct LIBSAIS_THREAD_CACHE type LIBSAIS_THREAD_STATE (line 69) | typedef union LIBSAIS_THREAD_STATE type LIBSAIS_CONTEXT (line 86) | typedef struct LIBSAIS_CONTEXT type LIBSAIS_UNBWT_CONTEXT (line 93) | typedef struct LIBSAIS_UNBWT_CONTEXT function libsais16_free_aligned (line 173) | static void libsais16_free_aligned(void * aligned_address) function LIBSAIS_THREAD_STATE (line 181) | static LIBSAIS_THREAD_STATE * libsais16_alloc_thread_state(sa_sint_t thr... function libsais16_free_thread_state (line 205) | static void libsais16_free_thread_state(LIBSAIS_THREAD_STATE * thread_st... function LIBSAIS_CONTEXT (line 215) | static LIBSAIS_CONTEXT * libsais16_create_ctx_main(sa_sint_t threads) function libsais16_free_ctx_main (line 236) | static void libsais16_free_ctx_main(LIBSAIS_CONTEXT * ctx) function sa_sint_t (line 248) | static sa_sint_t libsais16_count_negative_marked_suffixes(sa_sint_t * RE... function sa_sint_t (line 257) | static sa_sint_t libsais16_count_zero_marked_suffixes(sa_sint_t * RESTRI... function libsais16_place_cached_suffixes (line 266) | static void libsais16_place_cached_suffixes(sa_sint_t * RESTRICT SA, LIB... function libsais16_compact_and_place_cached_suffixes (line 292) | static void libsais16_compact_and_place_cached_suffixes(sa_sint_t * REST... function libsais16_accumulate_counts_s32_2 (line 315) | static void libsais16_accumulate_counts_s32_2(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_3 (line 321) | static void libsais16_accumulate_counts_s32_3(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_4 (line 328) | static void libsais16_accumulate_counts_s32_4(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_5 (line 336) | static void libsais16_accumulate_counts_s32_5(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_6 (line 345) | static void libsais16_accumulate_counts_s32_6(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_7 (line 355) | static void libsais16_accumulate_counts_s32_7(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_8 (line 366) | static void libsais16_accumulate_counts_s32_8(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32_9 (line 378) | static void libsais16_accumulate_counts_s32_9(sa_sint_t * RESTRICT bucke... function libsais16_accumulate_counts_s32 (line 391) | static void libsais16_accumulate_counts_s32(sa_sint_t * RESTRICT buckets... function libsais16_flip_suffix_markers_omp (line 414) | static void libsais16_flip_suffix_markers_omp(sa_sint_t * RESTRICT SA, s... function libsais16_gather_lms_suffixes_16u (line 437) | static void libsais16_gather_lms_suffixes_16u(const uint16_t * RESTRICT ... function libsais16_gather_lms_suffixes_16u_omp (line 468) | static void libsais16_gather_lms_suffixes_16u_omp(const uint16_t * RESTR... function sa_sint_t (line 509) | static sa_sint_t libsais16_gather_lms_suffixes_32s(const sa_sint_t * RES... function sa_sint_t (line 538) | static sa_sint_t libsais16_gather_compacted_lms_suffixes_32s(const sa_si... function libsais16_count_lms_suffixes_32s_4k (line 569) | static void libsais16_count_lms_suffixes_32s_4k(const sa_sint_t * RESTRI... function libsais16_count_lms_suffixes_32s_2k (line 614) | static void libsais16_count_lms_suffixes_32s_2k(const sa_sint_t * RESTRI... function libsais16_count_compacted_lms_suffixes_32s_2k (line 659) | static void libsais16_count_compacted_lms_suffixes_32s_2k(const sa_sint_... function sa_sint_t (line 704) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_16u(const uint1... function sa_sint_t (line 750) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_16u_omp(const u... function sa_sint_t (line 817) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_4k(const sa... function sa_sint_t (line 868) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_2k(const sa... function sa_sint_t (line 919) | static sa_sint_t libsais16_count_and_gather_compacted_lms_suffixes_32s_2... function fast_sint_t (line 972) | static fast_sint_t libsais16_get_bucket_stride(fast_sint_t free_space, f... function sa_sint_t (line 980) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_4k_fs_omp(c... function sa_sint_t (line 1048) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_2k_fs_omp(c... function libsais16_count_and_gather_compacted_lms_suffixes_32s_2k_fs_omp (line 1116) | static void libsais16_count_and_gather_compacted_lms_suffixes_32s_2k_fs_... function sa_sint_t (line 1176) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_4k_nofs_omp... function sa_sint_t (line 1211) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_2k_nofs_omp... function sa_sint_t (line 1246) | static sa_sint_t libsais16_count_and_gather_compacted_lms_suffixes_32s_2... function sa_sint_t (line 1281) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_4k_omp(cons... function sa_sint_t (line 1305) | static sa_sint_t libsais16_count_and_gather_lms_suffixes_32s_2k_omp(cons... function libsais16_count_and_gather_compacted_lms_suffixes_32s_2k_omp (line 1329) | static void libsais16_count_and_gather_compacted_lms_suffixes_32s_2k_omp... function libsais16_count_suffixes_32s (line 1349) | static void libsais16_count_suffixes_32s(const sa_sint_t * RESTRICT T, s... function sa_sint_t (line 1376) | static sa_sint_t libsais16_initialize_buckets_start_and_end_16u(sa_sint_... function libsais16_initialize_buckets_start_and_end_32s_6k (line 1407) | static void libsais16_initialize_buckets_start_and_end_32s_6k(sa_sint_t ... function libsais16_initialize_buckets_start_and_end_32s_4k (line 1421) | static void libsais16_initialize_buckets_start_and_end_32s_4k(sa_sint_t ... function libsais16_initialize_buckets_end_32s_2k (line 1435) | static void libsais16_initialize_buckets_end_32s_2k(sa_sint_t k, sa_sint... function libsais16_initialize_buckets_start_and_end_32s_2k (line 1444) | static void libsais16_initialize_buckets_start_and_end_32s_2k(sa_sint_t ... function libsais16_initialize_buckets_start_32s_1k (line 1455) | static void libsais16_initialize_buckets_start_32s_1k(sa_sint_t k, sa_si... function libsais16_initialize_buckets_end_32s_1k (line 1461) | static void libsais16_initialize_buckets_end_32s_1k(sa_sint_t k, sa_sint... function sa_sint_t (line 1467) | static sa_sint_t libsais16_initialize_buckets_for_lms_suffixes_radix_sor... function libsais16_initialize_buckets_for_lms_suffixes_radix_sort_32s_2k (line 1497) | static void libsais16_initialize_buckets_for_lms_suffixes_radix_sort_32s... function sa_sint_t (line 1513) | static sa_sint_t libsais16_initialize_buckets_for_lms_suffixes_radix_sor... function libsais16_initialize_buckets_for_radix_and_partial_sorting_32s_4k (line 1543) | static void libsais16_initialize_buckets_for_radix_and_partial_sorting_3... function libsais16_radix_sort_lms_suffixes_16u (line 1564) | static void libsais16_radix_sort_lms_suffixes_16u(const uint16_t * RESTR... function libsais16_radix_sort_lms_suffixes_16u_omp (line 1590) | static void libsais16_radix_sort_lms_suffixes_16u_omp(const uint16_t * R... function libsais16_radix_sort_lms_suffixes_32s_6k (line 1640) | static void libsais16_radix_sort_lms_suffixes_32s_6k(const sa_sint_t * R... function libsais16_radix_sort_lms_suffixes_32s_2k (line 1671) | static void libsais16_radix_sort_lms_suffixes_32s_2k(const sa_sint_t * R... function libsais16_radix_sort_lms_suffixes_32s_block_gather (line 1704) | static void libsais16_radix_sort_lms_suffixes_32s_block_gather(const sa_... function libsais16_radix_sort_lms_suffixes_32s_6k_block_sort (line 1732) | static void libsais16_radix_sort_lms_suffixes_32s_6k_block_sort(sa_sint_... function libsais16_radix_sort_lms_suffixes_32s_2k_block_sort (line 1758) | static void libsais16_radix_sort_lms_suffixes_32s_2k_block_sort(sa_sint_... function libsais16_radix_sort_lms_suffixes_32s_6k_block_omp (line 1784) | static void libsais16_radix_sort_lms_suffixes_32s_6k_block_omp(const sa_... function libsais16_radix_sort_lms_suffixes_32s_2k_block_omp (line 1833) | static void libsais16_radix_sort_lms_suffixes_32s_2k_block_omp(const sa_... function libsais16_radix_sort_lms_suffixes_32s_6k_omp (line 1884) | static void libsais16_radix_sort_lms_suffixes_32s_6k_omp(const sa_sint_t... function libsais16_radix_sort_lms_suffixes_32s_2k_omp (line 1906) | static void libsais16_radix_sort_lms_suffixes_32s_2k_omp(const sa_sint_t... function sa_sint_t (line 1928) | static sa_sint_t libsais16_radix_sort_lms_suffixes_32s_1k(const sa_sint_... function libsais16_radix_sort_set_markers_32s_6k (line 1976) | static void libsais16_radix_sort_set_markers_32s_6k(sa_sint_t * RESTRICT... function libsais16_radix_sort_set_markers_32s_4k (line 2002) | static void libsais16_radix_sort_set_markers_32s_4k(sa_sint_t * RESTRICT... function libsais16_radix_sort_set_markers_32s_6k_omp (line 2028) | static void libsais16_radix_sort_set_markers_32s_6k_omp(sa_sint_t * REST... function libsais16_radix_sort_set_markers_32s_4k_omp (line 2051) | static void libsais16_radix_sort_set_markers_32s_4k_omp(sa_sint_t * REST... function libsais16_initialize_buckets_for_partial_sorting_16u (line 2074) | static void libsais16_initialize_buckets_for_partial_sorting_16u(const u... function libsais16_initialize_buckets_for_partial_sorting_32s_6k (line 2093) | static void libsais16_initialize_buckets_for_partial_sorting_32s_6k(cons... function sa_sint_t (line 2135) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_16u(const ... function libsais16_partial_sorting_scan_left_to_right_16u_block_prepare (line 2170) | static void libsais16_partial_sorting_scan_left_to_right_16u_block_prepa... function libsais16_partial_sorting_scan_left_to_right_16u_block_place (line 2203) | static void libsais16_partial_sorting_scan_left_to_right_16u_block_place... function sa_sint_t (line 2229) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_16u_block_... function sa_sint_t (line 2296) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_16u_omp(co... function sa_sint_t (line 2347) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_6k(con... function sa_sint_t (line 2380) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_4k(con... function libsais16_partial_sorting_scan_left_to_right_32s_1k (line 2425) | static void libsais16_partial_sorting_scan_left_to_right_32s_1k(const sa... function libsais16_partial_sorting_scan_left_to_right_32s_6k_block_gather (line 2451) | static void libsais16_partial_sorting_scan_left_to_right_32s_6k_block_ga... function libsais16_partial_sorting_scan_left_to_right_32s_4k_block_gather (line 2477) | static void libsais16_partial_sorting_scan_left_to_right_32s_4k_block_ga... function libsais16_partial_sorting_scan_left_to_right_32s_1k_block_gather (line 2501) | static void libsais16_partial_sorting_scan_left_to_right_32s_1k_block_ga... function sa_sint_t (line 2525) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_6k_blo... function sa_sint_t (line 2553) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_4k_blo... function libsais16_partial_sorting_scan_left_to_right_32s_1k_block_sort (line 2596) | static void libsais16_partial_sorting_scan_left_to_right_32s_1k_block_so... function sa_sint_t (line 2634) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_6k_blo... function sa_sint_t (line 2685) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_4k_blo... function libsais16_partial_sorting_scan_left_to_right_32s_1k_block_omp (line 2736) | static void libsais16_partial_sorting_scan_left_to_right_32s_1k_block_om... function sa_sint_t (line 2787) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_6k_omp... function sa_sint_t (line 2814) | static sa_sint_t libsais16_partial_sorting_scan_left_to_right_32s_4k_omp... function libsais16_partial_sorting_scan_left_to_right_32s_1k_omp (line 2844) | static void libsais16_partial_sorting_scan_left_to_right_32s_1k_omp(cons... function libsais16_partial_sorting_shift_markers_16u_omp (line 2868) | static void libsais16_partial_sorting_shift_markers_16u_omp(sa_sint_t * ... function libsais16_partial_sorting_shift_markers_32s_6k_omp (line 2901) | static void libsais16_partial_sorting_shift_markers_32s_6k_omp(sa_sint_t... function libsais16_partial_sorting_shift_markers_32s_4k (line 2934) | static void libsais16_partial_sorting_shift_markers_32s_4k(sa_sint_t * R... function libsais16_partial_sorting_shift_buckets_32s_6k (line 2955) | static void libsais16_partial_sorting_shift_buckets_32s_6k(sa_sint_t k, ... function sa_sint_t (line 2967) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_16u(const ... function sa_sint_t (line 3000) | static sa_sint_t libsais16_partial_gsa_scan_right_to_left_16u(const uint... function libsais16_partial_sorting_scan_right_to_left_16u_block_prepare (line 3035) | static void libsais16_partial_sorting_scan_right_to_left_16u_block_prepa... function libsais16_partial_sorting_scan_right_to_left_16u_block_place (line 3068) | static void libsais16_partial_sorting_scan_right_to_left_16u_block_place... function libsais16_partial_gsa_scan_right_to_left_16u_block_place (line 3094) | static void libsais16_partial_gsa_scan_right_to_left_16u_block_place(sa_... function sa_sint_t (line 3120) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_16u_block_... function sa_sint_t (line 3185) | static sa_sint_t libsais16_partial_gsa_scan_right_to_left_16u_block_omp(... function libsais16_partial_sorting_scan_right_to_left_16u_omp (line 3252) | static void libsais16_partial_sorting_scan_right_to_left_16u_omp(const u... function libsais16_partial_gsa_scan_right_to_left_16u_omp (line 3301) | static void libsais16_partial_gsa_scan_right_to_left_16u_omp(const uint1... function sa_sint_t (line 3350) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_6k(con... function sa_sint_t (line 3383) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_4k(con... function libsais16_partial_sorting_scan_right_to_left_32s_1k (line 3428) | static void libsais16_partial_sorting_scan_right_to_left_32s_1k(const sa... function libsais16_partial_sorting_scan_right_to_left_32s_6k_block_gather (line 3454) | static void libsais16_partial_sorting_scan_right_to_left_32s_6k_block_ga... function libsais16_partial_sorting_scan_right_to_left_32s_4k_block_gather (line 3480) | static void libsais16_partial_sorting_scan_right_to_left_32s_4k_block_ga... function libsais16_partial_sorting_scan_right_to_left_32s_1k_block_gather (line 3504) | static void libsais16_partial_sorting_scan_right_to_left_32s_1k_block_ga... function sa_sint_t (line 3528) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_6k_blo... function sa_sint_t (line 3556) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_4k_blo... function libsais16_partial_sorting_scan_right_to_left_32s_1k_block_sort (line 3599) | static void libsais16_partial_sorting_scan_right_to_left_32s_1k_block_so... function sa_sint_t (line 3637) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_6k_blo... function sa_sint_t (line 3688) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_4k_blo... function libsais16_partial_sorting_scan_right_to_left_32s_1k_block_omp (line 3739) | static void libsais16_partial_sorting_scan_right_to_left_32s_1k_block_om... function sa_sint_t (line 3790) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_6k_omp... function sa_sint_t (line 3817) | static sa_sint_t libsais16_partial_sorting_scan_right_to_left_32s_4k_omp... function libsais16_partial_sorting_scan_right_to_left_32s_1k_omp (line 3841) | static void libsais16_partial_sorting_scan_right_to_left_32s_1k_omp(cons... function fast_sint_t (line 3863) | static fast_sint_t libsais16_partial_sorting_gather_lms_suffixes_32s_4k(... function fast_sint_t (line 3886) | static fast_sint_t libsais16_partial_sorting_gather_lms_suffixes_32s_1k(... function libsais16_partial_sorting_gather_lms_suffixes_32s_4k_omp (line 3909) | static void libsais16_partial_sorting_gather_lms_suffixes_32s_4k_omp(sa_... function libsais16_partial_sorting_gather_lms_suffixes_32s_1k_omp (line 3960) | static void libsais16_partial_sorting_gather_lms_suffixes_32s_1k_omp(sa_... function libsais16_induce_partial_order_16u_omp (line 4011) | static void libsais16_induce_partial_order_16u_omp(const uint16_t * REST... function libsais16_induce_partial_order_32s_6k_omp (line 4042) | static void libsais16_induce_partial_order_32s_6k_omp(const sa_sint_t * ... function libsais16_induce_partial_order_32s_4k_omp (line 4050) | static void libsais16_induce_partial_order_32s_4k_omp(const sa_sint_t * ... function libsais16_induce_partial_order_32s_2k_omp (line 4060) | static void libsais16_induce_partial_order_32s_2k_omp(const sa_sint_t * ... function libsais16_induce_partial_order_32s_1k_omp (line 4067) | static void libsais16_induce_partial_order_32s_1k_omp(const sa_sint_t * ... function sa_sint_t (line 4080) | static sa_sint_t libsais16_renumber_lms_suffixes_16u(sa_sint_t * RESTRIC... function fast_sint_t (line 4110) | static fast_sint_t libsais16_gather_marked_lms_suffixes(sa_sint_t * REST... function sa_sint_t (line 4137) | static sa_sint_t libsais16_renumber_lms_suffixes_16u_omp(sa_sint_t * RES... function libsais16_gather_marked_lms_suffixes_omp (line 4188) | static void libsais16_gather_marked_lms_suffixes_omp(sa_sint_t * RESTRIC... function sa_sint_t (line 4247) | static sa_sint_t libsais16_renumber_and_gather_lms_suffixes_omp(sa_sint_... function sa_sint_t (line 4264) | static sa_sint_t libsais16_renumber_distinct_lms_suffixes_32s_4k(sa_sint... function libsais16_mark_distinct_lms_suffixes_32s (line 4294) | static void libsais16_mark_distinct_lms_suffixes_32s(sa_sint_t * RESTRIC... function libsais16_clamp_lms_suffixes_length_32s (line 4315) | static void libsais16_clamp_lms_suffixes_length_32s(sa_sint_t * RESTRICT... function sa_sint_t (line 4338) | static sa_sint_t libsais16_renumber_distinct_lms_suffixes_32s_4k_omp(sa_... function libsais16_mark_distinct_lms_suffixes_32s_omp (line 4389) | static void libsais16_mark_distinct_lms_suffixes_32s_omp(sa_sint_t * RES... function libsais16_clamp_lms_suffixes_length_32s_omp (line 4411) | static void libsais16_clamp_lms_suffixes_length_32s_omp(sa_sint_t * REST... function sa_sint_t (line 4433) | static sa_sint_t libsais16_renumber_and_mark_distinct_lms_suffixes_32s_4... function sa_sint_t (line 4446) | static sa_sint_t libsais16_renumber_and_mark_distinct_lms_suffixes_32s_1... function libsais16_reconstruct_lms_suffixes (line 4525) | static void libsais16_reconstruct_lms_suffixes(sa_sint_t * RESTRICT SA, ... function libsais16_reconstruct_lms_suffixes_omp (line 4553) | static void libsais16_reconstruct_lms_suffixes_omp(sa_sint_t * RESTRICT ... function libsais16_place_lms_suffixes_interval_16u (line 4576) | static void libsais16_place_lms_suffixes_interval_16u(sa_sint_t * RESTRI... function libsais16_place_lms_suffixes_interval_32s_4k (line 4605) | static void libsais16_place_lms_suffixes_interval_32s_4k(sa_sint_t * RES... function libsais16_place_lms_suffixes_interval_32s_2k (line 4628) | static void libsais16_place_lms_suffixes_interval_32s_2k(sa_sint_t * RES... function libsais16_place_lms_suffixes_interval_32s_1k (line 4654) | static void libsais16_place_lms_suffixes_interval_32s_1k(const sa_sint_t... function libsais16_place_lms_suffixes_histogram_32s_6k (line 4682) | static void libsais16_place_lms_suffixes_histogram_32s_6k(sa_sint_t * RE... function libsais16_place_lms_suffixes_histogram_32s_4k (line 4705) | static void libsais16_place_lms_suffixes_histogram_32s_4k(sa_sint_t * RE... function libsais16_place_lms_suffixes_histogram_32s_2k (line 4728) | static void libsais16_place_lms_suffixes_histogram_32s_2k(sa_sint_t * RE... function libsais16_final_bwt_scan_left_to_right_16u (line 4754) | static void libsais16_final_bwt_scan_left_to_right_16u(const uint16_t * ... function libsais16_final_bwt_aux_scan_left_to_right_16u (line 4776) | static void libsais16_final_bwt_aux_scan_left_to_right_16u(const uint16_... function libsais16_final_sorting_scan_left_to_right_16u (line 4798) | static void libsais16_final_sorting_scan_left_to_right_16u(const uint16_... function libsais16_final_sorting_scan_left_to_right_32s (line 4820) | static void libsais16_final_sorting_scan_left_to_right_32s(const sa_sint... function fast_sint_t (line 4846) | static fast_sint_t libsais16_final_bwt_scan_left_to_right_16u_block_prep... function fast_sint_t (line 4872) | static fast_sint_t libsais16_final_sorting_scan_left_to_right_16u_block_... function libsais16_final_order_scan_left_to_right_16u_block_place (line 4898) | static void libsais16_final_order_scan_left_to_right_16u_block_place(sa_... function libsais16_final_bwt_aux_scan_left_to_right_16u_block_place (line 4919) | static void libsais16_final_bwt_aux_scan_left_to_right_16u_block_place(s... function libsais16_final_sorting_scan_left_to_right_32s_block_gather (line 4940) | static void libsais16_final_sorting_scan_left_to_right_32s_block_gather(... function libsais16_final_sorting_scan_left_to_right_32s_block_sort (line 4964) | static void libsais16_final_sorting_scan_left_to_right_32s_block_sort(co... function libsais16_final_bwt_scan_left_to_right_16u_block_omp (line 5002) | static void libsais16_final_bwt_scan_left_to_right_16u_block_omp(const u... function libsais16_final_bwt_aux_scan_left_to_right_16u_block_omp (line 5056) | static void libsais16_final_bwt_aux_scan_left_to_right_16u_block_omp(con... function libsais16_final_sorting_scan_left_to_right_16u_block_omp (line 5110) | static void libsais16_final_sorting_scan_left_to_right_16u_block_omp(con... function libsais16_final_sorting_scan_left_to_right_32s_block_omp (line 5164) | static void libsais16_final_sorting_scan_left_to_right_32s_block_omp(con... function libsais16_final_bwt_scan_left_to_right_16u_omp (line 5215) | static void libsais16_final_bwt_scan_left_to_right_16u_omp(const uint16_... function libsais16_final_bwt_aux_scan_left_to_right_16u_omp (line 5259) | static void libsais16_final_bwt_aux_scan_left_to_right_16u_omp(const uin... function libsais16_final_sorting_scan_left_to_right_16u_omp (line 5305) | static void libsais16_final_sorting_scan_left_to_right_16u_omp(const uin... function libsais16_final_sorting_scan_left_to_right_32s_omp (line 5349) | static void libsais16_final_sorting_scan_left_to_right_32s_omp(const sa_... function sa_sint_t (line 5373) | static sa_sint_t libsais16_final_bwt_scan_right_to_left_16u(const uint16... function libsais16_final_bwt_aux_scan_right_to_left_16u (line 5401) | static void libsais16_final_bwt_aux_scan_right_to_left_16u(const uint16_... function libsais16_final_sorting_scan_right_to_left_16u (line 5427) | static void libsais16_final_sorting_scan_right_to_left_16u(const uint16_... function libsais16_final_gsa_scan_right_to_left_16u (line 5449) | static void libsais16_final_gsa_scan_right_to_left_16u(const uint16_t * ... function libsais16_final_sorting_scan_right_to_left_32s (line 5471) | static void libsais16_final_sorting_scan_right_to_left_32s(const sa_sint... function fast_sint_t (line 5497) | static fast_sint_t libsais16_final_bwt_scan_right_to_left_16u_block_prep... function fast_sint_t (line 5523) | static fast_sint_t libsais16_final_bwt_aux_scan_right_to_left_16u_block_... function fast_sint_t (line 5549) | static fast_sint_t libsais16_final_sorting_scan_right_to_left_16u_block_... function libsais16_final_order_scan_right_to_left_16u_block_place (line 5575) | static void libsais16_final_order_scan_right_to_left_16u_block_place(sa_... function libsais16_final_gsa_scan_right_to_left_16u_block_place (line 5596) | static void libsais16_final_gsa_scan_right_to_left_16u_block_place(sa_si... function libsais16_final_bwt_aux_scan_right_to_left_16u_block_place (line 5617) | static void libsais16_final_bwt_aux_scan_right_to_left_16u_block_place(s... function libsais16_final_sorting_scan_right_to_left_32s_block_gather (line 5638) | static void libsais16_final_sorting_scan_right_to_left_32s_block_gather(... function libsais16_final_sorting_scan_right_to_left_32s_block_sort (line 5662) | static void libsais16_final_sorting_scan_right_to_left_32s_block_sort(co... function libsais16_final_bwt_scan_right_to_left_16u_block_omp (line 5700) | static void libsais16_final_bwt_scan_right_to_left_16u_block_omp(const u... function libsais16_final_bwt_aux_scan_right_to_left_16u_block_omp (line 5754) | static void libsais16_final_bwt_aux_scan_right_to_left_16u_block_omp(con... function libsais16_final_sorting_scan_right_to_left_16u_block_omp (line 5808) | static void libsais16_final_sorting_scan_right_to_left_16u_block_omp(con... function libsais16_final_gsa_scan_right_to_left_16u_block_omp (line 5862) | static void libsais16_final_gsa_scan_right_to_left_16u_block_omp(const u... function libsais16_final_sorting_scan_right_to_left_32s_block_omp (line 5916) | static void libsais16_final_sorting_scan_right_to_left_32s_block_omp(con... function sa_sint_t (line 5967) | static sa_sint_t libsais16_final_bwt_scan_right_to_left_16u_omp(const ui... function libsais16_final_bwt_aux_scan_right_to_left_16u_omp (line 6013) | static void libsais16_final_bwt_aux_scan_right_to_left_16u_omp(const uin... function libsais16_final_sorting_scan_right_to_left_16u_omp (line 6055) | static void libsais16_final_sorting_scan_right_to_left_16u_omp(const uin... function libsais16_final_gsa_scan_right_to_left_16u_omp (line 6097) | static void libsais16_final_gsa_scan_right_to_left_16u_omp(const uint16_... function libsais16_final_sorting_scan_right_to_left_32s_omp (line 6139) | static void libsais16_final_sorting_scan_right_to_left_32s_omp(const sa_... function libsais16_clear_lms_suffixes_omp (line 6161) | static void libsais16_clear_lms_suffixes_omp(sa_sint_t * RESTRICT SA, sa... function sa_sint_t (line 6179) | static sa_sint_t libsais16_induce_final_order_16u_omp(const uint16_t * R... function libsais16_induce_final_order_32s_6k (line 6215) | static void libsais16_induce_final_order_32s_6k(const sa_sint_t * RESTRI... function libsais16_induce_final_order_32s_4k (line 6221) | static void libsais16_induce_final_order_32s_4k(const sa_sint_t * RESTRI... function libsais16_induce_final_order_32s_2k (line 6227) | static void libsais16_induce_final_order_32s_2k(const sa_sint_t * RESTRI... function libsais16_induce_final_order_32s_1k (line 6233) | static void libsais16_induce_final_order_32s_1k(const sa_sint_t * RESTRI... function sa_sint_t (line 6244) | static sa_sint_t libsais16_renumber_unique_and_nonunique_lms_suffixes_32... function libsais16_compact_unique_and_nonunique_lms_suffixes_32s (line 6279) | static void libsais16_compact_unique_and_nonunique_lms_suffixes_32s(sa_s... function sa_sint_t (line 6307) | static sa_sint_t libsais16_count_unique_suffixes(sa_sint_t * RESTRICT SA... function sa_sint_t (line 6339) | static sa_sint_t libsais16_renumber_unique_and_nonunique_lms_suffixes_32... function libsais16_compact_unique_and_nonunique_lms_suffixes_32s_omp (line 6390) | static void libsais16_compact_unique_and_nonunique_lms_suffixes_32s_omp(... function sa_sint_t (line 6459) | static sa_sint_t libsais16_compact_lms_suffixes_32s_omp(sa_sint_t * REST... function libsais16_merge_unique_lms_suffixes_32s (line 6467) | static void libsais16_merge_unique_lms_suffixes_32s(sa_sint_t * RESTRICT... function libsais16_merge_nonunique_lms_suffixes_32s (line 6490) | static void libsais16_merge_nonunique_lms_suffixes_32s(sa_sint_t * RESTR... function libsais16_merge_unique_lms_suffixes_32s_omp (line 6513) | static void libsais16_merge_unique_lms_suffixes_32s_omp(sa_sint_t * REST... function libsais16_merge_nonunique_lms_suffixes_32s_omp (line 6555) | static void libsais16_merge_nonunique_lms_suffixes_32s_omp(sa_sint_t * R... function libsais16_merge_compacted_lms_suffixes_32s_omp (line 6597) | static void libsais16_merge_compacted_lms_suffixes_32s_omp(sa_sint_t * R... function libsais16_reconstruct_compacted_lms_suffixes_32s_2k_omp (line 6603) | static void libsais16_reconstruct_compacted_lms_suffixes_32s_2k_omp(sa_s... function libsais16_reconstruct_compacted_lms_suffixes_32s_1k_omp (line 6624) | static void libsais16_reconstruct_compacted_lms_suffixes_32s_1k_omp(sa_s... function sa_sint_t (line 6645) | static sa_sint_t libsais16_main_32s_recursion(sa_sint_t * RESTRICT T, sa... function sa_sint_t (line 6849) | static sa_sint_t libsais16_main_32s_entry(sa_sint_t * RESTRICT T, sa_sin... function sa_sint_t (line 6856) | static sa_sint_t libsais16_main_16u(const uint16_t * T, sa_sint_t * SA, ... function sa_sint_t (line 6902) | static sa_sint_t libsais16_main(const uint16_t * T, sa_sint_t * SA, sa_s... function sa_sint_t (line 6917) | static sa_sint_t libsais16_main_int(sa_sint_t * T, sa_sint_t * SA, sa_si... function sa_sint_t (line 6930) | static sa_sint_t libsais16_main_ctx(const LIBSAIS_CONTEXT * ctx, const u... function libsais16_bwt_copy_16u (line 6937) | static void libsais16_bwt_copy_16u(uint16_t * RESTRICT U, sa_sint_t * RE... function libsais16_bwt_copy_16u_omp (line 6962) | static void libsais16_bwt_copy_16u_omp(uint16_t * RESTRICT U, sa_sint_t ... function libsais16_free_ctx (line 6990) | void libsais16_free_ctx(void * ctx) function libsais16 (line 6995) | int32_t libsais16(const uint16_t * T, int32_t * SA, int32_t n, int32_t f... function libsais16_gsa (line 7011) | int32_t libsais16_gsa(const uint16_t * T, int32_t * SA, int32_t n, int32... function libsais16_int (line 7027) | int32_t libsais16_int(int32_t * T, int32_t * SA, int32_t n, int32_t k, i... function libsais16_ctx (line 7042) | int32_t libsais16_ctx(const void * ctx, const uint16_t * T, int32_t * SA... function libsais16_gsa_ctx (line 7058) | int32_t libsais16_gsa_ctx(const void * ctx, const uint16_t * T, int32_t ... function libsais16_bwt (line 7074) | int32_t libsais16_bwt(const uint16_t * T, uint16_t * U, int32_t * A, int... function libsais16_bwt_aux (line 7100) | int32_t libsais16_bwt_aux(const uint16_t * T, uint16_t * U, int32_t * A,... function libsais16_bwt_ctx (line 7125) | int32_t libsais16_bwt_ctx(const void * ctx, const uint16_t * T, uint16_t... function libsais16_bwt_aux_ctx (line 7151) | int32_t libsais16_bwt_aux_ctx(const void * ctx, const uint16_t * T, uint... function libsais16_omp (line 7188) | int32_t libsais16_omp(const uint16_t * T, int32_t * SA, int32_t n, int32... function libsais16_gsa_omp (line 7207) | int32_t libsais16_gsa_omp(const uint16_t * T, int32_t * SA, int32_t n, i... function libsais16_int_omp (line 7226) | int32_t libsais16_int_omp(int32_t * T, int32_t * SA, int32_t n, int32_t ... function libsais16_bwt_omp (line 7244) | int32_t libsais16_bwt_omp(const uint16_t * T, uint16_t * U, int32_t * A,... function libsais16_bwt_aux_omp (line 7273) | int32_t libsais16_bwt_aux_omp(const uint16_t * T, uint16_t * U, int32_t ... function LIBSAIS_UNBWT_CONTEXT (line 7303) | static LIBSAIS_UNBWT_CONTEXT * libsais16_unbwt_create_ctx_main(sa_sint_t... function libsais16_unbwt_free_ctx_main (line 7328) | static void libsais16_unbwt_free_ctx_main(LIBSAIS_UNBWT_CONTEXT * ctx) function libsais16_unbwt_compute_histogram (line 7339) | static void libsais16_unbwt_compute_histogram(const uint16_t * RESTRICT ... function libsais16_unbwt_calculate_fastbits (line 7344) | static void libsais16_unbwt_calculate_fastbits(sa_uint_t * RESTRICT buck... function libsais16_unbwt_calculate_P (line 7357) | static void libsais16_unbwt_calculate_P(const uint16_t * RESTRICT T, sa_... function libsais16_unbwt_init_single (line 7370) | static void libsais16_unbwt_init_single(const uint16_t * RESTRICT T, sa_... function libsais16_unbwt_init_parallel (line 7391) | static void libsais16_unbwt_init_parallel(const uint16_t * RESTRICT T, s... function libsais16_unbwt_decode_1 (line 7466) | static void libsais16_unbwt_decode_1(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_2 (line 7480) | static void libsais16_unbwt_decode_2(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_3 (line 7496) | static void libsais16_unbwt_decode_3(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_4 (line 7514) | static void libsais16_unbwt_decode_4(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_5 (line 7534) | static void libsais16_unbwt_decode_5(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_6 (line 7556) | static void libsais16_unbwt_decode_6(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_7 (line 7580) | static void libsais16_unbwt_decode_7(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode_8 (line 7606) | static void libsais16_unbwt_decode_8(uint16_t * RESTRICT U, sa_uint_t * ... function libsais16_unbwt_decode (line 7634) | static void libsais16_unbwt_decode(uint16_t * RESTRICT U, sa_uint_t * RE... function libsais16_unbwt_decode_omp (line 7695) | static void libsais16_unbwt_decode_omp(uint16_t * RESTRICT U, sa_uint_t ... function sa_sint_t (line 7724) | static sa_sint_t libsais16_unbwt_core(const uint16_t * RESTRICT T, uint1... function sa_sint_t (line 7743) | static sa_sint_t libsais16_unbwt_main(const uint16_t * T, uint16_t * U, ... function sa_sint_t (line 7762) | static sa_sint_t libsais16_unbwt_main_ctx(const LIBSAIS_UNBWT_CONTEXT * ... function libsais16_unbwt_free_ctx (line 7774) | void libsais16_unbwt_free_ctx(void * ctx) function libsais16_unbwt (line 7779) | int32_t libsais16_unbwt(const uint16_t * T, uint16_t * U, int32_t * A, i... function libsais16_unbwt_ctx (line 7784) | int32_t libsais16_unbwt_ctx(const void * ctx, const uint16_t * T, uint16... function libsais16_unbwt_aux (line 7789) | int32_t libsais16_unbwt_aux(const uint16_t * T, uint16_t * U, int32_t * ... function libsais16_unbwt_aux_ctx (line 7807) | int32_t libsais16_unbwt_aux_ctx(const void * ctx, const uint16_t * T, ui... function libsais16_unbwt_omp (line 7837) | int32_t libsais16_unbwt_omp(const uint16_t * T, uint16_t * U, int32_t * ... function libsais16_unbwt_aux_omp (line 7842) | int32_t libsais16_unbwt_aux_omp(const uint16_t * T, uint16_t * U, int32_... function libsais16_compute_phi (line 7865) | static void libsais16_compute_phi(const sa_sint_t * RESTRICT SA, sa_sint... function libsais16_compute_phi_omp (line 7893) | static void libsais16_compute_phi_omp(const sa_sint_t * RESTRICT SA, sa_... function libsais16_compute_plcp (line 7916) | static void libsais16_compute_plcp(const uint16_t * RESTRICT T, sa_sint_... function libsais16_compute_plcp_omp (line 7941) | static void libsais16_compute_plcp_omp(const uint16_t * RESTRICT T, sa_s... function libsais16_compute_plcp_gsa (line 7964) | static void libsais16_compute_plcp_gsa(const uint16_t * RESTRICT T, sa_s... function libsais16_compute_plcp_gsa_omp (line 7989) | static void libsais16_compute_plcp_gsa_omp(const uint16_t * RESTRICT T, ... function libsais16_compute_lcp (line 8012) | static void libsais16_compute_lcp(const sa_sint_t * RESTRICT PLCP, const... function libsais16_compute_lcp_omp (line 8041) | static void libsais16_compute_lcp_omp(const sa_sint_t * RESTRICT PLCP, c... function libsais16_plcp (line 8064) | int32_t libsais16_plcp(const uint16_t * T, const int32_t * SA, int32_t *... function libsais16_plcp_gsa (line 8082) | int32_t libsais16_plcp_gsa(const uint16_t * T, const int32_t * SA, int32... function libsais16_lcp (line 8100) | int32_t libsais16_lcp(const int32_t * PLCP, const int32_t * SA, int32_t ... function libsais16_plcp_omp (line 8119) | int32_t libsais16_plcp_omp(const uint16_t * T, const int32_t * SA, int32... function libsais16_plcp_gsa_omp (line 8140) | int32_t libsais16_plcp_gsa_omp(const uint16_t * T, const int32_t * SA, i... function libsais16_lcp_omp (line 8161) | int32_t libsais16_lcp_omp(const int32_t * PLCP, const int32_t * SA, int3... FILE: src/libsais16x64.c type sa_sint_t (line 39) | typedef int64_t sa_sint_t; type sa_uint_t (line 40) | typedef uint64_t sa_uint_t; type fast_sint_t (line 41) | typedef int64_t fast_sint_t; type fast_uint_t (line 42) | typedef uint64_t fast_uint_t; type LIBSAIS_THREAD_CACHE (line 64) | typedef struct LIBSAIS_THREAD_CACHE type LIBSAIS_THREAD_STATE (line 70) | typedef union LIBSAIS_THREAD_STATE type LIBSAIS_CONTEXT (line 87) | typedef struct LIBSAIS_CONTEXT type LIBSAIS_UNBWT_CONTEXT (line 94) | typedef struct LIBSAIS_UNBWT_CONTEXT function libsais16x64_free_aligned (line 174) | static void libsais16x64_free_aligned(void * aligned_address) function LIBSAIS_THREAD_STATE (line 182) | static LIBSAIS_THREAD_STATE * libsais16x64_alloc_thread_state(sa_sint_t ... function libsais16x64_free_thread_state (line 206) | static void libsais16x64_free_thread_state(LIBSAIS_THREAD_STATE * thread... function sa_sint_t (line 218) | static sa_sint_t libsais16x64_count_negative_marked_suffixes(sa_sint_t *... function sa_sint_t (line 227) | static sa_sint_t libsais16x64_count_zero_marked_suffixes(sa_sint_t * RES... function libsais16x64_place_cached_suffixes (line 236) | static void libsais16x64_place_cached_suffixes(sa_sint_t * RESTRICT SA, ... function libsais16x64_compact_and_place_cached_suffixes (line 262) | static void libsais16x64_compact_and_place_cached_suffixes(sa_sint_t * R... function libsais16x64_accumulate_counts_s32_2 (line 285) | static void libsais16x64_accumulate_counts_s32_2(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_3 (line 291) | static void libsais16x64_accumulate_counts_s32_3(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_4 (line 298) | static void libsais16x64_accumulate_counts_s32_4(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_5 (line 306) | static void libsais16x64_accumulate_counts_s32_5(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_6 (line 315) | static void libsais16x64_accumulate_counts_s32_6(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_7 (line 325) | static void libsais16x64_accumulate_counts_s32_7(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_8 (line 336) | static void libsais16x64_accumulate_counts_s32_8(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32_9 (line 348) | static void libsais16x64_accumulate_counts_s32_9(sa_sint_t * RESTRICT bu... function libsais16x64_accumulate_counts_s32 (line 361) | static void libsais16x64_accumulate_counts_s32(sa_sint_t * RESTRICT buck... function libsais16x64_flip_suffix_markers_omp (line 384) | static void libsais16x64_flip_suffix_markers_omp(sa_sint_t * RESTRICT SA... function libsais16x64_gather_lms_suffixes_16u (line 407) | static void libsais16x64_gather_lms_suffixes_16u(const uint16_t * RESTRI... function libsais16x64_gather_lms_suffixes_16u_omp (line 438) | static void libsais16x64_gather_lms_suffixes_16u_omp(const uint16_t * RE... function sa_sint_t (line 479) | static sa_sint_t libsais16x64_gather_lms_suffixes_32s(const sa_sint_t * ... function sa_sint_t (line 508) | static sa_sint_t libsais16x64_gather_compacted_lms_suffixes_32s(const sa... function libsais16x64_count_lms_suffixes_32s_4k (line 539) | static void libsais16x64_count_lms_suffixes_32s_4k(const sa_sint_t * RES... function libsais16x64_count_lms_suffixes_32s_2k (line 584) | static void libsais16x64_count_lms_suffixes_32s_2k(const sa_sint_t * RES... function libsais16x64_count_compacted_lms_suffixes_32s_2k (line 629) | static void libsais16x64_count_compacted_lms_suffixes_32s_2k(const sa_si... function sa_sint_t (line 674) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_16u(const ui... function sa_sint_t (line 720) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_16u_omp(cons... function sa_sint_t (line 787) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_4k(const... function sa_sint_t (line 838) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_2k(const... function sa_sint_t (line 889) | static sa_sint_t libsais16x64_count_and_gather_compacted_lms_suffixes_32... function fast_sint_t (line 942) | static fast_sint_t libsais16x64_get_bucket_stride(fast_sint_t free_space... function sa_sint_t (line 950) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_4k_fs_om... function sa_sint_t (line 1018) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_2k_fs_om... function libsais16x64_count_and_gather_compacted_lms_suffixes_32s_2k_fs_omp (line 1086) | static void libsais16x64_count_and_gather_compacted_lms_suffixes_32s_2k_... function sa_sint_t (line 1146) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_4k_nofs_... function sa_sint_t (line 1181) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_2k_nofs_... function sa_sint_t (line 1216) | static sa_sint_t libsais16x64_count_and_gather_compacted_lms_suffixes_32... function sa_sint_t (line 1251) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_4k_omp(c... function sa_sint_t (line 1275) | static sa_sint_t libsais16x64_count_and_gather_lms_suffixes_32s_2k_omp(c... function libsais16x64_count_and_gather_compacted_lms_suffixes_32s_2k_omp (line 1299) | static void libsais16x64_count_and_gather_compacted_lms_suffixes_32s_2k_... function libsais16x64_count_suffixes_32s (line 1319) | static void libsais16x64_count_suffixes_32s(const sa_sint_t * RESTRICT T... function sa_sint_t (line 1346) | static sa_sint_t libsais16x64_initialize_buckets_start_and_end_16u(sa_si... function libsais16x64_initialize_buckets_start_and_end_32s_6k (line 1377) | static void libsais16x64_initialize_buckets_start_and_end_32s_6k(sa_sint... function libsais16x64_initialize_buckets_start_and_end_32s_4k (line 1391) | static void libsais16x64_initialize_buckets_start_and_end_32s_4k(sa_sint... function libsais16x64_initialize_buckets_end_32s_2k (line 1405) | static void libsais16x64_initialize_buckets_end_32s_2k(sa_sint_t k, sa_s... function libsais16x64_initialize_buckets_start_and_end_32s_2k (line 1414) | static void libsais16x64_initialize_buckets_start_and_end_32s_2k(sa_sint... function libsais16x64_initialize_buckets_start_32s_1k (line 1425) | static void libsais16x64_initialize_buckets_start_32s_1k(sa_sint_t k, sa... function libsais16x64_initialize_buckets_end_32s_1k (line 1431) | static void libsais16x64_initialize_buckets_end_32s_1k(sa_sint_t k, sa_s... function sa_sint_t (line 1437) | static sa_sint_t libsais16x64_initialize_buckets_for_lms_suffixes_radix_... function libsais16x64_initialize_buckets_for_lms_suffixes_radix_sort_32s_2k (line 1467) | static void libsais16x64_initialize_buckets_for_lms_suffixes_radix_sort_... function sa_sint_t (line 1483) | static sa_sint_t libsais16x64_initialize_buckets_for_lms_suffixes_radix_... function libsais16x64_initialize_buckets_for_radix_and_partial_sorting_32s_4k (line 1513) | static void libsais16x64_initialize_buckets_for_radix_and_partial_sortin... function libsais16x64_radix_sort_lms_suffixes_16u (line 1534) | static void libsais16x64_radix_sort_lms_suffixes_16u(const uint16_t * RE... function libsais16x64_radix_sort_lms_suffixes_16u_omp (line 1560) | static void libsais16x64_radix_sort_lms_suffixes_16u_omp(const uint16_t ... function libsais16x64_radix_sort_lms_suffixes_32s_6k (line 1610) | static void libsais16x64_radix_sort_lms_suffixes_32s_6k(const sa_sint_t ... function libsais16x64_radix_sort_lms_suffixes_32s_2k (line 1641) | static void libsais16x64_radix_sort_lms_suffixes_32s_2k(const sa_sint_t ... function libsais16x64_radix_sort_lms_suffixes_32s_block_gather (line 1674) | static void libsais16x64_radix_sort_lms_suffixes_32s_block_gather(const ... function libsais16x64_radix_sort_lms_suffixes_32s_6k_block_sort (line 1702) | static void libsais16x64_radix_sort_lms_suffixes_32s_6k_block_sort(sa_si... function libsais16x64_radix_sort_lms_suffixes_32s_2k_block_sort (line 1728) | static void libsais16x64_radix_sort_lms_suffixes_32s_2k_block_sort(sa_si... function libsais16x64_radix_sort_lms_suffixes_32s_6k_block_omp (line 1754) | static void libsais16x64_radix_sort_lms_suffixes_32s_6k_block_omp(const ... function libsais16x64_radix_sort_lms_suffixes_32s_2k_block_omp (line 1803) | static void libsais16x64_radix_sort_lms_suffixes_32s_2k_block_omp(const ... function libsais16x64_radix_sort_lms_suffixes_32s_6k_omp (line 1854) | static void libsais16x64_radix_sort_lms_suffixes_32s_6k_omp(const sa_sin... function libsais16x64_radix_sort_lms_suffixes_32s_2k_omp (line 1876) | static void libsais16x64_radix_sort_lms_suffixes_32s_2k_omp(const sa_sin... function sa_sint_t (line 1898) | static sa_sint_t libsais16x64_radix_sort_lms_suffixes_32s_1k(const sa_si... function libsais16x64_radix_sort_set_markers_32s_6k (line 1946) | static void libsais16x64_radix_sort_set_markers_32s_6k(sa_sint_t * RESTR... function libsais16x64_radix_sort_set_markers_32s_4k (line 1972) | static void libsais16x64_radix_sort_set_markers_32s_4k(sa_sint_t * RESTR... function libsais16x64_radix_sort_set_markers_32s_6k_omp (line 1998) | static void libsais16x64_radix_sort_set_markers_32s_6k_omp(sa_sint_t * R... function libsais16x64_radix_sort_set_markers_32s_4k_omp (line 2021) | static void libsais16x64_radix_sort_set_markers_32s_4k_omp(sa_sint_t * R... function libsais16x64_initialize_buckets_for_partial_sorting_16u (line 2044) | static void libsais16x64_initialize_buckets_for_partial_sorting_16u(cons... function libsais16x64_initialize_buckets_for_partial_sorting_32s_6k (line 2063) | static void libsais16x64_initialize_buckets_for_partial_sorting_32s_6k(c... function sa_sint_t (line 2105) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_16u(con... function libsais16x64_partial_sorting_scan_left_to_right_16u_block_prepare (line 2140) | static void libsais16x64_partial_sorting_scan_left_to_right_16u_block_pr... function libsais16x64_partial_sorting_scan_left_to_right_16u_block_place (line 2173) | static void libsais16x64_partial_sorting_scan_left_to_right_16u_block_pl... function sa_sint_t (line 2199) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_16u_blo... function sa_sint_t (line 2266) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_16u_omp... function sa_sint_t (line 2317) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_6k(... function sa_sint_t (line 2350) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_4k(... function libsais16x64_partial_sorting_scan_left_to_right_32s_1k (line 2395) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_1k(const... function libsais16x64_partial_sorting_scan_left_to_right_32s_6k_block_gather (line 2421) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_6k_block... function libsais16x64_partial_sorting_scan_left_to_right_32s_4k_block_gather (line 2447) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_4k_block... function libsais16x64_partial_sorting_scan_left_to_right_32s_1k_block_gather (line 2471) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_1k_block... function sa_sint_t (line 2495) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_6k_... function sa_sint_t (line 2523) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_4k_... function libsais16x64_partial_sorting_scan_left_to_right_32s_1k_block_sort (line 2566) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_1k_block... function sa_sint_t (line 2604) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_6k_... function sa_sint_t (line 2655) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_4k_... function libsais16x64_partial_sorting_scan_left_to_right_32s_1k_block_omp (line 2706) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_1k_block... function sa_sint_t (line 2757) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_6k_... function sa_sint_t (line 2784) | static sa_sint_t libsais16x64_partial_sorting_scan_left_to_right_32s_4k_... function libsais16x64_partial_sorting_scan_left_to_right_32s_1k_omp (line 2814) | static void libsais16x64_partial_sorting_scan_left_to_right_32s_1k_omp(c... function libsais16x64_partial_sorting_shift_markers_16u_omp (line 2838) | static void libsais16x64_partial_sorting_shift_markers_16u_omp(sa_sint_t... function libsais16x64_partial_sorting_shift_markers_32s_6k_omp (line 2871) | static void libsais16x64_partial_sorting_shift_markers_32s_6k_omp(sa_sin... function libsais16x64_partial_sorting_shift_markers_32s_4k (line 2904) | static void libsais16x64_partial_sorting_shift_markers_32s_4k(sa_sint_t ... function libsais16x64_partial_sorting_shift_buckets_32s_6k (line 2925) | static void libsais16x64_partial_sorting_shift_buckets_32s_6k(sa_sint_t ... function sa_sint_t (line 2937) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_16u(con... function sa_sint_t (line 2970) | static sa_sint_t libsais16x64_partial_gsa_scan_right_to_left_16u(const u... function libsais16x64_partial_sorting_scan_right_to_left_16u_block_prepare (line 3005) | static void libsais16x64_partial_sorting_scan_right_to_left_16u_block_pr... function libsais16x64_partial_sorting_scan_right_to_left_16u_block_place (line 3038) | static void libsais16x64_partial_sorting_scan_right_to_left_16u_block_pl... function libsais16x64_partial_gsa_scan_right_to_left_16u_block_place (line 3064) | static void libsais16x64_partial_gsa_scan_right_to_left_16u_block_place(... function sa_sint_t (line 3090) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_16u_blo... function sa_sint_t (line 3155) | static sa_sint_t libsais16x64_partial_gsa_scan_right_to_left_16u_block_o... function libsais16x64_partial_sorting_scan_right_to_left_16u_omp (line 3223) | static void libsais16x64_partial_sorting_scan_right_to_left_16u_omp(cons... function libsais16x64_partial_gsa_scan_right_to_left_16u_omp (line 3272) | static void libsais16x64_partial_gsa_scan_right_to_left_16u_omp(const ui... function sa_sint_t (line 3321) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_6k(... function sa_sint_t (line 3354) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_4k(... function libsais16x64_partial_sorting_scan_right_to_left_32s_1k (line 3399) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_1k(const... function libsais16x64_partial_sorting_scan_right_to_left_32s_6k_block_gather (line 3425) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_6k_block... function libsais16x64_partial_sorting_scan_right_to_left_32s_4k_block_gather (line 3451) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_4k_block... function libsais16x64_partial_sorting_scan_right_to_left_32s_1k_block_gather (line 3475) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_1k_block... function sa_sint_t (line 3499) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_6k_... function sa_sint_t (line 3527) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_4k_... function libsais16x64_partial_sorting_scan_right_to_left_32s_1k_block_sort (line 3570) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_1k_block... function sa_sint_t (line 3608) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_6k_... function sa_sint_t (line 3659) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_4k_... function libsais16x64_partial_sorting_scan_right_to_left_32s_1k_block_omp (line 3710) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_1k_block... function sa_sint_t (line 3761) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_6k_... function sa_sint_t (line 3788) | static sa_sint_t libsais16x64_partial_sorting_scan_right_to_left_32s_4k_... function libsais16x64_partial_sorting_scan_right_to_left_32s_1k_omp (line 3812) | static void libsais16x64_partial_sorting_scan_right_to_left_32s_1k_omp(c... function fast_sint_t (line 3834) | static fast_sint_t libsais16x64_partial_sorting_gather_lms_suffixes_32s_... function fast_sint_t (line 3857) | static fast_sint_t libsais16x64_partial_sorting_gather_lms_suffixes_32s_... function libsais16x64_partial_sorting_gather_lms_suffixes_32s_4k_omp (line 3880) | static void libsais16x64_partial_sorting_gather_lms_suffixes_32s_4k_omp(... function libsais16x64_partial_sorting_gather_lms_suffixes_32s_1k_omp (line 3931) | static void libsais16x64_partial_sorting_gather_lms_suffixes_32s_1k_omp(... function libsais16x64_induce_partial_order_16u_omp (line 3982) | static void libsais16x64_induce_partial_order_16u_omp(const uint16_t * R... function libsais16x64_induce_partial_order_32s_6k_omp (line 4013) | static void libsais16x64_induce_partial_order_32s_6k_omp(const sa_sint_t... function libsais16x64_induce_partial_order_32s_4k_omp (line 4021) | static void libsais16x64_induce_partial_order_32s_4k_omp(const sa_sint_t... function libsais16x64_induce_partial_order_32s_2k_omp (line 4031) | static void libsais16x64_induce_partial_order_32s_2k_omp(const sa_sint_t... function libsais16x64_induce_partial_order_32s_1k_omp (line 4038) | static void libsais16x64_induce_partial_order_32s_1k_omp(const sa_sint_t... function sa_sint_t (line 4051) | static sa_sint_t libsais16x64_renumber_lms_suffixes_16u(sa_sint_t * REST... function fast_sint_t (line 4081) | static fast_sint_t libsais16x64_gather_marked_lms_suffixes(sa_sint_t * R... function sa_sint_t (line 4108) | static sa_sint_t libsais16x64_renumber_lms_suffixes_16u_omp(sa_sint_t * ... function libsais16x64_gather_marked_lms_suffixes_omp (line 4159) | static void libsais16x64_gather_marked_lms_suffixes_omp(sa_sint_t * REST... function sa_sint_t (line 4218) | static sa_sint_t libsais16x64_renumber_and_gather_lms_suffixes_omp(sa_si... function sa_sint_t (line 4235) | static sa_sint_t libsais16x64_renumber_distinct_lms_suffixes_32s_4k(sa_s... function libsais16x64_mark_distinct_lms_suffixes_32s (line 4265) | static void libsais16x64_mark_distinct_lms_suffixes_32s(sa_sint_t * REST... function libsais16x64_clamp_lms_suffixes_length_32s (line 4286) | static void libsais16x64_clamp_lms_suffixes_length_32s(sa_sint_t * RESTR... function sa_sint_t (line 4309) | static sa_sint_t libsais16x64_renumber_distinct_lms_suffixes_32s_4k_omp(... function libsais16x64_mark_distinct_lms_suffixes_32s_omp (line 4360) | static void libsais16x64_mark_distinct_lms_suffixes_32s_omp(sa_sint_t * ... function libsais16x64_clamp_lms_suffixes_length_32s_omp (line 4382) | static void libsais16x64_clamp_lms_suffixes_length_32s_omp(sa_sint_t * R... function sa_sint_t (line 4404) | static sa_sint_t libsais16x64_renumber_and_mark_distinct_lms_suffixes_32... function sa_sint_t (line 4417) | static sa_sint_t libsais16x64_renumber_and_mark_distinct_lms_suffixes_32... function libsais16x64_reconstruct_lms_suffixes (line 4496) | static void libsais16x64_reconstruct_lms_suffixes(sa_sint_t * RESTRICT S... function libsais16x64_reconstruct_lms_suffixes_omp (line 4524) | static void libsais16x64_reconstruct_lms_suffixes_omp(sa_sint_t * RESTRI... function libsais16x64_place_lms_suffixes_interval_16u (line 4547) | static void libsais16x64_place_lms_suffixes_interval_16u(sa_sint_t * RES... function libsais16x64_place_lms_suffixes_interval_32s_4k (line 4576) | static void libsais16x64_place_lms_suffixes_interval_32s_4k(sa_sint_t * ... function libsais16x64_place_lms_suffixes_interval_32s_2k (line 4599) | static void libsais16x64_place_lms_suffixes_interval_32s_2k(sa_sint_t * ... function libsais16x64_place_lms_suffixes_interval_32s_1k (line 4625) | static void libsais16x64_place_lms_suffixes_interval_32s_1k(const sa_sin... function libsais16x64_place_lms_suffixes_histogram_32s_6k (line 4653) | static void libsais16x64_place_lms_suffixes_histogram_32s_6k(sa_sint_t *... function libsais16x64_place_lms_suffixes_histogram_32s_4k (line 4676) | static void libsais16x64_place_lms_suffixes_histogram_32s_4k(sa_sint_t *... function libsais16x64_place_lms_suffixes_histogram_32s_2k (line 4699) | static void libsais16x64_place_lms_suffixes_histogram_32s_2k(sa_sint_t *... function libsais16x64_final_bwt_scan_left_to_right_16u (line 4725) | static void libsais16x64_final_bwt_scan_left_to_right_16u(const uint16_t... function libsais16x64_final_bwt_aux_scan_left_to_right_16u (line 4747) | static void libsais16x64_final_bwt_aux_scan_left_to_right_16u(const uint... function libsais16x64_final_sorting_scan_left_to_right_16u (line 4769) | static void libsais16x64_final_sorting_scan_left_to_right_16u(const uint... function libsais16x64_final_sorting_scan_left_to_right_32s (line 4791) | static void libsais16x64_final_sorting_scan_left_to_right_32s(const sa_s... function fast_sint_t (line 4817) | static fast_sint_t libsais16x64_final_bwt_scan_left_to_right_16u_block_p... function fast_sint_t (line 4843) | static fast_sint_t libsais16x64_final_sorting_scan_left_to_right_16u_blo... function libsais16x64_final_order_scan_left_to_right_16u_block_place (line 4869) | static void libsais16x64_final_order_scan_left_to_right_16u_block_place(... function libsais16x64_final_bwt_aux_scan_left_to_right_16u_block_place (line 4890) | static void libsais16x64_final_bwt_aux_scan_left_to_right_16u_block_plac... function libsais16x64_final_sorting_scan_left_to_right_32s_block_gather (line 4911) | static void libsais16x64_final_sorting_scan_left_to_right_32s_block_gath... function libsais16x64_final_sorting_scan_left_to_right_32s_block_sort (line 4935) | static void libsais16x64_final_sorting_scan_left_to_right_32s_block_sort... function libsais16x64_final_bwt_scan_left_to_right_16u_block_omp (line 4973) | static void libsais16x64_final_bwt_scan_left_to_right_16u_block_omp(cons... function libsais16x64_final_bwt_aux_scan_left_to_right_16u_block_omp (line 5027) | static void libsais16x64_final_bwt_aux_scan_left_to_right_16u_block_omp(... function libsais16x64_final_sorting_scan_left_to_right_16u_block_omp (line 5081) | static void libsais16x64_final_sorting_scan_left_to_right_16u_block_omp(... function libsais16x64_final_sorting_scan_left_to_right_32s_block_omp (line 5135) | static void libsais16x64_final_sorting_scan_left_to_right_32s_block_omp(... function libsais16x64_final_bwt_scan_left_to_right_16u_omp (line 5186) | static void libsais16x64_final_bwt_scan_left_to_right_16u_omp(const uint... function libsais16x64_final_bwt_aux_scan_left_to_right_16u_omp (line 5230) | static void libsais16x64_final_bwt_aux_scan_left_to_right_16u_omp(const ... function libsais16x64_final_sorting_scan_left_to_right_16u_omp (line 5276) | static void libsais16x64_final_sorting_scan_left_to_right_16u_omp(const ... function libsais16x64_final_sorting_scan_left_to_right_32s_omp (line 5320) | static void libsais16x64_final_sorting_scan_left_to_right_32s_omp(const ... function sa_sint_t (line 5344) | static sa_sint_t libsais16x64_final_bwt_scan_right_to_left_16u(const uin... function libsais16x64_final_bwt_aux_scan_right_to_left_16u (line 5372) | static void libsais16x64_final_bwt_aux_scan_right_to_left_16u(const uint... function libsais16x64_final_sorting_scan_right_to_left_16u (line 5398) | static void libsais16x64_final_sorting_scan_right_to_left_16u(const uint... function libsais16x64_final_gsa_scan_right_to_left_16u (line 5420) | static void libsais16x64_final_gsa_scan_right_to_left_16u(const uint16_t... function libsais16x64_final_sorting_scan_right_to_left_32s (line 5442) | static void libsais16x64_final_sorting_scan_right_to_left_32s(const sa_s... function fast_sint_t (line 5468) | static fast_sint_t libsais16x64_final_bwt_scan_right_to_left_16u_block_p... function fast_sint_t (line 5494) | static fast_sint_t libsais16x64_final_bwt_aux_scan_right_to_left_16u_blo... function fast_sint_t (line 5520) | static fast_sint_t libsais16x64_final_sorting_scan_right_to_left_16u_blo... function libsais16x64_final_order_scan_right_to_left_16u_block_place (line 5546) | static void libsais16x64_final_order_scan_right_to_left_16u_block_place(... function libsais16x64_final_gsa_scan_right_to_left_16u_block_place (line 5567) | static void libsais16x64_final_gsa_scan_right_to_left_16u_block_place(sa... function libsais16x64_final_bwt_aux_scan_right_to_left_16u_block_place (line 5588) | static void libsais16x64_final_bwt_aux_scan_right_to_left_16u_block_plac... function libsais16x64_final_sorting_scan_right_to_left_32s_block_gather (line 5609) | static void libsais16x64_final_sorting_scan_right_to_left_32s_block_gath... function libsais16x64_final_sorting_scan_right_to_left_32s_block_sort (line 5633) | static void libsais16x64_final_sorting_scan_right_to_left_32s_block_sort... function libsais16x64_final_bwt_scan_right_to_left_16u_block_omp (line 5671) | static void libsais16x64_final_bwt_scan_right_to_left_16u_block_omp(cons... function libsais16x64_final_bwt_aux_scan_right_to_left_16u_block_omp (line 5725) | static void libsais16x64_final_bwt_aux_scan_right_to_left_16u_block_omp(... function libsais16x64_final_sorting_scan_right_to_left_16u_block_omp (line 5779) | static void libsais16x64_final_sorting_scan_right_to_left_16u_block_omp(... function libsais16x64_final_gsa_scan_right_to_left_16u_block_omp (line 5833) | static void libsais16x64_final_gsa_scan_right_to_left_16u_block_omp(cons... function libsais16x64_final_sorting_scan_right_to_left_32s_block_omp (line 5887) | static void libsais16x64_final_sorting_scan_right_to_left_32s_block_omp(... function sa_sint_t (line 5938) | static sa_sint_t libsais16x64_final_bwt_scan_right_to_left_16u_omp(const... function libsais16x64_final_bwt_aux_scan_right_to_left_16u_omp (line 5984) | static void libsais16x64_final_bwt_aux_scan_right_to_left_16u_omp(const ... function libsais16x64_final_sorting_scan_right_to_left_16u_omp (line 6026) | static void libsais16x64_final_sorting_scan_right_to_left_16u_omp(const ... function libsais16x64_final_gsa_scan_right_to_left_16u_omp (line 6068) | static void libsais16x64_final_gsa_scan_right_to_left_16u_omp(const uint... function libsais16x64_final_sorting_scan_right_to_left_32s_omp (line 6110) | static void libsais16x64_final_sorting_scan_right_to_left_32s_omp(const ... function libsais16x64_clear_lms_suffixes_omp (line 6132) | static void libsais16x64_clear_lms_suffixes_omp(sa_sint_t * RESTRICT SA,... function sa_sint_t (line 6150) | static sa_sint_t libsais16x64_induce_final_order_16u_omp(const uint16_t ... function libsais16x64_induce_final_order_32s_6k (line 6186) | static void libsais16x64_induce_final_order_32s_6k(const sa_sint_t * RES... function libsais16x64_induce_final_order_32s_4k (line 6192) | static void libsais16x64_induce_final_order_32s_4k(const sa_sint_t * RES... function libsais16x64_induce_final_order_32s_2k (line 6198) | static void libsais16x64_induce_final_order_32s_2k(const sa_sint_t * RES... function libsais16x64_induce_final_order_32s_1k (line 6204) | static void libsais16x64_induce_final_order_32s_1k(const sa_sint_t * RES... function sa_sint_t (line 6215) | static sa_sint_t libsais16x64_renumber_unique_and_nonunique_lms_suffixes... function libsais16x64_compact_unique_and_nonunique_lms_suffixes_32s (line 6250) | static void libsais16x64_compact_unique_and_nonunique_lms_suffixes_32s(s... function sa_sint_t (line 6278) | static sa_sint_t libsais16x64_count_unique_suffixes(sa_sint_t * RESTRICT... function sa_sint_t (line 6310) | static sa_sint_t libsais16x64_renumber_unique_and_nonunique_lms_suffixes... function libsais16x64_compact_unique_and_nonunique_lms_suffixes_32s_omp (line 6361) | static void libsais16x64_compact_unique_and_nonunique_lms_suffixes_32s_o... function sa_sint_t (line 6430) | static sa_sint_t libsais16x64_compact_lms_suffixes_32s_omp(sa_sint_t * R... function libsais16x64_merge_unique_lms_suffixes_32s (line 6438) | static void libsais16x64_merge_unique_lms_suffixes_32s(sa_sint_t * RESTR... function libsais16x64_merge_nonunique_lms_suffixes_32s (line 6461) | static void libsais16x64_merge_nonunique_lms_suffixes_32s(sa_sint_t * RE... function libsais16x64_merge_unique_lms_suffixes_32s_omp (line 6484) | static void libsais16x64_merge_unique_lms_suffixes_32s_omp(sa_sint_t * R... function libsais16x64_merge_nonunique_lms_suffixes_32s_omp (line 6526) | static void libsais16x64_merge_nonunique_lms_suffixes_32s_omp(sa_sint_t ... function libsais16x64_merge_compacted_lms_suffixes_32s_omp (line 6568) | static void libsais16x64_merge_compacted_lms_suffixes_32s_omp(sa_sint_t ... function libsais16x64_reconstruct_compacted_lms_suffixes_32s_2k_omp (line 6574) | static void libsais16x64_reconstruct_compacted_lms_suffixes_32s_2k_omp(s... function libsais16x64_reconstruct_compacted_lms_suffixes_32s_1k_omp (line 6595) | static void libsais16x64_reconstruct_compacted_lms_suffixes_32s_1k_omp(s... function libsais16x64_convert_32u_to_64u (line 6616) | static void libsais16x64_convert_32u_to_64u(uint32_t * RESTRICT S, uint6... function libsais16x64_convert_inplace_32u_to_64u (line 6625) | static void libsais16x64_convert_inplace_32u_to_64u(uint32_t * V, fast_s... function libsais16x64_convert_inplace_64u_to_32u (line 6638) | static void libsais16x64_convert_inplace_64u_to_32u(uint32_t * V, fast_s... function libsais16x64_convert_inplace_32u_to_64u_omp (line 6651) | static void libsais16x64_convert_inplace_32u_to_64u_omp(uint32_t * V, sa... function sa_sint_t (line 6681) | static sa_sint_t libsais16x64_main_32s_recursion(sa_sint_t * RESTRICT T,... function sa_sint_t (line 6907) | static sa_sint_t libsais16x64_main_32s_entry(sa_sint_t * RESTRICT T, sa_... function sa_sint_t (line 6914) | static sa_sint_t libsais16x64_main_16u(const uint16_t * T, sa_sint_t * S... function sa_sint_t (line 6960) | static sa_sint_t libsais16x64_main(const uint16_t * T, sa_sint_t * SA, s... function sa_sint_t (line 6975) | static sa_sint_t libsais16x64_main_long(sa_sint_t * T, sa_sint_t * SA, s... function libsais16x64_bwt_copy_16u (line 6988) | static void libsais16x64_bwt_copy_16u(uint16_t * RESTRICT U, sa_sint_t *... function libsais16x64_bwt_copy_16u_omp (line 7013) | static void libsais16x64_bwt_copy_16u_omp(uint16_t * RESTRICT U, sa_sint... function libsais16x64 (line 7036) | int64_t libsais16x64(const uint16_t * T, int64_t * SA, int64_t n, int64_... function libsais16x64_gsa (line 7066) | int64_t libsais16x64_gsa(const uint16_t * T, int64_t * SA, int64_t n, in... function libsais16x64_long (line 7096) | int64_t libsais16x64_long(int64_t * T, int64_t * SA, int64_t n, int64_t ... function libsais16x64_bwt (line 7111) | int64_t libsais16x64_bwt(const uint16_t * T, uint16_t * U, int64_t * A, ... function libsais16x64_bwt_aux (line 7150) | int64_t libsais16x64_bwt_aux(const uint16_t * T, uint16_t * U, int64_t *... function libsais16x64_omp (line 7191) | int64_t libsais16x64_omp(const uint16_t * T, int64_t * SA, int64_t n, in... function libsais16x64_gsa_omp (line 7224) | int64_t libsais16x64_gsa_omp(const uint16_t * T, int64_t * SA, int64_t n... function libsais16x64_long_omp (line 7257) | int64_t libsais16x64_long_omp(int64_t * T, int64_t * SA, int64_t n, int6... function libsais16x64_bwt_omp (line 7275) | int64_t libsais16x64_bwt_omp(const uint16_t * T, uint16_t * U, int64_t *... function libsais16x64_bwt_aux_omp (line 7317) | int64_t libsais16x64_bwt_aux_omp(const uint16_t * T, uint16_t * U, int64... function libsais16x64_unbwt_compute_histogram (line 7361) | static void libsais16x64_unbwt_compute_histogram(const uint16_t * RESTRI... function libsais16x64_unbwt_calculate_fastbits (line 7366) | static void libsais16x64_unbwt_calculate_fastbits(sa_uint_t * RESTRICT b... function libsais16x64_unbwt_calculate_P (line 7379) | static void libsais16x64_unbwt_calculate_P(const uint16_t * RESTRICT T, ... function libsais16x64_unbwt_init_single (line 7392) | static void libsais16x64_unbwt_init_single(const uint16_t * RESTRICT T, ... function libsais16x64_unbwt_init_parallel (line 7413) | static void libsais16x64_unbwt_init_parallel(const uint16_t * RESTRICT T... function libsais16x64_unbwt_decode_1 (line 7488) | static void libsais16x64_unbwt_decode_1(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_2 (line 7502) | static void libsais16x64_unbwt_decode_2(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_3 (line 7518) | static void libsais16x64_unbwt_decode_3(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_4 (line 7536) | static void libsais16x64_unbwt_decode_4(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_5 (line 7556) | static void libsais16x64_unbwt_decode_5(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_6 (line 7578) | static void libsais16x64_unbwt_decode_6(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_7 (line 7602) | static void libsais16x64_unbwt_decode_7(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode_8 (line 7628) | static void libsais16x64_unbwt_decode_8(uint16_t * RESTRICT U, sa_uint_t... function libsais16x64_unbwt_decode (line 7656) | static void libsais16x64_unbwt_decode(uint16_t * RESTRICT U, sa_uint_t *... function libsais16x64_unbwt_decode_omp (line 7717) | static void libsais16x64_unbwt_decode_omp(uint16_t * RESTRICT U, sa_uint... function sa_sint_t (line 7746) | static sa_sint_t libsais16x64_unbwt_core(const uint16_t * RESTRICT T, ui... function sa_sint_t (line 7765) | static sa_sint_t libsais16x64_unbwt_main(const uint16_t * T, uint16_t * ... function libsais16x64_unbwt (line 7784) | int64_t libsais16x64_unbwt(const uint16_t * T, uint16_t * U, int64_t * A... function libsais16x64_unbwt_aux (line 7789) | int64_t libsais16x64_unbwt_aux(const uint16_t * T, uint16_t * U, int64_t... function libsais16x64_unbwt_omp (line 7816) | int64_t libsais16x64_unbwt_omp(const uint16_t * T, uint16_t * U, int64_t... function libsais16x64_unbwt_aux_omp (line 7821) | int64_t libsais16x64_unbwt_aux_omp(const uint16_t * T, uint16_t * U, int... function libsais16x64_compute_phi (line 7851) | static void libsais16x64_compute_phi(const sa_sint_t * RESTRICT SA, sa_s... function libsais16x64_compute_phi_omp (line 7879) | static void libsais16x64_compute_phi_omp(const sa_sint_t * RESTRICT SA, ... function libsais16x64_compute_plcp (line 7902) | static void libsais16x64_compute_plcp(const uint16_t * RESTRICT T, sa_si... function libsais16x64_compute_plcp_omp (line 7927) | static void libsais16x64_compute_plcp_omp(const uint16_t * RESTRICT T, s... function libsais16x64_compute_plcp_gsa (line 7950) | static void libsais16x64_compute_plcp_gsa(const uint16_t * RESTRICT T, s... function libsais16x64_compute_plcp_gsa_omp (line 7975) | static void libsais16x64_compute_plcp_gsa_omp(const uint16_t * RESTRICT ... function libsais16x64_compute_lcp (line 7998) | static void libsais16x64_compute_lcp(const sa_sint_t * RESTRICT PLCP, co... function libsais16x64_compute_lcp_omp (line 8027) | static void libsais16x64_compute_lcp_omp(const sa_sint_t * RESTRICT PLCP... function libsais16x64_plcp (line 8050) | int64_t libsais16x64_plcp(const uint16_t * T, const int64_t * SA, int64_... function libsais16x64_plcp_gsa (line 8068) | int64_t libsais16x64_plcp_gsa(const uint16_t * T, const int64_t * SA, in... function libsais16x64_lcp (line 8086) | int64_t libsais16x64_lcp(const int64_t * PLCP, const int64_t * SA, int64... function libsais16x64_plcp_omp (line 8105) | int64_t libsais16x64_plcp_omp(const uint16_t * T, const int64_t * SA, in... function libsais16x64_plcp_gsa_omp (line 8126) | int64_t libsais16x64_plcp_gsa_omp(const uint16_t * T, const int64_t * SA... function libsais16x64_lcp_omp (line 8147) | int64_t libsais16x64_lcp_omp(const int64_t * PLCP, const int64_t * SA, i... FILE: src/libsais64.c type sa_sint_t (line 39) | typedef int64_t sa_sint_t; type sa_uint_t (line 40) | typedef uint64_t sa_uint_t; type fast_sint_t (line 41) | typedef int64_t fast_sint_t; type fast_uint_t (line 42) | typedef uint64_t fast_uint_t; type LIBSAIS_THREAD_CACHE (line 64) | typedef struct LIBSAIS_THREAD_CACHE type LIBSAIS_THREAD_STATE (line 70) | typedef union LIBSAIS_THREAD_STATE type LIBSAIS_CONTEXT (line 87) | typedef struct LIBSAIS_CONTEXT type LIBSAIS_UNBWT_CONTEXT (line 94) | typedef struct LIBSAIS_UNBWT_CONTEXT function libsais64_free_aligned (line 196) | static void libsais64_free_aligned(void * aligned_address) function LIBSAIS_THREAD_STATE (line 204) | static LIBSAIS_THREAD_STATE * libsais64_alloc_thread_state(sa_sint_t thr... function libsais64_free_thread_state (line 228) | static void libsais64_free_thread_state(LIBSAIS_THREAD_STATE * thread_st... function sa_sint_t (line 240) | static sa_sint_t libsais64_count_negative_marked_suffixes(sa_sint_t * RE... function sa_sint_t (line 249) | static sa_sint_t libsais64_count_zero_marked_suffixes(sa_sint_t * RESTRI... function libsais64_place_cached_suffixes (line 258) | static void libsais64_place_cached_suffixes(sa_sint_t * RESTRICT SA, LIB... function libsais64_compact_and_place_cached_suffixes (line 284) | static void libsais64_compact_and_place_cached_suffixes(sa_sint_t * REST... function libsais64_accumulate_counts_s32_2 (line 307) | static void libsais64_accumulate_counts_s32_2(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_3 (line 313) | static void libsais64_accumulate_counts_s32_3(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_4 (line 320) | static void libsais64_accumulate_counts_s32_4(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_5 (line 328) | static void libsais64_accumulate_counts_s32_5(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_6 (line 337) | static void libsais64_accumulate_counts_s32_6(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_7 (line 347) | static void libsais64_accumulate_counts_s32_7(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_8 (line 358) | static void libsais64_accumulate_counts_s32_8(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32_9 (line 370) | static void libsais64_accumulate_counts_s32_9(sa_sint_t * RESTRICT bucke... function libsais64_accumulate_counts_s32 (line 383) | static void libsais64_accumulate_counts_s32(sa_sint_t * RESTRICT buckets... function libsais64_flip_suffix_markers_omp (line 406) | static void libsais64_flip_suffix_markers_omp(sa_sint_t * RESTRICT SA, s... function libsais64_gather_lms_suffixes_8u (line 429) | static void libsais64_gather_lms_suffixes_8u(const uint8_t * RESTRICT T,... function libsais64_gather_lms_suffixes_8u_omp (line 460) | static void libsais64_gather_lms_suffixes_8u_omp(const uint8_t * RESTRIC... function sa_sint_t (line 501) | static sa_sint_t libsais64_gather_lms_suffixes_32s(const sa_sint_t * RES... function sa_sint_t (line 530) | static sa_sint_t libsais64_gather_compacted_lms_suffixes_32s(const sa_si... function libsais64_count_lms_suffixes_32s_4k (line 561) | static void libsais64_count_lms_suffixes_32s_4k(const sa_sint_t * RESTRI... function libsais64_count_lms_suffixes_32s_2k (line 606) | static void libsais64_count_lms_suffixes_32s_2k(const sa_sint_t * RESTRI... function libsais64_count_compacted_lms_suffixes_32s_2k (line 651) | static void libsais64_count_compacted_lms_suffixes_32s_2k(const sa_sint_... function sa_sint_t (line 696) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_8u(const uint8_... function sa_sint_t (line 742) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_8u_omp(const ui... function sa_sint_t (line 809) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_4k(const sa... function sa_sint_t (line 860) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_2k(const sa... function sa_sint_t (line 911) | static sa_sint_t libsais64_count_and_gather_compacted_lms_suffixes_32s_2... function fast_sint_t (line 964) | static fast_sint_t libsais64_get_bucket_stride(fast_sint_t free_space, f... function sa_sint_t (line 972) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_4k_fs_omp(c... function sa_sint_t (line 1040) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_2k_fs_omp(c... function libsais64_count_and_gather_compacted_lms_suffixes_32s_2k_fs_omp (line 1108) | static void libsais64_count_and_gather_compacted_lms_suffixes_32s_2k_fs_... function sa_sint_t (line 1168) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_4k_nofs_omp... function sa_sint_t (line 1203) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_2k_nofs_omp... function sa_sint_t (line 1238) | static sa_sint_t libsais64_count_and_gather_compacted_lms_suffixes_32s_2... function sa_sint_t (line 1273) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_4k_omp(cons... function sa_sint_t (line 1297) | static sa_sint_t libsais64_count_and_gather_lms_suffixes_32s_2k_omp(cons... function libsais64_count_and_gather_compacted_lms_suffixes_32s_2k_omp (line 1321) | static void libsais64_count_and_gather_compacted_lms_suffixes_32s_2k_omp... function libsais64_count_suffixes_32s (line 1341) | static void libsais64_count_suffixes_32s(const sa_sint_t * RESTRICT T, s... function sa_sint_t (line 1368) | static sa_sint_t libsais64_initialize_buckets_start_and_end_8u(sa_sint_t... function libsais64_initialize_buckets_start_and_end_32s_6k (line 1399) | static void libsais64_initialize_buckets_start_and_end_32s_6k(sa_sint_t ... function libsais64_initialize_buckets_start_and_end_32s_4k (line 1413) | static void libsais64_initialize_buckets_start_and_end_32s_4k(sa_sint_t ... function libsais64_initialize_buckets_end_32s_2k (line 1427) | static void libsais64_initialize_buckets_end_32s_2k(sa_sint_t k, sa_sint... function libsais64_initialize_buckets_start_and_end_32s_2k (line 1436) | static void libsais64_initialize_buckets_start_and_end_32s_2k(sa_sint_t ... function libsais64_initialize_buckets_start_32s_1k (line 1447) | static void libsais64_initialize_buckets_start_32s_1k(sa_sint_t k, sa_si... function libsais64_initialize_buckets_end_32s_1k (line 1453) | static void libsais64_initialize_buckets_end_32s_1k(sa_sint_t k, sa_sint... function sa_sint_t (line 1459) | static sa_sint_t libsais64_initialize_buckets_for_lms_suffixes_radix_sor... function libsais64_initialize_buckets_for_lms_suffixes_radix_sort_32s_2k (line 1489) | static void libsais64_initialize_buckets_for_lms_suffixes_radix_sort_32s... function sa_sint_t (line 1505) | static sa_sint_t libsais64_initialize_buckets_for_lms_suffixes_radix_sor... function libsais64_initialize_buckets_for_radix_and_partial_sorting_32s_4k (line 1535) | static void libsais64_initialize_buckets_for_radix_and_partial_sorting_3... function libsais64_radix_sort_lms_suffixes_8u (line 1556) | static void libsais64_radix_sort_lms_suffixes_8u(const uint8_t * RESTRIC... function libsais64_radix_sort_lms_suffixes_8u_omp (line 1582) | static void libsais64_radix_sort_lms_suffixes_8u_omp(const uint8_t * RES... function libsais64_radix_sort_lms_suffixes_32s_6k (line 1632) | static void libsais64_radix_sort_lms_suffixes_32s_6k(const sa_sint_t * R... function libsais64_radix_sort_lms_suffixes_32s_2k (line 1663) | static void libsais64_radix_sort_lms_suffixes_32s_2k(const sa_sint_t * R... function libsais64_radix_sort_lms_suffixes_32s_block_gather (line 1696) | static void libsais64_radix_sort_lms_suffixes_32s_block_gather(const sa_... function libsais64_radix_sort_lms_suffixes_32s_6k_block_sort (line 1724) | static void libsais64_radix_sort_lms_suffixes_32s_6k_block_sort(sa_sint_... function libsais64_radix_sort_lms_suffixes_32s_2k_block_sort (line 1750) | static void libsais64_radix_sort_lms_suffixes_32s_2k_block_sort(sa_sint_... function libsais64_radix_sort_lms_suffixes_32s_6k_block_omp (line 1776) | static void libsais64_radix_sort_lms_suffixes_32s_6k_block_omp(const sa_... function libsais64_radix_sort_lms_suffixes_32s_2k_block_omp (line 1825) | static void libsais64_radix_sort_lms_suffixes_32s_2k_block_omp(const sa_... function libsais64_radix_sort_lms_suffixes_32s_6k_omp (line 1876) | static void libsais64_radix_sort_lms_suffixes_32s_6k_omp(const sa_sint_t... function libsais64_radix_sort_lms_suffixes_32s_2k_omp (line 1898) | static void libsais64_radix_sort_lms_suffixes_32s_2k_omp(const sa_sint_t... function sa_sint_t (line 1920) | static sa_sint_t libsais64_radix_sort_lms_suffixes_32s_1k(const sa_sint_... function libsais64_radix_sort_set_markers_32s_6k (line 1968) | static void libsais64_radix_sort_set_markers_32s_6k(sa_sint_t * RESTRICT... function libsais64_radix_sort_set_markers_32s_4k (line 1994) | static void libsais64_radix_sort_set_markers_32s_4k(sa_sint_t * RESTRICT... function libsais64_radix_sort_set_markers_32s_6k_omp (line 2020) | static void libsais64_radix_sort_set_markers_32s_6k_omp(sa_sint_t * REST... function libsais64_radix_sort_set_markers_32s_4k_omp (line 2043) | static void libsais64_radix_sort_set_markers_32s_4k_omp(sa_sint_t * REST... function libsais64_initialize_buckets_for_partial_sorting_8u (line 2066) | static void libsais64_initialize_buckets_for_partial_sorting_8u(const ui... function libsais64_initialize_buckets_for_partial_sorting_32s_6k (line 2085) | static void libsais64_initialize_buckets_for_partial_sorting_32s_6k(cons... function sa_sint_t (line 2127) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_8u(const u... function libsais64_partial_sorting_scan_left_to_right_8u_block_prepare (line 2162) | static void libsais64_partial_sorting_scan_left_to_right_8u_block_prepar... function libsais64_partial_sorting_scan_left_to_right_8u_block_place (line 2195) | static void libsais64_partial_sorting_scan_left_to_right_8u_block_place(... function sa_sint_t (line 2221) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_8u_block_o... function sa_sint_t (line 2288) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_8u_omp(con... function sa_sint_t (line 2339) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_6k(con... function sa_sint_t (line 2372) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_4k(con... function libsais64_partial_sorting_scan_left_to_right_32s_1k (line 2417) | static void libsais64_partial_sorting_scan_left_to_right_32s_1k(const sa... function libsais64_partial_sorting_scan_left_to_right_32s_6k_block_gather (line 2443) | static void libsais64_partial_sorting_scan_left_to_right_32s_6k_block_ga... function libsais64_partial_sorting_scan_left_to_right_32s_4k_block_gather (line 2469) | static void libsais64_partial_sorting_scan_left_to_right_32s_4k_block_ga... function libsais64_partial_sorting_scan_left_to_right_32s_1k_block_gather (line 2493) | static void libsais64_partial_sorting_scan_left_to_right_32s_1k_block_ga... function sa_sint_t (line 2517) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_6k_blo... function sa_sint_t (line 2545) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_4k_blo... function libsais64_partial_sorting_scan_left_to_right_32s_1k_block_sort (line 2588) | static void libsais64_partial_sorting_scan_left_to_right_32s_1k_block_so... function sa_sint_t (line 2626) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_6k_blo... function sa_sint_t (line 2677) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_4k_blo... function libsais64_partial_sorting_scan_left_to_right_32s_1k_block_omp (line 2728) | static void libsais64_partial_sorting_scan_left_to_right_32s_1k_block_om... function sa_sint_t (line 2779) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_6k_omp... function sa_sint_t (line 2806) | static sa_sint_t libsais64_partial_sorting_scan_left_to_right_32s_4k_omp... function libsais64_partial_sorting_scan_left_to_right_32s_1k_omp (line 2836) | static void libsais64_partial_sorting_scan_left_to_right_32s_1k_omp(cons... function libsais64_partial_sorting_shift_markers_8u_omp (line 2860) | static void libsais64_partial_sorting_shift_markers_8u_omp(sa_sint_t * R... function libsais64_partial_sorting_shift_markers_32s_6k_omp (line 2893) | static void libsais64_partial_sorting_shift_markers_32s_6k_omp(sa_sint_t... function libsais64_partial_sorting_shift_markers_32s_4k (line 2926) | static void libsais64_partial_sorting_shift_markers_32s_4k(sa_sint_t * R... function libsais64_partial_sorting_shift_buckets_32s_6k (line 2947) | static void libsais64_partial_sorting_shift_buckets_32s_6k(sa_sint_t k, ... function sa_sint_t (line 2959) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_8u(const u... function sa_sint_t (line 2992) | static sa_sint_t libsais64_partial_gsa_scan_right_to_left_8u(const uint8... function libsais64_partial_sorting_scan_right_to_left_8u_block_prepare (line 3027) | static void libsais64_partial_sorting_scan_right_to_left_8u_block_prepar... function libsais64_partial_sorting_scan_right_to_left_8u_block_place (line 3060) | static void libsais64_partial_sorting_scan_right_to_left_8u_block_place(... function libsais64_partial_gsa_scan_right_to_left_8u_block_place (line 3086) | static void libsais64_partial_gsa_scan_right_to_left_8u_block_place(sa_s... function sa_sint_t (line 3112) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_8u_block_o... function sa_sint_t (line 3177) | static sa_sint_t libsais64_partial_gsa_scan_right_to_left_8u_block_omp(c... function libsais64_partial_sorting_scan_right_to_left_8u_omp (line 3245) | static void libsais64_partial_sorting_scan_right_to_left_8u_omp(const ui... function libsais64_partial_gsa_scan_right_to_left_8u_omp (line 3294) | static void libsais64_partial_gsa_scan_right_to_left_8u_omp(const uint8_... function sa_sint_t (line 3343) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_6k(con... function sa_sint_t (line 3376) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_4k(con... function libsais64_partial_sorting_scan_right_to_left_32s_1k (line 3421) | static void libsais64_partial_sorting_scan_right_to_left_32s_1k(const sa... function libsais64_partial_sorting_scan_right_to_left_32s_6k_block_gather (line 3447) | static void libsais64_partial_sorting_scan_right_to_left_32s_6k_block_ga... function libsais64_partial_sorting_scan_right_to_left_32s_4k_block_gather (line 3473) | static void libsais64_partial_sorting_scan_right_to_left_32s_4k_block_ga... function libsais64_partial_sorting_scan_right_to_left_32s_1k_block_gather (line 3497) | static void libsais64_partial_sorting_scan_right_to_left_32s_1k_block_ga... function sa_sint_t (line 3521) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_6k_blo... function sa_sint_t (line 3549) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_4k_blo... function libsais64_partial_sorting_scan_right_to_left_32s_1k_block_sort (line 3592) | static void libsais64_partial_sorting_scan_right_to_left_32s_1k_block_so... function sa_sint_t (line 3630) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_6k_blo... function sa_sint_t (line 3681) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_4k_blo... function libsais64_partial_sorting_scan_right_to_left_32s_1k_block_omp (line 3732) | static void libsais64_partial_sorting_scan_right_to_left_32s_1k_block_om... function sa_sint_t (line 3783) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_6k_omp... function sa_sint_t (line 3810) | static sa_sint_t libsais64_partial_sorting_scan_right_to_left_32s_4k_omp... function libsais64_partial_sorting_scan_right_to_left_32s_1k_omp (line 3834) | static void libsais64_partial_sorting_scan_right_to_left_32s_1k_omp(cons... function fast_sint_t (line 3856) | static fast_sint_t libsais64_partial_sorting_gather_lms_suffixes_32s_4k(... function fast_sint_t (line 3879) | static fast_sint_t libsais64_partial_sorting_gather_lms_suffixes_32s_1k(... function libsais64_partial_sorting_gather_lms_suffixes_32s_4k_omp (line 3902) | static void libsais64_partial_sorting_gather_lms_suffixes_32s_4k_omp(sa_... function libsais64_partial_sorting_gather_lms_suffixes_32s_1k_omp (line 3953) | static void libsais64_partial_sorting_gather_lms_suffixes_32s_1k_omp(sa_... function libsais64_induce_partial_order_8u_omp (line 4004) | static void libsais64_induce_partial_order_8u_omp(const uint8_t * RESTRI... function libsais64_induce_partial_order_32s_6k_omp (line 4035) | static void libsais64_induce_partial_order_32s_6k_omp(const sa_sint_t * ... function libsais64_induce_partial_order_32s_4k_omp (line 4043) | static void libsais64_induce_partial_order_32s_4k_omp(const sa_sint_t * ... function libsais64_induce_partial_order_32s_2k_omp (line 4053) | static void libsais64_induce_partial_order_32s_2k_omp(const sa_sint_t * ... function libsais64_induce_partial_order_32s_1k_omp (line 4060) | static void libsais64_induce_partial_order_32s_1k_omp(const sa_sint_t * ... function sa_sint_t (line 4073) | static sa_sint_t libsais64_renumber_lms_suffixes_8u(sa_sint_t * RESTRICT... function fast_sint_t (line 4103) | static fast_sint_t libsais64_gather_marked_lms_suffixes(sa_sint_t * REST... function sa_sint_t (line 4130) | static sa_sint_t libsais64_renumber_lms_suffixes_8u_omp(sa_sint_t * REST... function libsais64_gather_marked_lms_suffixes_omp (line 4181) | static void libsais64_gather_marked_lms_suffixes_omp(sa_sint_t * RESTRIC... function sa_sint_t (line 4240) | static sa_sint_t libsais64_renumber_and_gather_lms_suffixes_omp(sa_sint_... function sa_sint_t (line 4257) | static sa_sint_t libsais64_renumber_distinct_lms_suffixes_32s_4k(sa_sint... function libsais64_mark_distinct_lms_suffixes_32s (line 4287) | static void libsais64_mark_distinct_lms_suffixes_32s(sa_sint_t * RESTRIC... function libsais64_clamp_lms_suffixes_length_32s (line 4308) | static void libsais64_clamp_lms_suffixes_length_32s(sa_sint_t * RESTRICT... function sa_sint_t (line 4331) | static sa_sint_t libsais64_renumber_distinct_lms_suffixes_32s_4k_omp(sa_... function libsais64_mark_distinct_lms_suffixes_32s_omp (line 4382) | static void libsais64_mark_distinct_lms_suffixes_32s_omp(sa_sint_t * RES... function libsais64_clamp_lms_suffixes_length_32s_omp (line 4404) | static void libsais64_clamp_lms_suffixes_length_32s_omp(sa_sint_t * REST... function sa_sint_t (line 4426) | static sa_sint_t libsais64_renumber_and_mark_distinct_lms_suffixes_32s_4... function sa_sint_t (line 4439) | static sa_sint_t libsais64_renumber_and_mark_distinct_lms_suffixes_32s_1... function libsais64_reconstruct_lms_suffixes (line 4518) | static void libsais64_reconstruct_lms_suffixes(sa_sint_t * RESTRICT SA, ... function libsais64_reconstruct_lms_suffixes_omp (line 4546) | static void libsais64_reconstruct_lms_suffixes_omp(sa_sint_t * RESTRICT ... function libsais64_place_lms_suffixes_interval_8u (line 4569) | static void libsais64_place_lms_suffixes_interval_8u(sa_sint_t * RESTRIC... function libsais64_place_lms_suffixes_interval_32s_4k (line 4598) | static void libsais64_place_lms_suffixes_interval_32s_4k(sa_sint_t * RES... function libsais64_place_lms_suffixes_interval_32s_2k (line 4621) | static void libsais64_place_lms_suffixes_interval_32s_2k(sa_sint_t * RES... function libsais64_place_lms_suffixes_interval_32s_1k (line 4647) | static void libsais64_place_lms_suffixes_interval_32s_1k(const sa_sint_t... function libsais64_place_lms_suffixes_histogram_32s_6k (line 4675) | static void libsais64_place_lms_suffixes_histogram_32s_6k(sa_sint_t * RE... function libsais64_place_lms_suffixes_histogram_32s_4k (line 4698) | static void libsais64_place_lms_suffixes_histogram_32s_4k(sa_sint_t * RE... function libsais64_place_lms_suffixes_histogram_32s_2k (line 4721) | static void libsais64_place_lms_suffixes_histogram_32s_2k(sa_sint_t * RE... function libsais64_final_bwt_scan_left_to_right_8u (line 4747) | static void libsais64_final_bwt_scan_left_to_right_8u(const uint8_t * RE... function libsais64_final_bwt_aux_scan_left_to_right_8u (line 4769) | static void libsais64_final_bwt_aux_scan_left_to_right_8u(const uint8_t ... function libsais64_final_sorting_scan_left_to_right_8u (line 4791) | static void libsais64_final_sorting_scan_left_to_right_8u(const uint8_t ... function libsais64_final_sorting_scan_left_to_right_32s (line 4813) | static void libsais64_final_sorting_scan_left_to_right_32s(const sa_sint... function fast_sint_t (line 4839) | static fast_sint_t libsais64_final_bwt_scan_left_to_right_8u_block_prepa... function fast_sint_t (line 4865) | static fast_sint_t libsais64_final_sorting_scan_left_to_right_8u_block_p... function libsais64_final_order_scan_left_to_right_8u_block_place (line 4891) | static void libsais64_final_order_scan_left_to_right_8u_block_place(sa_s... function libsais64_final_bwt_aux_scan_left_to_right_8u_block_place (line 4912) | static void libsais64_final_bwt_aux_scan_left_to_right_8u_block_place(sa... function libsais64_final_sorting_scan_left_to_right_32s_block_gather (line 4933) | static void libsais64_final_sorting_scan_left_to_right_32s_block_gather(... function libsais64_final_sorting_scan_left_to_right_32s_block_sort (line 4957) | static void libsais64_final_sorting_scan_left_to_right_32s_block_sort(co... function libsais64_final_bwt_scan_left_to_right_8u_block_omp (line 4995) | static void libsais64_final_bwt_scan_left_to_right_8u_block_omp(const ui... function libsais64_final_bwt_aux_scan_left_to_right_8u_block_omp (line 5049) | static void libsais64_final_bwt_aux_scan_left_to_right_8u_block_omp(cons... function libsais64_final_sorting_scan_left_to_right_8u_block_omp (line 5103) | static void libsais64_final_sorting_scan_left_to_right_8u_block_omp(cons... function libsais64_final_sorting_scan_left_to_right_32s_block_omp (line 5157) | static void libsais64_final_sorting_scan_left_to_right_32s_block_omp(con... function libsais64_final_bwt_scan_left_to_right_8u_omp (line 5208) | static void libsais64_final_bwt_scan_left_to_right_8u_omp(const uint8_t ... function libsais64_final_bwt_aux_scan_left_to_right_8u_omp (line 5252) | static void libsais64_final_bwt_aux_scan_left_to_right_8u_omp(const uint... function libsais64_final_sorting_scan_left_to_right_8u_omp (line 5298) | static void libsais64_final_sorting_scan_left_to_right_8u_omp(const uint... function libsais64_final_sorting_scan_left_to_right_32s_omp (line 5342) | static void libsais64_final_sorting_scan_left_to_right_32s_omp(const sa_... function sa_sint_t (line 5366) | static sa_sint_t libsais64_final_bwt_scan_right_to_left_8u(const uint8_t... function libsais64_final_bwt_aux_scan_right_to_left_8u (line 5394) | static void libsais64_final_bwt_aux_scan_right_to_left_8u(const uint8_t ... function libsais64_final_sorting_scan_right_to_left_8u (line 5420) | static void libsais64_final_sorting_scan_right_to_left_8u(const uint8_t ... function libsais64_final_gsa_scan_right_to_left_8u (line 5442) | static void libsais64_final_gsa_scan_right_to_left_8u(const uint8_t * RE... function libsais64_final_sorting_scan_right_to_left_32s (line 5464) | static void libsais64_final_sorting_scan_right_to_left_32s(const sa_sint... function fast_sint_t (line 5490) | static fast_sint_t libsais64_final_bwt_scan_right_to_left_8u_block_prepa... function fast_sint_t (line 5516) | static fast_sint_t libsais64_final_bwt_aux_scan_right_to_left_8u_block_p... function fast_sint_t (line 5542) | static fast_sint_t libsais64_final_sorting_scan_right_to_left_8u_block_p... function libsais64_final_order_scan_right_to_left_8u_block_place (line 5568) | static void libsais64_final_order_scan_right_to_left_8u_block_place(sa_s... function libsais64_final_gsa_scan_right_to_left_8u_block_place (line 5589) | static void libsais64_final_gsa_scan_right_to_left_8u_block_place(sa_sin... function libsais64_final_bwt_aux_scan_right_to_left_8u_block_place (line 5610) | static void libsais64_final_bwt_aux_scan_right_to_left_8u_block_place(sa... function libsais64_final_sorting_scan_right_to_left_32s_block_gather (line 5631) | static void libsais64_final_sorting_scan_right_to_left_32s_block_gather(... function libsais64_final_sorting_scan_right_to_left_32s_block_sort (line 5655) | static void libsais64_final_sorting_scan_right_to_left_32s_block_sort(co... function libsais64_final_bwt_scan_right_to_left_8u_block_omp (line 5693) | static void libsais64_final_bwt_scan_right_to_left_8u_block_omp(const ui... function libsais64_final_bwt_aux_scan_right_to_left_8u_block_omp (line 5747) | static void libsais64_final_bwt_aux_scan_right_to_left_8u_block_omp(cons... function libsais64_final_sorting_scan_right_to_left_8u_block_omp (line 5801) | static void libsais64_final_sorting_scan_right_to_left_8u_block_omp(cons... function libsais64_final_gsa_scan_right_to_left_8u_block_omp (line 5855) | static void libsais64_final_gsa_scan_right_to_left_8u_block_omp(const ui... function libsais64_final_sorting_scan_right_to_left_32s_block_omp (line 5909) | static void libsais64_final_sorting_scan_right_to_left_32s_block_omp(con... function sa_sint_t (line 5960) | static sa_sint_t libsais64_final_bwt_scan_right_to_left_8u_omp(const uin... function libsais64_final_bwt_aux_scan_right_to_left_8u_omp (line 6006) | static void libsais64_final_bwt_aux_scan_right_to_left_8u_omp(const uint... function libsais64_final_sorting_scan_right_to_left_8u_omp (line 6048) | static void libsais64_final_sorting_scan_right_to_left_8u_omp(const uint... function libsais64_final_gsa_scan_right_to_left_8u_omp (line 6090) | static void libsais64_final_gsa_scan_right_to_left_8u_omp(const uint8_t ... function libsais64_final_sorting_scan_right_to_left_32s_omp (line 6132) | static void libsais64_final_sorting_scan_right_to_left_32s_omp(const sa_... function libsais64_clear_lms_suffixes_omp (line 6154) | static void libsais64_clear_lms_suffixes_omp(sa_sint_t * RESTRICT SA, sa... function sa_sint_t (line 6172) | static sa_sint_t libsais64_induce_final_order_8u_omp(const uint8_t * RES... function libsais64_induce_final_order_32s_6k (line 6208) | static void libsais64_induce_final_order_32s_6k(const sa_sint_t * RESTRI... function libsais64_induce_final_order_32s_4k (line 6214) | static void libsais64_induce_final_order_32s_4k(const sa_sint_t * RESTRI... function libsais64_induce_final_order_32s_2k (line 6220) | static void libsais64_induce_final_order_32s_2k(const sa_sint_t * RESTRI... function libsais64_induce_final_order_32s_1k (line 6226) | static void libsais64_induce_final_order_32s_1k(const sa_sint_t * RESTRI... function sa_sint_t (line 6237) | static sa_sint_t libsais64_renumber_unique_and_nonunique_lms_suffixes_32... function libsais64_compact_unique_and_nonunique_lms_suffixes_32s (line 6272) | static void libsais64_compact_unique_and_nonunique_lms_suffixes_32s(sa_s... function sa_sint_t (line 6300) | static sa_sint_t libsais64_count_unique_suffixes(sa_sint_t * RESTRICT SA... function sa_sint_t (line 6332) | static sa_sint_t libsais64_renumber_unique_and_nonunique_lms_suffixes_32... function libsais64_compact_unique_and_nonunique_lms_suffixes_32s_omp (line 6383) | static void libsais64_compact_unique_and_nonunique_lms_suffixes_32s_omp(... function sa_sint_t (line 6452) | static sa_sint_t libsais64_compact_lms_suffixes_32s_omp(sa_sint_t * REST... function libsais64_merge_unique_lms_suffixes_32s (line 6460) | static void libsais64_merge_unique_lms_suffixes_32s(sa_sint_t * RESTRICT... function libsais64_merge_nonunique_lms_suffixes_32s (line 6483) | static void libsais64_merge_nonunique_lms_suffixes_32s(sa_sint_t * RESTR... function libsais64_merge_unique_lms_suffixes_32s_omp (line 6506) | static void libsais64_merge_unique_lms_suffixes_32s_omp(sa_sint_t * REST... function libsais64_merge_nonunique_lms_suffixes_32s_omp (line 6548) | static void libsais64_merge_nonunique_lms_suffixes_32s_omp(sa_sint_t * R... function libsais64_merge_compacted_lms_suffixes_32s_omp (line 6590) | static void libsais64_merge_compacted_lms_suffixes_32s_omp(sa_sint_t * R... function libsais64_reconstruct_compacted_lms_suffixes_32s_2k_omp (line 6596) | static void libsais64_reconstruct_compacted_lms_suffixes_32s_2k_omp(sa_s... function libsais64_reconstruct_compacted_lms_suffixes_32s_1k_omp (line 6617) | static void libsais64_reconstruct_compacted_lms_suffixes_32s_1k_omp(sa_s... function libsais64_convert_32u_to_64u (line 6638) | static void libsais64_convert_32u_to_64u(uint32_t * RESTRICT S, uint64_t... function libsais64_convert_inplace_32u_to_64u (line 6647) | static void libsais64_convert_inplace_32u_to_64u(uint32_t * V, fast_sint... function libsais64_convert_inplace_64u_to_32u (line 6660) | static void libsais64_convert_inplace_64u_to_32u(uint32_t * V, fast_sint... function libsais64_convert_inplace_32u_to_64u_omp (line 6673) | static void libsais64_convert_inplace_32u_to_64u_omp(uint32_t * V, sa_si... function sa_sint_t (line 6703) | static sa_sint_t libsais64_main_32s_recursion(sa_sint_t * RESTRICT T, sa... function sa_sint_t (line 6929) | static sa_sint_t libsais64_main_32s_entry(sa_sint_t * RESTRICT T, sa_sin... function sa_sint_t (line 6936) | static sa_sint_t libsais64_main_8u(const uint8_t * T, sa_sint_t * SA, sa... function sa_sint_t (line 6982) | static sa_sint_t libsais64_main(const uint8_t * T, sa_sint_t * SA, sa_si... function sa_sint_t (line 6997) | static sa_sint_t libsais64_main_long(sa_sint_t * T, sa_sint_t * SA, sa_s... function libsais64_bwt_copy_8u (line 7010) | static void libsais64_bwt_copy_8u(uint8_t * RESTRICT U, sa_sint_t * REST... function libsais64_bwt_copy_8u_omp (line 7035) | static void libsais64_bwt_copy_8u_omp(uint8_t * RESTRICT U, sa_sint_t * ... function libsais64 (line 7058) | int64_t libsais64(const uint8_t * T, int64_t * SA, int64_t n, int64_t fs... function libsais64_gsa (line 7088) | int64_t libsais64_gsa(const uint8_t * T, int64_t * SA, int64_t n, int64_... function libsais64_long (line 7118) | int64_t libsais64_long(int64_t * T, int64_t * SA, int64_t n, int64_t k, ... function libsais64_bwt (line 7133) | int64_t libsais64_bwt(const uint8_t * T, uint8_t * U, int64_t * A, int64... function libsais64_bwt_aux (line 7172) | int64_t libsais64_bwt_aux(const uint8_t * T, uint8_t * U, int64_t * A, i... function libsais64_omp (line 7213) | int64_t libsais64_omp(const uint8_t * T, int64_t * SA, int64_t n, int64_... function libsais64_gsa_omp (line 7246) | int64_t libsais64_gsa_omp(const uint8_t * T, int64_t * SA, int64_t n, in... function libsais64_long_omp (line 7279) | int64_t libsais64_long_omp(int64_t * T, int64_t * SA, int64_t n, int64_t... function libsais64_bwt_omp (line 7297) | int64_t libsais64_bwt_omp(const uint8_t * T, uint8_t * U, int64_t * A, i... function libsais64_bwt_aux_omp (line 7339) | int64_t libsais64_bwt_aux_omp(const uint8_t * T, uint8_t * U, int64_t * ... function libsais64_unbwt_compute_histogram (line 7383) | static void libsais64_unbwt_compute_histogram(const uint8_t * RESTRICT T... function libsais64_unbwt_transpose_bucket2 (line 7452) | static void libsais64_unbwt_transpose_bucket2(sa_uint_t * RESTRICT bucket2) function libsais64_unbwt_compute_bigram_histogram_single (line 7493) | static void libsais64_unbwt_compute_bigram_histogram_single(const uint8_... function libsais64_unbwt_calculate_fastbits (line 7518) | static void libsais64_unbwt_calculate_fastbits(sa_uint_t * RESTRICT buck... function libsais64_unbwt_calculate_biPSI (line 7536) | static void libsais64_unbwt_calculate_biPSI(const uint8_t * RESTRICT T, ... function libsais64_unbwt_init_single (line 7571) | static void libsais64_unbwt_init_single(const uint8_t * RESTRICT T, sa_u... function libsais64_unbwt_compute_bigram_histogram_parallel (line 7598) | static void libsais64_unbwt_compute_bigram_histogram_parallel(const uint... function libsais64_unbwt_init_parallel (line 7615) | static void libsais64_unbwt_init_parallel(const uint8_t * RESTRICT T, sa... function libsais64_unbwt_decode_1 (line 7735) | static void libsais64_unbwt_decode_1(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_2 (line 7749) | static void libsais64_unbwt_decode_2(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_3 (line 7765) | static void libsais64_unbwt_decode_3(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_4 (line 7783) | static void libsais64_unbwt_decode_4(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_5 (line 7803) | static void libsais64_unbwt_decode_5(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_6 (line 7825) | static void libsais64_unbwt_decode_6(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_7 (line 7849) | static void libsais64_unbwt_decode_7(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode_8 (line 7875) | static void libsais64_unbwt_decode_8(uint8_t * RESTRICT U, sa_uint_t * R... function libsais64_unbwt_decode (line 7903) | static void libsais64_unbwt_decode(uint8_t * RESTRICT U, sa_uint_t * RES... function libsais64_unbwt_decode_omp (line 7964) | static void libsais64_unbwt_decode_omp(const uint8_t * RESTRICT T, uint8... function sa_sint_t (line 7996) | static sa_sint_t libsais64_unbwt_core(const uint8_t * RESTRICT T, uint8_... function sa_sint_t (line 8015) | static sa_sint_t libsais64_unbwt_main(const uint8_t * T, uint8_t * U, sa... function libsais64_unbwt (line 8034) | int64_t libsais64_unbwt(const uint8_t * T, uint8_t * U, int64_t * A, int... function libsais64_unbwt_aux (line 8039) | int64_t libsais64_unbwt_aux(const uint8_t * T, uint8_t * U, int64_t * A,... function libsais64_unbwt_omp (line 8067) | int64_t libsais64_unbwt_omp(const uint8_t * T, uint8_t * U, int64_t * A,... function libsais64_unbwt_aux_omp (line 8072) | int64_t libsais64_unbwt_aux_omp(const uint8_t * T, uint8_t * U, int64_t ... function libsais64_compute_phi (line 8103) | static void libsais64_compute_phi(const sa_sint_t * RESTRICT SA, sa_sint... function libsais64_compute_phi_omp (line 8131) | static void libsais64_compute_phi_omp(const sa_sint_t * RESTRICT SA, sa_... function libsais64_compute_plcp (line 8154) | static void libsais64_compute_plcp(const uint8_t * RESTRICT T, sa_sint_t... function libsais64_compute_plcp_omp (line 8179) | static void libsais64_compute_plcp_omp(const uint8_t * RESTRICT T, sa_si... function libsais64_compute_plcp_gsa (line 8202) | static void libsais64_compute_plcp_gsa(const uint8_t * RESTRICT T, sa_si... function libsais64_compute_plcp_gsa_omp (line 8227) | static void libsais64_compute_plcp_gsa_omp(const uint8_t * RESTRICT T, s... function libsais64_compute_lcp (line 8250) | static void libsais64_compute_lcp(const sa_sint_t * RESTRICT PLCP, const... function libsais64_compute_lcp_omp (line 8279) | static void libsais64_compute_lcp_omp(const sa_sint_t * RESTRICT PLCP, c... function libsais64_plcp (line 8302) | int64_t libsais64_plcp(const uint8_t * T, const int64_t * SA, int64_t * ... function libsais64_plcp_gsa (line 8320) | int64_t libsais64_plcp_gsa(const uint8_t * T, const int64_t * SA, int64_... function libsais64_lcp (line 8338) | int64_t libsais64_lcp(const int64_t * PLCP, const int64_t * SA, int64_t ... function libsais64_plcp_omp (line 8357) | int64_t libsais64_plcp_omp(const uint8_t * T, const int64_t * SA, int64_... function libsais64_plcp_gsa_omp (line 8378) | int64_t libsais64_plcp_gsa_omp(const uint8_t * T, const int64_t * SA, in... function libsais64_lcp_omp (line 8399) | int64_t libsais64_lcp_omp(const int64_t * PLCP, const int64_t * SA, int6...
Condensed preview — 14 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (1,705K chars).
[
{
"path": "Benchmarks.md",
"chars": 18045,
"preview": "# Specifications\n * OS: Windows 11 Pro (64-bit)\n * CPU: AMD Ryzen 9 9950X3D (16C / 32T, 128MB L3 cache, PBO +200Mhz, C"
},
{
"path": "CHANGES",
"chars": 3317,
"preview": "Changes in 2.10.4 (September 1, 2025)\n- Tuned prefetch distance for improved throughput.\n\nChanges in 2.10.3 (August 12, "
},
{
"path": "CMakeLists.txt",
"chars": 2606,
"preview": "cmake_minimum_required(VERSION 3.10)\n\nproject(\n libsais\n VERSION 2.10.4\n LANGUAGES C\n DESCRIPTION \"The libsa"
},
{
"path": "LICENSE",
"chars": 11358,
"preview": "\n Apache License\n Version 2.0, January 2004\n "
},
{
"path": "README.md",
"chars": 23970,
"preview": "# libsais\n\nThe libsais library provides fast (see [Benchmarks](#benchmarks) below) linear-time construction of suffix ar"
},
{
"path": "VERSION",
"chars": 7,
"preview": "2.10.4\n"
},
{
"path": "include/libsais.h",
"chars": 23796,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "include/libsais16.h",
"chars": 23622,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "include/libsais16x64.h",
"chars": 16786,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "include/libsais64.h",
"chars": 16066,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "src/libsais.c",
"chars": 388397,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "src/libsais16.c",
"chars": 374919,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "src/libsais16x64.c",
"chars": 377723,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
},
{
"path": "src/libsais64.c",
"chars": 387820,
"preview": "/*--\n\nThis file is a part of libsais, a library for linear time suffix array,\nlongest common prefix array and burrows wh"
}
]
About this extraction
This page contains the full source code of the IlyaGrebnov/libsais GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 14 files (1.6 MB), approximately 553.0k tokens, and a symbol index with 1118 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.
Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.