+
+#include "static_sequence_gmr_chunk.h"
+
+static_sequence_gmr_chunk::static_sequence_gmr_chunk(uint * sequence, uint chunk_length, static_bitsequence_builder *bmb, static_permutation_builder *pmb) {
+ sigma = 0;
+ for(uint i=0;i<chunk_length;i++) {
+ sigma = max(sigma,sequence[i]);
+ }
+ uint * X_bitmap = new uint[(1+chunk_length+sigma)/W+1];
+ assert(X_bitmap!=NULL);
+ for(uint i=0;i<(1+sigma+chunk_length)/W+1;i++) X_bitmap[i]=0;
+ uint pi_blen = bits(chunk_length-1);
+ uint * pi = new uint[pi_blen*chunk_length/W+1];
+ assert(pi!=NULL);
+ for(uint i=0;i<pi_blen*chunk_length/W+1;i++) pi[i] = 0;
+ uint X_pos = 0;
+ uint * counter = new uint[sigma+1];
+ for(uint c=0;c<=sigma;c++) counter[c]=0;
+ for(uint i=0;i<chunk_length;i++) counter[sequence[i]+1]++;
+
+ for(uint c=0;c<sigma;c++) {
+ X_pos++;
+ for(uint i=0;i<counter[c+1];i++) {
+ bitset(X_bitmap, X_pos);
+ X_pos++;
+ }
+ counter[c+1]+=counter[c];
+ }
+ X_pos++;
+ for(uint i=0;i<chunk_length;i++) {
+ bitput(pi, pi_blen*counter[sequence[i]], pi_blen, (uint)i);
+ counter[sequence[i]]++;
+ }
+ this->X = new BitRankW32Int(X_bitmap, X_pos, true,20);
+ assert(X!=NULL);
+ this->permutation = createPerm(pi, chunk_length, t);
+ assert(permutation!=NULL);
+ this->sigma = sigma;
+ this->chunk_length = chunk_length;
+ delete [] counter;
+}
+
+
+static_sequence_gmr_chunk::~static_sequence_gmr_chunk() {
+ delete X;
+ delete permutation;
+}
+
+
+uint static_sequence_gmr_chunk::caccess(uint j) {
+ uint invPerm = inversePerm(permutation, j);
+ uint rank_pos = X->select1(invPerm+1);
+ uint ret = rank_pos - X->rank(rank_pos);// - 1;
+ return ret;
+}
+
+
+uint static_sequence_gmr_chunk::cselect(uint i, uint j) {
+ uint pos = X->select0(i+1) + j - i -1;
+ return getelemPerm(permutation, pos);
+}
+
+
+uint static_sequence_gmr_chunk::crank(uint i, uint j) {
+ uint ini = X->select0(i+1)-i;
+ uint ini_o = ini;
+ uint fin = X->select0(i+2);
+ if(fin<i+2) return 0;
+ fin = fin-(i+2);
+ if(fin<ini) return 0;
+ if(getelemPerm(permutation,ini) > j) return 0;
+ if(getelemPerm(permutation,ini) == j) return 1;
+ if(ini==fin) return 1;
+ while(ini < fin-1) {
+ uint med = (ini+fin)/2;
+ uint elem = getelemPerm(permutation, med);
+ if(elem >= j) fin = med;
+ else ini = med;
+ }
+ while(fin>ini_o && getelemPerm(permutation, fin)>j) fin--;
+ return fin-ini_o+1;
+}
+
+
+uint static_sequence_gmr_chunk::size() {
+ return sizeof(BitRankW32Int*)+sizeof(perm*)+(X->SpaceRequirementInBits()/8+sizeofPerm(permutation));
+}