1 /* static_bitsequence_rrr02_light.cpp
2 * Copyright (C) 2008, Francisco Claude, all rights reserved.
4 * static_bitsequence_rrr02_light 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_bitsequence_rrr02_light.h>
25 #define VARS_NEEDED uint C_len = len/BLOCK_SIZE_LIGHT + (len%BLOCK_SIZE_LIGHT!=0);\
26 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);\
27 uint O_len = uint_len(1,O_bits_len);\
28 uint C_sampling_len = C_len/sample_rate+2;\
29 uint C_sampling_field_bits = bits(ones);\
30 uint O_pos_len = C_len/sample_rate+1;\
31 uint O_pos_field_bits = bits(O_bits_len);
34 table_offset * static_bitsequence_rrr02_light::E = NULL;
36 static_bitsequence_rrr02_light::static_bitsequence_rrr02_light() {
39 if(E==NULL) E = new table_offset(BLOCK_SIZE_LIGHT);
45 sample_rate = DEFAULT_SAMPLING_LIGHT;
49 static_bitsequence_rrr02_light::static_bitsequence_rrr02_light(uint * bitseq, uint len, uint sample_rate) {
52 if(E==NULL) E = new table_offset(BLOCK_SIZE_LIGHT);
55 uint C_len = len/BLOCK_SIZE_LIGHT + (len%BLOCK_SIZE_LIGHT!=0);
56 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
57 C = new uint[uint_len(C_len,C_field_bits)];
58 for(uint i=0;i<uint_len(C_len,C_field_bits);i++)
61 for(uint i=0;i<C_len;i++) {
62 uint value = popcount(get_var_field(bitseq,i*BLOCK_SIZE_LIGHT,min((uint)len-1,(i+1)*BLOCK_SIZE_LIGHT-1)));
63 assert(value<=BLOCK_SIZE_LIGHT);
64 set_field(C,C_field_bits,i,value);
66 O_bits_len += E->get_log2binomial(BLOCK_SIZE_LIGHT,value);
69 uint O_len = uint_len(1,O_bits_len);
71 for(uint i=0;i<O_len;i++)
74 for(uint i=0;i<C_len;i++) {
75 uint value = (ushort)get_var_field(bitseq,i*BLOCK_SIZE_LIGHT,min((uint)len-1,(i+1)*BLOCK_SIZE_LIGHT-1));
76 set_var_field(O,O_pos,O_pos+E->get_log2binomial(BLOCK_SIZE_LIGHT,popcount(value))-1,E->compute_offset((ushort)value));
77 O_pos += E->get_log2binomial(BLOCK_SIZE_LIGHT,popcount(value));
82 create_sampling(sample_rate);
85 void static_bitsequence_rrr02_light::create_sampling(uint sample_rate) {
86 this->sample_rate = sample_rate;
87 /* for(uint i=0;i<C_len;i++) {
88 O_bits_len += E->get_log2binomial(BLOCK_SIZE_LIGHT,get_field(C,C_field_bits,i));
91 uint C_len = len/BLOCK_SIZE_LIGHT + (len%BLOCK_SIZE_LIGHT!=0);
92 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
93 uint C_sampling_len = C_len/sample_rate+2;
94 uint C_sampling_field_bits = bits(ones);
95 if(C_sampling!=NULL) delete [] C_sampling;
96 C_sampling = new uint[max((uint)1,uint_len(C_sampling_len,C_sampling_field_bits))];
97 for(uint i=0;i<max((uint)1,uint_len(C_sampling_len,C_sampling_field_bits));i++)
100 for(uint i=0;i<C_len;i++) {
102 set_field(C_sampling,C_sampling_field_bits,i/sample_rate,sum);
103 sum += get_field(C,C_field_bits,i);
105 for(uint i=(C_len-1)/sample_rate+1;i<C_sampling_len;i++)
106 set_field(C_sampling,C_sampling_field_bits,i,sum);
107 // Sampling for O (table S) (Code separated from previous construction for readability)
108 uint O_pos_len = C_len/sample_rate+1;
109 uint O_pos_field_bits = bits(O_bits_len);
110 if(O_pos!=NULL) delete [] O_pos;
111 O_pos = new uint[uint_len(O_pos_len,O_pos_field_bits)];
112 for(uint i=0;i<uint_len(O_pos_len,O_pos_field_bits);i++)
115 for(uint i=0;i<C_len;i++) {
117 set_field(O_pos,O_pos_field_bits,i/sample_rate,pos);
118 pos += E->get_log2binomial(BLOCK_SIZE_LIGHT,get_field(C,C_field_bits,i));
122 bool static_bitsequence_rrr02_light::access(uint i) {
123 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
124 uint O_pos_field_bits = bits(O_bits_len);
125 uint nearest_sampled_value = i/BLOCK_SIZE_LIGHT/sample_rate;
126 uint pos_O = get_field(O_pos,O_pos_field_bits,nearest_sampled_value);
127 uint pos = i/BLOCK_SIZE_LIGHT;
128 for(uint k=nearest_sampled_value*sample_rate;k<pos;k++) {
129 uint aux = get_field(C,C_field_bits,k);
130 pos_O += E->get_log2binomial(BLOCK_SIZE_LIGHT,aux);
132 uint c = get_field(C,C_field_bits,pos);
133 return ((1<<(i%BLOCK_SIZE_LIGHT))&E->short_bitmap(c,get_var_field(O,pos_O,pos_O+E->get_log2binomial(BLOCK_SIZE_LIGHT,c)-1)))!=0;
136 uint static_bitsequence_rrr02_light::rank0(uint i) {
141 uint static_bitsequence_rrr02_light::rank1(uint i) {
142 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
143 uint C_sampling_field_bits = bits(ones);
144 uint O_pos_field_bits = bits(O_bits_len);
146 uint nearest_sampled_value = i/BLOCK_SIZE_LIGHT/sample_rate;
147 uint sum = get_field(C_sampling,C_sampling_field_bits,nearest_sampled_value);
148 uint pos_O = get_field(O_pos,O_pos_field_bits,nearest_sampled_value);
149 uint pos = i/BLOCK_SIZE_LIGHT;
150 uint k=nearest_sampled_value*sample_rate;
151 if(k%2==1 && k<pos) {
152 uint aux = get_field(C,C_field_bits,k);
154 pos_O += E->get_log2binomial(BLOCK_SIZE_LIGHT,aux);
157 uchar * a = (uchar *)C;
160 while(k<(uint)max(0,(int)pos-1)) {
161 assert(((*a)&mask)==get_field(C,C_field_bits,k));
162 assert((*a)/16==get_field(C,C_field_bits,k+1));
163 sum += ((*a)&mask)+(*a)/16;
164 pos_O += E->get_log2binomial(BLOCK_SIZE_LIGHT,((*a)&mask))+E->get_log2binomial(BLOCK_SIZE_LIGHT,((*a)/16));
169 uint aux = get_field(C,C_field_bits,k);
171 pos_O += E->get_log2binomial(BLOCK_SIZE_LIGHT,aux);
174 uint c = get_field(C,C_field_bits,pos);
175 sum += popcount(((2<<(i%BLOCK_SIZE_LIGHT))-1) & E->short_bitmap(c,get_var_field(O,pos_O,pos_O+E->get_log2binomial(BLOCK_SIZE_LIGHT,c)-1)));
179 uint static_bitsequence_rrr02_light::select0(uint i) {
180 uint C_len = len/BLOCK_SIZE_LIGHT + (len%BLOCK_SIZE_LIGHT!=0);
181 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
182 uint C_sampling_len = C_len/sample_rate+2;
183 uint C_sampling_field_bits = bits(ones);
184 uint O_pos_field_bits = bits(O_bits_len);
186 if(i>len-ones) return len;
187 // Search over partial sums
189 uint end=C_sampling_len-1;
190 uint med, acc=0, pos;
193 acc = med*sample_rate*BLOCK_SIZE_LIGHT-get_field(C_sampling,C_sampling_field_bits,med);
195 if(med==start) break;
203 acc = get_field(C_sampling,C_sampling_field_bits,start);
204 while(start<C_len-1 && acc+sample_rate*BLOCK_SIZE_LIGHT==get_field(C_sampling,C_sampling_field_bits,start+1)) {
206 acc +=sample_rate*BLOCK_SIZE_LIGHT;
208 acc = start*sample_rate*BLOCK_SIZE_LIGHT-acc;
209 pos = (start)*sample_rate;
210 uint pos_O = get_field(O_pos,O_pos_field_bits,start);
211 // Sequential search over C
213 for(;pos<C_len;pos++) {
214 s = get_field(C,C_field_bits,pos);
215 if(acc+BLOCK_SIZE_LIGHT-s>=i) break;
216 pos_O += E->get_log2binomial(BLOCK_SIZE_LIGHT,s);
217 acc += BLOCK_SIZE_LIGHT-s;
219 pos = (pos)*BLOCK_SIZE_LIGHT;
220 // Search inside the block
223 uint new_posO = pos_O+E->get_log2binomial(BLOCK_SIZE_LIGHT,s);
224 uint block = E->short_bitmap(s,get_var_field(O,pos_O,new_posO-1));
227 while(acc<i && new_posO<BLOCK_SIZE_LIGHT) {
229 acc += (((block&1)==0)?1:0);
235 assert(rank0(pos)==i);
236 assert(!access(pos));
240 uint static_bitsequence_rrr02_light::select1(uint i) {
241 uint C_len = len/BLOCK_SIZE_LIGHT + (len%BLOCK_SIZE_LIGHT!=0);
242 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
243 uint C_sampling_len = C_len/sample_rate+2;
244 uint C_sampling_field_bits = bits(ones);
245 uint O_pos_field_bits = bits(O_bits_len);
247 if(i>ones) return len;
248 // Search over partial sums
250 uint end=C_sampling_len-1;
251 uint med, acc=0, pos;
254 acc = get_field(C_sampling,C_sampling_field_bits,med);
256 if(med==start) break;
264 acc = get_field(C_sampling,C_sampling_field_bits,start);
265 while(start<C_len-1 && acc==get_field(C_sampling,C_sampling_field_bits,start+1)) start++;
266 pos = (start)*sample_rate;
267 uint pos_O = get_field(O_pos,O_pos_field_bits,start);
268 acc = get_field(C_sampling,C_sampling_field_bits,start);
269 // Sequential search over C
271 for(;pos<C_len;pos++) {
272 s = get_field(C,C_field_bits,pos);
274 pos_O += E->get_log2binomial(BLOCK_SIZE_LIGHT,s);
277 pos = (pos)*BLOCK_SIZE_LIGHT;
278 //cout << "pos=" << pos << endl;
279 // Search inside the block
281 uint new_posO = pos_O+E->get_log2binomial(BLOCK_SIZE_LIGHT,s);
282 uint block = E->short_bitmap(s,get_var_field(O,pos_O,new_posO-1));
285 while(acc<i && new_posO<BLOCK_SIZE_LIGHT) {
287 acc += (((block&1)!=0)?1:0);
290 //cout << "i=" << i << " len=" << len << " ones=" << ones << " pos=" << pos << " acc=" << acc << " rank=" << rank1(pos) << endl;
294 assert(rank1(pos)==i);
299 uint static_bitsequence_rrr02_light::size() {
301 /*cout << "RRR02 SIZE: " << endl;
302 cout << "Default: " << 9*sizeof(uint)+sizeof(uint*)*4 << endl;
303 cout << "Cs: " << uint_len(C_len,C_field_bits)*sizeof(uint) << endl;
304 cout << "Os: " << O_len*sizeof(uint) << endl;
305 cout << "CSamp: " << uint_len(C_sampling_len,C_sampling_field_bits)*sizeof(uint) << endl;
306 cout << "OSamp: " << uint_len(O_pos_len,O_pos_field_bits)*sizeof(uint) << endl;
307 cout << "E: " << E->size() << endl;*/
308 uint sum = sizeof(uint)*8;//sizeof(static_bitsequence_rrr02_light);
309 sum += uint_len(C_len,C_field_bits)*sizeof(uint);
310 sum += O_len*sizeof(uint);
311 sum += uint_len(C_sampling_len,C_sampling_field_bits)*sizeof(uint);
312 sum += uint_len(O_pos_len,O_pos_field_bits)*sizeof(uint);
317 static_bitsequence_rrr02_light::~static_bitsequence_rrr02_light() {
318 if(C!=NULL) delete [] C;
319 if(O!=NULL) delete [] O;
320 if(C_sampling!=NULL) delete [] C_sampling;
321 if(O_pos!=NULL) delete [] O_pos;
325 int static_bitsequence_rrr02_light::save(FILE * fp) {
326 uint C_len = len/BLOCK_SIZE_LIGHT + (len%BLOCK_SIZE_LIGHT!=0);
327 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
328 uint O_len = uint_len(1,O_bits_len);
329 uint wr = RRR02_LIGHT_HDR;
330 wr = fwrite(&wr,sizeof(uint),1,fp);
331 wr += fwrite(&len,sizeof(uint),1,fp);
332 wr += fwrite(&ones,sizeof(uint),1,fp);
333 wr += fwrite(&O_bits_len,sizeof(uint),1,fp);
334 wr += fwrite(&sample_rate,sizeof(uint),1,fp);
336 wr = fwrite(C,sizeof(uint),uint_len(C_len,C_field_bits),fp);
337 if(wr!=uint_len(C_len,C_field_bits)) return -1;
338 wr = fwrite(O,sizeof(uint),O_len,fp);
339 if(wr!=O_len) return -1;
343 static_bitsequence_rrr02_light * static_bitsequence_rrr02_light::load(FILE * fp) {
344 static_bitsequence_rrr02_light * ret = new static_bitsequence_rrr02_light();
346 rd += fread(&type,sizeof(uint),1,fp);
347 rd += fread(&ret->len,sizeof(uint),1,fp);
348 rd += fread(&ret->ones,sizeof(uint),1,fp);
349 rd += fread(&ret->O_bits_len,sizeof(uint),1,fp);
350 rd += fread(&ret->sample_rate,sizeof(uint),1,fp);
351 uint C_len = ret->len/BLOCK_SIZE_LIGHT + (ret->len%BLOCK_SIZE_LIGHT!=0);
352 uint C_field_bits = bits(BLOCK_SIZE_LIGHT);
353 uint O_len = uint_len(1,ret->O_bits_len);
354 if(rd!=5 || type!=RRR02_LIGHT_HDR) {
358 ret->C = new uint[uint_len(C_len,C_field_bits)];
359 rd = fread(ret->C,sizeof(uint),uint_len(C_len,C_field_bits),fp);
360 if(rd!=uint_len(C_len,C_field_bits)) {
365 ret->O = new uint[O_len];
366 rd = fread(ret->O,sizeof(uint),O_len,fp);
372 ret->create_sampling(ret->sample_rate);