size_t PSV::find_PSV_r(size_t v, size_t level, TextIndex *csa, LCP *lcp) const { if(level == r) { return get_field_64(A, b_A, v); } /*look in the same block*/ size_t pos_v = R[level-1]->select1(v+1); size_t value_v = lcp->get_LCP(pos_v-1, csa); size_t aux_psv; size_t pioneer, psv_pioneer; size_t ini_block = b*(v/b); size_t ini_search; if(ini_block==0) ini_block = 1; for(size_t i=v; i >= ini_block; i--) { aux_psv = lcp->get_LCP( R[level-1]->select1(i+1)-1,csa); if(aux_psv < value_v) return i; } if(ini_block==1) return 0; /*find the pioneer*/ if(P[level]->access(pos_v)) pioneer = pos_v; else pioneer = P[level]->select1(P[level]->rank1(pos_v)+1); pioneer = R[level]->rank1(pioneer)-1; /*resolve the pioneer recursive*/ psv_pioneer = find_PSV_r(pioneer, level+1, csa, lcp); psv_pioneer = R[level-1]->rank1(R[level]->select1(psv_pioneer+1))-1; if(psv_pioneer==0) psv_pioneer = 1; ini_search = b*((psv_pioneer+b)/b)-1; /*seek the answer in the same block of the nsv(las_pioneer)*/ for(size_t i= ini_search; i >= psv_pioneer; i--) { aux_psv = lcp->get_LCP(R[level-1]->select1(i+1)-1,csa); if(aux_psv < value_v) return i; } return 0; }
size_t NSV::find_NSV_r(size_t v, size_t level, TextIndex *csa, LCP *lcp) const { if(level == r) { return get_field_64(A, b_A, v); } /*look in the same block*/ size_t num_elements = R[level-1]->rank1(n-1); size_t pos_v = R[level-1]->select1(v+1); size_t value_v = lcp->get_LCP(pos_v, csa); size_t aux_nsv; size_t pioneer, nsv_pioneer; size_t end_block = b*((v+b)/b); if(end_block > num_elements) end_block = num_elements; for(size_t i=v+1; i < end_block; i++) { aux_nsv = lcp->get_LCP(R[level-1]->select1(i+1),csa); if(aux_nsv < value_v) return i; } if(end_block==num_elements) { return num_elements; } /*find the pioneer*/ pioneer = P[level]->select1(P[level]->rank1(pos_v)); pioneer = R[level]->rank1(pioneer)-1; /*resolve the pioneer recursive*/ nsv_pioneer = find_NSV_r(pioneer, level+1, csa, lcp); nsv_pioneer = R[level]->select1(nsv_pioneer+1); if(nsv_pioneer==(size_t)-1) nsv_pioneer = n; nsv_pioneer = R[level-1]->rank1(nsv_pioneer)-1; /*seek the answer in the same block of the nsv(las_pioneer)*/ for(size_t i=(nsv_pioneer/b)*b ; i<=nsv_pioneer; i++) { aux_nsv = lcp->get_LCP(R[level-1]->select1(i+1),csa); if(aux_nsv < value_v) return i; } return num_elements; }
size_t LCP_naive::get_LCP(size_t i, TextIndex *csa) const { return get_field_64(lcp_array, b, i); }