Debug swcsa
[SXSI/TextCollection.git] / TextStorage.cpp
1 /******************************************************************************
2  *   Copyright (C) 2009 Niko Välimäki                                         *
3  *                                                                            *
4  *                                                                            *
5  *   This program is free software; you can redistribute it and/or modify     *
6  *   it under the terms of the GNU Lesser General Public License as published *
7  *   by the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                      *
9  *                                                                            *
10  *   This program is distributed in the hope that it will be useful,          *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of           *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the            *
13  *   GNU Lesser General Public License for more details.                      *
14  *                                                                            *
15  *   You should have received a copy of the GNU Lesser General Public License *
16  *   along with this program; if not, write to the                            *
17  *   Free Software Foundation, Inc.,                                          *
18  *   51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.            *
19  *****************************************************************************/
20
21 #include "TextStorage.h"
22
23 #undef W
24 #undef bitsW
25 #undef bitset
26 #undef bits
27
28 #include "lzindex/lztrie.h"
29
30 // Re-define word size to ulong:
31 #undef W
32 #if __WORDSIZE == 64
33 #   define W 64
34 #else
35 #   define W 32
36 #endif
37 #undef bitset
38 #undef bitget
39 #undef bits
40
41
42 namespace SXSI
43 {
44
45 /******************************************************************
46  * Class TextStorage
47  */
48
49 TextStorage * TextStorage::Load(std::FILE *file)
50 {
51     char type = 0;
52     if (std::fread(&type, sizeof(char), 1, file) != 1)
53         throw std::runtime_error("TextStorage::Load(): file read error (type).");
54
55     switch(type)
56     {
57     case (TYPE_PLAIN_TEXT):
58         return new TextStoragePlainText(file);
59     case (TYPE_LZ_INDEX):
60         return new TextStorageLzIndex(file);
61     default:
62         std::cerr << "TextStorage::Load(): Unknown type in save file!" << std::endl;
63         exit(1);
64     }
65 }
66
67 TextStorage::TextStorage(std::FILE * file)
68     : n_(0), offsets_(0), offit_(0), numberOfTexts_(0)
69 {
70    if (std::fread(&(this->n_), sizeof(TextPosition), 1, file) != 1)
71         throw std::runtime_error("TextStorage::Load(): file read error (n_).");
72
73     if (std::fread(&(this->numberOfTexts_), sizeof(TextPosition), 1, file) != 1)
74         throw std::runtime_error("TextStorage::Load(): file read error (numberOfTexts_).");
75
76     offsets_ = new CSA::DeltaVector(file);   
77     offit_ = new CSA::DeltaVector::Iterator(*offsets_);
78 }
79
80 void TextStorage::Save(FILE *file, char type) const
81 {
82     if (std::fwrite(&type, sizeof(char), 1, file) != 1)
83         throw std::runtime_error("TextStorage::Save(): file write error (type).");
84         
85     if (std::fwrite(&(this->n_), sizeof(TextPosition), 1, file) != 1)
86         throw std::runtime_error("TextStorage::Save(): file write error (n_).");
87     
88     if (std::fwrite(&(this->numberOfTexts_), sizeof(TextPosition), 1, file) != 1)
89         throw std::runtime_error("TextStorage::Save(): file write error (n_).");
90
91     offsets_->writeTo(file);
92 }
93
94
95 /******************************************************************
96  * Class TextStorageLzIndex
97  */
98
99 // Hide the lztrie declaration
100 struct LzTriePimpl 
101 {
102     lztrie lz;
103     
104     LzTriePimpl()
105         : lz(0)
106     { }
107 };    
108
109 TextStorageLzIndex::TextStorageLzIndex(uchar *text, TextPosition n)
110     : TextStorage(text, n), p_(new struct LzTriePimpl)
111
112     for (ulong i = 0; i < n_ - 1; ++i)
113         if (text[i] == 0)
114             text[i] = 1; // '\0' can appear only once.
115     text[n_ - 1] = 0;
116
117     p_->lz = buildLZTrie(text, (uchar)0, n_);
118     delete [] text;
119 }
120
121 TextStorageLzIndex::TextStorageLzIndex(FILE *file)
122     : TextStorage(file), p_(new struct LzTriePimpl)
123 {
124     p_->lz = loadLZTrie(file);
125 }
126
127 void TextStorageLzIndex::Save(FILE *file) const
128 {
129     TextStorage::Save(file, TYPE_LZ_INDEX);
130
131     saveLZTrie(p_->lz, file);
132 }
133
134 TextStorageLzIndex::~TextStorageLzIndex()
135 {
136     destroyLZTrie(p_->lz);
137     delete p_;
138     p_ = 0;
139     n_ = 0;
140 }
141
142 uchar * TextStorageLzIndex::GetText(TextCollection::DocId docId) const
143 {
144     assert(docId < (TextCollection::DocId)numberOfTexts_);
145
146     TextPosition from = offit_->select(docId);
147     TextPosition to = 0;
148     if (docId < (TextCollection::DocId)numberOfTexts_ - 1)
149         to = offit_->select(docId + 1) - 1;
150     else
151         to = n_-1;
152
153     uchar *text = 0;
154     ulong l = 0;
155     extract(p_->lz, from, to, &text, &l);
156
157     text[l-1] = 0;
158     return text;
159 }
160
161 uchar * TextStorageLzIndex::GetText(TextCollection::DocId i, TextCollection::DocId j) const
162 {
163     assert(i < (TextCollection::DocId)numberOfTexts_);
164     assert(j < (TextCollection::DocId)numberOfTexts_);
165
166     TextPosition from = offit_->select(i);
167     TextPosition to = 0;
168     if (j < (TextCollection::DocId)numberOfTexts_ - 1)
169         to = offit_->select(j + 1) - 1;
170     else
171         to = n_-1;
172
173     uchar *text = 0;
174     ulong l = 0;
175     extract(p_->lz, from, to, &text, &l);
176
177     // Put '\0' bytes back in place
178     while (i < j && i < (TextCollection::DocId)numberOfTexts_)
179     {        
180         ++i;
181         text[offit_->select(i) - 1 - from] = 0;
182     }
183     text[l-1] = 0;
184     return text;
185 }
186
187 } // namespace SXSI
188