Debug swcsa
[SXSI/TextCollection.git] / incbwt / locate_test.cpp
1 #include <algorithm>
2 #include <cstdlib>
3 #include <ctime>
4 #include <fstream>
5 #include <iostream>
6
7 #include "rlcsa.h"
8 #include "misc/utils.h"
9
10
11 using namespace CSA;
12
13
14 int main(int argc, char** argv)
15 {
16   std::cout << "RLCSA locate test" << std::endl;
17   if(argc < 3)
18   {
19     std::cout << "Usage: locate_test basename [begin end] output [direct]" << std::endl;
20     return 1;
21   }
22
23   usint begin = 0, end = 0;
24   int output_arg = 2;
25   std::cout << "Base name: " << argv[1] << std::endl;
26   if(argc >= 5)
27   {
28     output_arg = 4;
29     begin = atoi(argv[2]), end = atoi(argv[3]);
30     std::cout << "Begin: " << begin << std::endl;
31     std::cout << "End: " << end << std::endl;
32     if(begin > end)
33     {
34       std::cerr << "Error: Empty range!" << std::endl;
35       return 2;
36     }
37   }
38   if(argc < output_arg + 2)
39   {
40     std::cout << "Using run-based optimizations." << std::endl;
41   }
42   else
43   {
44     std::cout << "Using direct locate." << std::endl;
45   }
46   std::cout << std::endl;
47
48   RLCSA rlcsa(argv[1]);
49   if(!rlcsa.supportsLocate())
50   {
51     std::cerr << "Error: Locate is not supported!" << std::endl;
52     return 3;
53   }
54
55   if(argc >= 5)
56   {
57     if(end >= rlcsa.getSize())
58     {
59       std::cerr << "Error: Invalid range!" << std::endl;
60       return 4;
61     }
62   }
63   else
64   {
65     begin = 0; end = rlcsa.getSize() - 1;
66   }
67
68   std::ofstream output(argv[output_arg], std::ios_base::binary);
69   if(!output)
70   {
71     std::cerr << "Error: Cannot open output file!" << std::endl;
72     return 5;
73   }
74
75   usint* buffer = new usint[MILLION];
76   std::clock_t start = std::clock();
77   if(argc < output_arg + 2)  // Use run-based optimizations for locate.
78   {
79     for(usint curr = begin; curr <= end; curr += MILLION)
80     {
81       pair_type range(curr, std::min(end, curr + MILLION - 1));
82       rlcsa.locate(range, buffer);
83       for(usint i = 0; i < range.second + 1 - range.first; i++)
84       {
85         output.write((char*)&(buffer[i]), sizeof(usint));
86       }
87     }
88   }
89   else  // Use direct locate.
90   {
91     for(usint curr = begin; curr <= end; curr += MILLION)
92     {
93       pair_type range(curr, std::min(end, curr + MILLION - 1));
94       for(usint i = 0; i < range.second + 1 - range.first; i++)
95       {
96         buffer[i] = rlcsa.locate(curr + i);
97       }
98       for(usint i = 0; i < range.second + 1 - range.first; i++)
99       {
100         output.write((char*)&(buffer[i]), sizeof(usint));
101       }
102     }
103   }
104   std::clock_t stop = std::clock();
105   delete[] buffer;
106
107   double size = (end + 1 - begin);
108   double time = (stop - start) / (double)CLOCKS_PER_SEC;
109   std::cout << size << " locates in " << time << " seconds (" << (size / time) << " locates/s)" << std::endl;
110   output.close();
111
112   return 0;
113 }