d575e99ac129e5d7576ef027e2cd85fd5ea619f8
[SXSI/XMLTree.git] / libcds / src / static_sequence / static_sequence_gmr_chunk.cpp
1 /* static_sequence_gmr_chunk.cpp
2  * Copyright (C) 2008, Francisco Claude, all rights reserved.
3  *
4  * gmr_chunk
5  *
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.
10  *
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.
15  *
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
19  *
20  */
21  
22 #include "static_sequence_gmr_chunk.h"
23
24 static_sequence_gmr_chunk::static_sequence_gmr_chunk(uint * sequence, uint chunk_length, static_bitsequence_builder *bmb, static_permutation_builder *pmb) {
25   sigma = 0;
26   for(uint i=0;i<chunk_length;i++) {
27     sigma = max(sigma,sequence[i]);
28   }sigma++;
29   uint * X_bitmap = new uint[uint_len(1+chunk_length+sigma,1)];
30   assert(X_bitmap!=NULL);
31   for(uint i=0;i<uint_len(1+chunk_length+sigma,1);i++) X_bitmap[i]=0;
32   uint pi_blen = bits(chunk_length-1);
33   uint * pi = new uint[uint_len(pi_blen,chunk_length)];
34   assert(pi!=NULL);
35   for(uint i=0;i<uint_len(pi_blen,chunk_length);i++) pi[i] = 0;
36   uint X_pos = 0;
37   uint * counter = new uint[sigma+2];
38   for(uint c=0;c<=sigma+1;c++) counter[c]=0;
39   for(uint i=0;i<chunk_length;i++) counter[sequence[i]+1]++;
40
41   for(uint c=0;c<sigma;c++) {
42     X_pos++;
43     for(uint i=0;i<counter[c+1];i++) {
44       bitset(X_bitmap, X_pos);
45       X_pos++;
46     }
47     counter[c+1]+=counter[c];
48   }
49   X_pos++;
50   for(uint i=0;i<chunk_length;i++) {
51     set_field(pi, pi_blen,counter[sequence[i]], i);
52     counter[sequence[i]]++;
53   }
54   //cout << "pi_blen=" << pi_blen << endl;
55   this->X = bmb->build(X_bitmap,X_pos); //new BitRankW32Int(X_bitmap, X_pos, true,20);
56   assert(X!=NULL);
57   delete [] X_bitmap;
58   //cout << "a" << endl; cout.flush();
59   this->permutation = pmb->build(pi,chunk_length); //createPerm(pi, chunk_length, t);
60   //cout << "a" << endl; cout.flush();
61   assert(permutation!=NULL);
62   this->sigma = sigma;
63   this->len = chunk_length;
64         delete [] counter;
65 }
66
67 static_sequence_gmr_chunk::static_sequence_gmr_chunk() {
68 }
69
70 static_sequence_gmr_chunk::~static_sequence_gmr_chunk() {
71         delete X;
72   delete permutation;
73 }
74
75
76 uint static_sequence_gmr_chunk::access(uint j) {
77   uint invPerm = permutation->rev_pi(j); //inversePerm(permutation, j);
78   //cout << "invPerm=" << invPerm << endl;
79   uint rank_pos = X->select1(invPerm+1);
80   //cout << "rank_pos=" << rank_pos << endl;
81   uint ret = rank_pos - X->rank1(rank_pos);// - 1;
82   //cout << "ret = " << ret << endl;
83   return ret;
84 }
85
86
87 uint static_sequence_gmr_chunk::select(uint i, uint j) {
88   uint pos = X->select0(i+1) + j - i -1;
89   /*cout << "pos=" << pos << endl;
90   cout << "pos'=" << X->rank1(X->select0(i+1)+j) << endl;
91   cout << "perm_pos=" << permutation->pi(pos) << endl;*/
92   return permutation->pi(pos); //getelemPerm(permutation, pos);
93 }
94
95
96 uint static_sequence_gmr_chunk::rank(uint i, uint j) {
97   uint ini = X->select0(i+1)-i;
98   uint ini_o = ini;
99   uint fin = X->select0(i+2);
100         if(fin<i+2) return 0;
101         fin = fin-(i+2);
102         if(fin<ini) return 0;
103         if(permutation->pi(ini) > j) return 0;
104         if(permutation->pi(ini) == j) return 1;
105         if(ini==fin) return 1;
106   while(ini < fin-1) {
107                 uint med = (ini+fin)/2;
108     uint elem = permutation->pi(med); //getelemPerm(permutation, med);
109     if(elem >= j) fin = med;
110     else ini = med;
111   }
112         while(fin>ini_o && permutation->pi(fin)>j) fin--;
113   return fin-ini_o+1;
114 }
115
116
117 uint static_sequence_gmr_chunk::size() {
118   return sizeof(static_sequence_gmr_chunk)+permutation->size()+X->size();
119 }
120
121 uint static_sequence_gmr_chunk::save(FILE *fp) {
122   uint wr = GMR_CHUNK_HDR;
123   wr = fwrite(&wr,sizeof(uint),1,fp);
124   wr += fwrite(&len,sizeof(uint),1,fp);
125   wr += fwrite(&sigma,sizeof(uint),1,fp);
126   if(wr!=3) return 1;
127   if(X->save(fp)) return 1;
128   if(permutation->save(fp)) return 1;
129   return 0;
130 }
131
132 static_sequence_gmr_chunk * static_sequence_gmr_chunk::load(FILE *fp) {
133   uint rd;
134   if(fread(&rd,sizeof(uint),1,fp)!=1) return NULL;
135   if(rd!=GMR_CHUNK_HDR) return NULL;
136   static_sequence_gmr_chunk * ret = new static_sequence_gmr_chunk();
137   rd = fread(&ret->len,sizeof(uint),1,fp);
138   rd += fread(&ret->sigma,sizeof(uint),1,fp);
139   ret->X = static_bitsequence::load(fp);
140   ret->permutation = static_permutation::load(fp);
141   if(rd!=2 || ret->X==NULL || ret->permutation==NULL) {
142                 /*cout << "rd=" << rd << endl;
143                 cout << "X =" << ret->X << endl;
144                 cout << "P =" << ret->permutation << endl;*/
145     delete ret;
146     return NULL;
147   }
148   return ret;
149 }