1 /* static_sequence_wvtree_noptrs.cpp
2 * Copyright (C) 2008, Francisco Claude, all rights reserved.
4 * static_sequence_wvtree_noptrs definition
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
22 #include <static_sequence_wvtree_noptrs.h>
24 static_sequence_wvtree_noptrs::static_sequence_wvtree_noptrs(uint * symbols, uint n, static_bitsequence_builder * bmb, alphabet_mapper * am, bool deleteSymbols) {
29 symbols[i] = am->map(symbols[i]);
30 max_v=max_value(symbols,n);
32 uint *occurrences=new uint[max_v+1];
33 for(uint i=0;i<=max_v;i++) occurrences[i]=0;
35 occurrences[symbols[i]]++;
37 for(uint i=0;i<max_v;i++)
38 if(occurrences[i]==0) to_add++;
39 uint * new_symb = new uint[n+to_add];
41 new_symb[i] = symbols[i];
50 for(uint i=0;i<max_v;i++)
51 if(occurrences[i]==0) {
56 uint new_n = n+to_add;
57 for(uint i=1;i<=max_v;i++)
58 occurrences[i] += occurrences[i-1];
59 uint *oc = new uint[(new_n+1)/W+1];
60 for(uint i=0;i<(new_n+1)/W+1;i++)
62 for(uint i=0;i<=max_v;i++)
63 bitset(oc,occurrences[i]-1);
65 occ = bmb->build(oc,new_n+1);
66 delete [] occurrences;
68 uint ** _bm=new uint*[height];
69 for(uint i=0;i<height;i++) {
70 _bm[i] = new uint[new_n/W+1];
71 for(uint j=0;j<new_n/W+1;j++)
74 build_level(_bm,new_symb,0,new_n,0);
75 bitstring = new static_bitsequence*[height];
76 for(uint i=0;i<height;i++) {
77 bitstring[i] = bmb->build(_bm[i],new_n);
84 symbols[i] = am->unmap(symbols[i]);
86 // delete [] new_symb; // already deleted in build_level()!
90 // symbols is an array of elements of "width" bits
91 static_sequence_wvtree_noptrs::static_sequence_wvtree_noptrs(uint * symbols, uint n, unsigned width, static_bitsequence_builder * bmb, alphabet_mapper * am, bool deleteSymbols) {
96 set_field(symbols, width, i, am->map(get_field(symbols, width, i)));
97 max_v=max_value(symbols, width, n);
99 uint *occurrences=new uint[max_v+1];
100 for(uint i=0;i<=max_v;i++) occurrences[i]=0;
101 for(uint i=0;i<n;i++)
102 occurrences[get_field(symbols, width, i)]++;
104 for(uint i=0;i<max_v;i++)
105 if(occurrences[i]==0) to_add++;
106 uint * new_symb = new uint[((n+to_add)*width)/W + 1];
107 for(uint i=0;i<n;i++)
108 set_field(new_symb, width, i, get_field(symbols, width, i));
117 for(uint i=0;i<max_v;i++)
118 if(occurrences[i]==0) {
120 set_field(new_symb, width, n+to_add, i);
123 uint new_n = n+to_add;
124 for(uint i=1;i<=max_v;i++)
125 occurrences[i] += occurrences[i-1];
126 uint *oc = new uint[(new_n+1)/W+1];
127 for(uint i=0;i<(new_n+1)/W+1;i++)
129 for(uint i=0;i<=max_v;i++)
130 bitset(oc,occurrences[i]-1);
132 occ = bmb->build(oc,new_n+1);
133 delete [] occurrences;
135 uint ** _bm=new uint*[height];
136 for(uint i=0;i<height;i++) {
137 _bm[i] = new uint[new_n/W+1];
138 for(uint j=0;j<new_n/W+1;j++)
141 build_level(_bm,new_symb,width,0,new_n,0);
142 bitstring = new static_bitsequence*[height];
143 for(uint i=0;i<height;i++) {
144 bitstring[i] = bmb->build(_bm[i],new_n);
150 for(uint i=0;i<n;i++)
151 set_field(symbols, width, i, am->unmap(get_field(symbols, width, i)));
153 // delete [] new_symb; // already deleted in build_level()!
157 static_sequence_wvtree_noptrs::static_sequence_wvtree_noptrs() {
160 static_sequence_wvtree_noptrs::~static_sequence_wvtree_noptrs() {
161 for(uint i=0;i<height;i++)
168 uint static_sequence_wvtree_noptrs::save(FILE *fp) {
169 uint wr = WVTREE_NOPTRS_HDR;
170 wr = fwrite(&wr,sizeof(uint),1,fp);
171 wr += fwrite(&n,sizeof(uint),1,fp);
172 wr += fwrite(&max_v,sizeof(uint),1,fp);
173 wr += fwrite(&height,sizeof(uint),1,fp);
175 if(am->save(fp)) return 1;
176 for(uint i=0;i<height;i++)
177 if(bitstring[i]->save(fp)) return 1;
178 if(occ->save(fp)) return 1;
182 static_sequence_wvtree_noptrs * static_sequence_wvtree_noptrs::load(FILE *fp) {
184 if(fread(&rd,sizeof(uint),1,fp)!=1) return NULL;
185 if(rd!=WVTREE_NOPTRS_HDR) return NULL;
186 static_sequence_wvtree_noptrs * ret = new static_sequence_wvtree_noptrs();
187 rd = fread(&ret->n,sizeof(uint),1,fp);
188 rd += fread(&ret->max_v,sizeof(uint),1,fp);
189 rd += fread(&ret->height,sizeof(uint),1,fp);
194 ret->am = alphabet_mapper::load(fp);
200 ret->bitstring = new static_bitsequence*[ret->height];
201 for(uint i=0;i<ret->height;i++) {
202 ret->bitstring[i] = static_bitsequence::load(fp);
203 if(ret->bitstring[i]==NULL){
208 ret->occ = static_bitsequence::load(fp);
216 uint static_sequence_wvtree_noptrs::access(uint pos) {
221 while(level<height) {
222 assert(pos>=start && pos<=end);
223 if(bitstring[level]->access(pos)) {
225 pos=bitstring[level]->rank1(pos-1)-bitstring[level]->rank1(start-1);
226 start=(bitstring[level]->rank1(end)-bitstring[level]->rank1(start-1));
231 pos=pos-start-(bitstring[level]->rank1(pos)-bitstring[level]->rank1(start-1));
232 end=end-start-(bitstring[level]->rank1(end)-bitstring[level]->rank1(start-1));
238 return am->unmap(ret);
241 uint static_sequence_wvtree_noptrs::rank(uint symbol, uint pos) {
242 symbol = am->map(symbol);
247 while(level<height) {
248 if(is_set(symbol,level)) {
249 pos=bitstring[level]->rank1(pos)-bitstring[level]->rank1(start-1)-1;
251 start=(bitstring[level]->rank1(end)-bitstring[level]->rank1(start-1));
256 pos=pos-start+bitstring[level]->rank1(start-1)-bitstring[level]->rank1(pos);
258 end=end-start-(bitstring[level]->rank1(end)-bitstring[level]->rank1(start-1));
263 if(count==0) return 0;
268 vector<int> static_sequence_wvtree_noptrs::access(uint i, uint j, uint min, uint max)
270 vector<int> resultSet;
271 // cout << "height = " << height << endl;
272 access(resultSet, i, j, am->map(min), am->map(max), 0, 0, 0, n-1);
276 void static_sequence_wvtree_noptrs::access(vector<int> &result, uint i, uint j, uint min, uint max, uint l, uint pivot, uint start, uint end)
278 uint symbol = pivot | (1 << (height-l-1));
279 //std::cout << "At l = " << l << ", [" << i << ", " << j << "], [" << min << ", " << max << "], [" << start << ", " << end << "], symbol = " << symbol << std::endl;
283 if (i <= j && pivot >= min && pivot <= max && start <= end)
284 result.push_back(am->unmap((int)pivot));
288 if (j < i || max < min || end < start)
294 uint newi = i + bitstring[l]->rank1(start-1) - bitstring[l]->rank1(i-1);
295 uint newend = end - (bitstring[l]->rank1(end) - bitstring[l]->rank1(start-1));
296 uint newj = j + bitstring[l]->rank1(start-1) - bitstring[l]->rank1(j) + 1;
298 uint newmax = max < symbol - 1 ? max : symbol - 1;
300 access(result, newi, newj-1, min, newmax, l+1, pivot, start, newend);
306 uint newstart = (bitstring[l]->rank1(end)-bitstring[l]->rank1(start-1));
307 newstart = end - newstart + 1;
308 uint newi = bitstring[l]->rank1(i-1)-bitstring[l]->rank1(start-1) + newstart;
309 uint newj = bitstring[l]->rank1(j)-bitstring[l]->rank1(start-1) + newstart;
311 uint newmin = min > symbol ? min : symbol;
313 access(result, newi, newj-1, newmin, max, l+1, symbol, newstart, end);
318 vector<int> static_sequence_wvtree_noptrs::accessAll(uint i, uint j)
320 vector<int> resultSet;
324 resultSet.reserve(j-i+1);
325 accessAll(resultSet, i, j, 0, 0, 0, n-1);
329 void static_sequence_wvtree_noptrs::accessAll(vector<int> &result, uint i, uint j, uint l, uint pivot, uint start, uint end)
331 uint symbol = pivot | (1 << (height-l-1));
332 // std::cout << "At l = " << l << ", [" << i << ", " << j << "], [" << start << ", " << end << "], symbol = " << symbol << std::endl;
336 if (i <= j && start <= end)
337 result.push_back(am->unmap((int)pivot));
341 if (j < i || end < start)
346 uint newi = i + bitstring[l]->rank1(start-1) - bitstring[l]->rank1(i-1);
347 uint newend = end - (bitstring[l]->rank1(end) - bitstring[l]->rank1(start-1));
348 uint newj = j + bitstring[l]->rank1(start-1) - bitstring[l]->rank1(j) + 1;
351 accessAll(result, newi, newj-1, l+1, pivot, start, newend);
356 uint newstart = (bitstring[l]->rank1(end)-bitstring[l]->rank1(start-1));
357 newstart = end - newstart + 1;
358 uint newi = bitstring[l]->rank1(i-1)-bitstring[l]->rank1(start-1) + newstart;
359 uint newj = bitstring[l]->rank1(j)-bitstring[l]->rank1(start-1) + newstart;
362 accessAll(result, newi, newj-1, l+1, symbol, newstart, end);
367 uint static_sequence_wvtree_noptrs::count(uint i, uint j, uint min, uint max)
369 return count(i, j, am->map(min), am->map(max), 0, 0, 0, n-1);
372 uint static_sequence_wvtree_noptrs::count(uint i, uint j, uint min, uint max, uint l, uint pivot, uint start, uint end)
374 uint symbol = pivot | (1 << (height-l-1));
375 //std::cout << "At l = " << l << ", [" << i << ", " << j << "], [" << min << ", " << max << "], [" << start << ", " << end << "], symbol = " << symbol << std::endl;
379 if (i <= j && pivot >= min && pivot <= max && start <= end)
384 if (j < i || max < min || end < start)
391 uint newi = i + bitstring[l]->rank1(start-1) - bitstring[l]->rank1(i-1);
392 uint newend = end - (bitstring[l]->rank1(end) - bitstring[l]->rank1(start-1));
393 uint newj = j + bitstring[l]->rank1(start-1) - bitstring[l]->rank1(j) + 1;
395 uint newmax = max < symbol - 1 ? max : symbol - 1;
397 result += count(newi, newj-1, min, newmax, l+1, pivot, start, newend);
403 uint newstart = (bitstring[l]->rank1(end)-bitstring[l]->rank1(start-1));
404 newstart = end - newstart + 1;
405 uint newi = bitstring[l]->rank1(i-1)-bitstring[l]->rank1(start-1) + newstart;
406 uint newj = bitstring[l]->rank1(j)-bitstring[l]->rank1(start-1) + newstart;
408 uint newmin = min > symbol ? min : symbol;
410 result += count(newi, newj-1, newmin, max, l+1, symbol, newstart, end);
417 inline uint get_start(uint symbol, uint mask) {
421 inline uint get_end(uint symbol, uint mask) {
422 return get_start(symbol,mask)+!mask+1;
425 uint static_sequence_wvtree_noptrs::select(uint symbol, uint j) {
426 symbol = am->map(symbol);
427 uint mask = (1<<height)-2;
429 uint level = height-1;
432 uint start = get_start(symbol,mask);
433 uint end = min(max_v+1,start+sum);
434 start = (start==0)?0:(occ->select1(start)+1);
435 end = occ->select1(end+1)-1;
436 if(is_set(symbol,level)) {
437 uint ones_start = bitstring[level]->rank1(start-1);
438 pos = bitstring[level]->select1(ones_start+pos)-start+1;
441 uint ones_start = bitstring[level]->rank1(start-1);
442 pos = bitstring[level]->select0(start-ones_start+pos)-start+1;
452 uint static_sequence_wvtree_noptrs::size() {
453 uint ptrs = sizeof(static_sequence_wvtree_noptrs)+height*sizeof(static_sequence*);
454 uint bytesBitstrings = 0;
455 for(uint i=0;i<height;i++)
456 bytesBitstrings += bitstring[i]->size();
457 return bytesBitstrings+occ->size()+ptrs;
460 void static_sequence_wvtree_noptrs::build_level(uint **bm, uint *symbols, uint level, uint length, uint offset) {
467 for(uint i=0;i<length;i++)
468 if(!is_set(symbols[i],level))
470 uint cright=length-cleft;
471 uint *left=new uint[cleft], *right=new uint[cright];
473 for(uint i=0;i<length;i++)
474 if(!is_set(symbols[i],level)) {
475 left[cleft++]=symbols[i];
476 bitclean(bm[level],offset+i);
479 right[cright++]=symbols[i];
480 bitset(bm[level],offset+i);
486 build_level(bm,left,level+1,cleft,offset);
487 left = 0; // Gets deleted in recursion.
488 build_level(bm,right,level+1,cright,offset+cleft);
489 right = 0; // Gets deleted in recursion.
494 // symbols is an array of elements of "width" bits.
495 void static_sequence_wvtree_noptrs::build_level(uint **bm, uint *symbols, unsigned width, uint level, uint length, uint offset) {
502 for(uint i=0;i<length;i++)
503 if(!is_set(get_field(symbols, width, i),level))
505 uint cright=length-cleft;
506 uint *left=new uint[(cleft*width)/W + 1],
507 *right=new uint[(cright*width)/W + 1];
509 for(uint i=0;i<length;i++)
510 if(!is_set(get_field(symbols,width,i),level)) {
511 set_field(left,width,cleft++,get_field(symbols, width,i));
512 bitclean(bm[level],offset+i);
515 set_field(right,width,cright++,get_field(symbols,width,i));
516 bitset(bm[level],offset+i);
522 build_level(bm,left,width,level+1,cleft,offset);
523 left = 0; // Gets deleted in recursion.
524 build_level(bm,right,width,level+1,cright,offset+cleft);
525 right = 0; // Gets deleted in recursion.
530 uint static_sequence_wvtree_noptrs::max_value(uint *symbols, uint n) {
532 for(uint i=0;i<n;i++)
533 max_v = max(symbols[i],max_v);
537 uint static_sequence_wvtree_noptrs::max_value(uint *symbols, unsigned width, uint n) {
539 for(uint i=0;i<n;i++)
540 max_v = max(get_field(symbols, width, i),max_v);
544 uint static_sequence_wvtree_noptrs::bits(uint val) {
553 bool static_sequence_wvtree_noptrs::is_set(uint val, uint ind) {
555 return (val & (1<<(height-ind-1)))!=0;
559 uint static_sequence_wvtree_noptrs::set(uint val, uint ind) {
561 return val | (1<<(height-ind-1));