Added TextStorage class
[SXSI/TextCollection.git] / TextCollectionBuilder.cpp
1 #include "incbwt/rlcsa_builder.h"
2 #include "TextCollectionBuilder.h"
3
4 // Un-comment next line to run a comparison of resulting BWT
5 //#define TCB_TEST_BWT
6
7 #ifdef TCB_TEST_BWT
8 #include "dynFMI.h"
9 #endif
10
11 #include "TCImplementation.h"
12
13 namespace SXSI
14 {
15
16 struct TCBuilderRep
17 {
18     unsigned samplerate;
19     CSA::RLCSABuilder * sa;
20
21     ulong n;
22     // Total number of texts in the collection
23     unsigned numberOfTexts;
24     // Length of the longest text
25     ulong maxTextLength;
26
27 #ifdef TCB_TEST_BWT
28     DynFMI *dynFMI;
29 #endif
30 };
31
32 /**
33  * Init text collection
34  *
35  * See CSA.h for more details.
36  */
37 TextCollectionBuilder::TextCollectionBuilder(unsigned samplerate)
38     : p_(new struct TCBuilderRep())
39 {
40     p_->n = 0;
41     p_->samplerate = samplerate;
42     p_->numberOfTexts = 0;
43     
44     // Current params: 8 bytes, 15 MB, no samples
45     p_->sa = new CSA::RLCSABuilder(8, 0, 15 * 1024 * 1024);
46     assert(p_->sa->isOk());
47
48 #ifdef TCB_TEST_BWT
49     uchar temp[256];
50     for (unsigned i = 0; i < 255; ++i)
51         temp[i] = i+1;
52     temp[255] = 0;
53     p_->dynFMI = new DynFMI(temp, 1, 255, false);
54 #endif
55 }
56
57 TextCollectionBuilder::~TextCollectionBuilder()
58 {
59 #ifdef TCB_TEST_BWT
60     delete p_->dynFMI;
61 #endif
62
63     delete p_->sa;
64     delete p_;
65 }
66
67 void TextCollectionBuilder::InsertText(uchar const * text)
68 {
69     TextCollection::TextPosition m = std::strlen((char *)text) + 1;
70     if (m > p_->maxTextLength)
71         p_->maxTextLength = m; // Store length of the longest text seen so far.
72
73     if (m > 1)
74     {
75         p_->n += m;
76         p_->numberOfTexts ++;
77
78 #ifdef TCB_TEST_BWT
79         p_->dynFMI->addText(text, m);
80 #endif
81
82         p_->sa->insertSequence((char*)text, m-1, 0);
83         assert(p_->sa->isOk());
84     }
85     else
86     {
87         // FIXME indexing empty texts
88         std::cerr << "TextCollectionBuilder::InsertText() error: can not index empty texts!" << std::endl;
89         exit(1);
90     }
91 }
92
93
94 TextCollection * TextCollectionBuilder::InitTextCollection()
95 {
96     uchar * bwt = 0;
97     CSA::usint length = 0;
98     if (p_->numberOfTexts == 0)
99     {
100         p_->numberOfTexts ++; // Add one empty text
101         bwt = new uchar[2];
102         bwt[0] = '\0';
103         bwt[1] = '\0';
104         length = 1;
105         p_->maxTextLength = 1;
106     }
107     else
108     {
109         bwt = (uchar *)p_->sa->getBWT(length);
110         delete p_->sa;
111         p_->sa = 0;
112
113         assert(length == p_->n);
114
115 #ifdef TCB_TEST_BWT
116         { 
117             uchar *bwtTest = p_->dynFMI->getBWT();
118             printf("123456789012345678901234567890123456789\n");
119             for (ulong i = 0; i < p_->n && i < 100; i ++)
120                 if (bwt[i] < 50)
121                     printf("%d", (int)bwt[i]);
122                 else
123                     printf("%c", bwt[i]);
124             printf("\n");
125             for (ulong i = 0; i < p_->n && i < 100; i ++)
126                 if (bwtTest[i] < 50)
127                     printf("%d", (int)bwtTest[i]);
128                 else
129                     printf("%c", bwtTest[i]);
130             printf("\n");
131             
132             // Sanity check
133             assert(p_->numberOfTexts == p_->dynFMI->getCollectionSize());    
134             
135             delete p_->dynFMI;
136             p_->dynFMI = 0;
137             for (ulong i = 0; i < p_->n; ++i)
138                 if (bwt[i] != bwtTest[i])
139                 {
140                     std::cout << "i = " << i << ", bwt = " << (unsigned)bwt[i] << ", " << (unsigned)bwtTest[i] << std::endl;
141                     assert(0);
142                 }
143             delete [] bwtTest;
144         }
145 #endif // TCB_TEST_BWT
146     }
147
148     TextCollection *result = new TCImplementation(bwt, (ulong)length, p_->samplerate, p_->numberOfTexts, p_->maxTextLength);
149     return result;
150 }
151
152
153 } // namespace SXSI