Debug swcsa
[SXSI/TextCollection.git] / RLCSABuilder.cpp
1 #include "incbwt/rlcsa_builder.h"
2 #include "RLCSABuilder.h"
3 #include "RLCSAWrapper.h"
4
5 namespace SXSI
6 {
7
8 // Using pimpl idiom to hide RLCSABuilder*
9 struct TCBuilderRep
10 {
11     unsigned samplerate;
12     CSA::RLCSABuilder * sa;
13
14     ulong n;
15     unsigned numberOfTexts;
16     bool insertAllowed;
17 };
18
19 /**
20  * Init text collection
21  */
22 RLCSABuilder::RLCSABuilder(unsigned samplerate, ulong estimatedInputLength)
23     : p_(new struct TCBuilderRep())
24 {
25     p_->n = 0;
26     p_->samplerate = samplerate;
27     if (samplerate == 0)
28         p_->samplerate = TEXTCOLLECTION_DEFAULT_SAMPLERATE;
29
30     p_->numberOfTexts = 0;
31     p_->insertAllowed = true;
32
33     CSA::usint rlcsa_block_size = CSA::RLCSA_BLOCK_SIZE.second;
34     CSA::usint rlcsa_sample_rate = p_->samplerate;
35  
36     // Parameters for RLCSA: 32 bytes, samples, buffer size n/10 bytes.
37     // Buffer size is always at least 15MB:
38     if (estimatedInputLength < TEXTCOLLECTION_DEFAULT_INPUT_LENGTH)
39         estimatedInputLength = TEXTCOLLECTION_DEFAULT_INPUT_LENGTH;
40     p_->sa = new CSA::RLCSABuilder(rlcsa_block_size, rlcsa_sample_rate, estimatedInputLength/10);
41     assert(p_->sa->isOk());
42 }
43
44 RLCSABuilder::~RLCSABuilder()
45 {
46     delete p_->sa;
47     delete p_;
48 }
49
50 void RLCSABuilder::InsertText(uchar const * text, bool index)
51 {
52     assert(index);
53     if (!index)
54     {
55         std::cerr << "SWCSABuilder::InsertText(): The implementation of SWCSA does not support non-indexed texts" 
56                   << std::endl << "Use the default (FMIndex) text collection instead." << std::endl;
57         std::exit(1);                
58     }
59     
60     if (!p_->insertAllowed)
61     {
62         std::cerr << "RLCSABuilder::InsertText() error: new text can not be inserted after InitTextCollection() call!" << std::endl;
63         std::exit(1);
64     }
65
66     TextCollection::TextPosition m = std::strlen((char *)text) + 1;
67     if (m > 1)
68     {
69         p_->n += m;
70         p_->numberOfTexts ++;
71
72         p_->sa->insertSequence((char*)text, m-1, 0);
73         assert(p_->sa->isOk());
74     }
75     else
76     {
77         // FIXME indexing empty texts
78         std::cerr << "RLCSABuilder::InsertText() error: can not index empty texts!" << std::endl;
79         exit(1);
80     }
81 }
82
83 TextCollection * RLCSABuilder::InitTextCollection(char type)
84 {
85     p_->insertAllowed = false; // Disable future insertions
86     assert(type == TextStorage::TYPE_PLAIN_TEXT);
87     if (type != TextStorage::TYPE_PLAIN_TEXT)
88     {
89         std::cerr << "RLCSABuilder::InitTextCollection(): The implementation of RLCSA supports only TextStorage::TYPE_PLAIN_TEXT" 
90                   << std::endl << "Use the default (FMIndex) text collection instead." << std::endl;
91         std::exit(1);
92     }
93     
94     TextCollection *result = new RLCSAWrapper(p_->sa->getRLCSA());
95     delete p_->sa;
96     p_->sa = 0;
97     return result;
98 }
99 }