4 ({ __typeof__ (a) _a = (a); \
5 __typeof__ (b) _b = (b); \
10 ({ __typeof__ (a) _a = (a); \
11 __typeof__ (b) _b = (b); \
12 _a <= _b ? _a : _b; })
18 #define mymalloc(p,n,f) { \
19 p = (__typeof__(p)) malloc((n)*sizeof(*p)); \
20 if ((p)==NULL) {printf("not enough memory (%d bytes) in line %d\n",msize,__LINE__); \
22 msize += (f)*(n)*sizeof(*p); \
25 int postorder_select_bsearch(bp *b,int s);
27 int naive_depth(bp *b, int s)
32 for (i=0; i<=s; i++) {
33 if (getbit(b->B,i)==OP) {
42 void printbp(bp *b, int s, int t)
46 for (i=s; i<=t; i++) {
47 if (getbit(b->B,i)==OP) {
58 int *matchtbl,*parenttbl;
59 void make_naivetbl(pb *B,int n)
64 mymalloc(matchtbl,n,0);
65 mymalloc(parenttbl,n,0);
68 for (i=0; i<n; i++) matchtbl[i] = parenttbl[i] = -1;
74 if (getbit(B,i)==OP) {
77 parenttbl[i] = stack[v-1];
82 matchtbl[stack[v]] = i; // close
83 matchtbl[i] = stack[v]; // open
93 int fwdtbl[(2*ETW+1)*(1<<ETW)];
94 int bwdtbl[(2*ETW+1)*(1<<ETW)];
96 int mintbl_li[1<<ETW], mintbl_lv[1<<ETW];
97 int mintbl_ri[1<<ETW], mintbl_rv[1<<ETW];
98 int maxtbl_li[1<<ETW], maxtbl_lv[1<<ETW];
99 int maxtbl_ri[1<<ETW], maxtbl_rv[1<<ETW];
101 int minmaxtbl_i[4][1<<ETW], minmaxtbl_v[4][1<<ETW];
103 int degtbl2[(2*ETW+1)*(1<<ETW)];
104 int childtbl[(ETW)*(1<<ETW)];
105 int childtbl2[2*ETW+1][ETW][(1<<ETW)];
106 int depthtbl[(2*ETW+1)*(1<<ETW)];
108 void make_matchtbl(void)
117 for (x = 0; x < (1<<ETW); x++) {
118 setbits(buf,0,ETW,x);
119 for (r=-ETW; r<=ETW; r++) fwdtbl[((r+ETW)<<ETW)+x] = ETW;
120 for (r=-ETW; r<=ETW; r++) bwdtbl[((r+ETW)<<ETW)+x] = ETW;
121 for (r=-ETW; r<=ETW; r++) degtbl2[((r+ETW)<<ETW)+x] = 0;
122 for (r=-ETW; r<=ETW; r++) depthtbl[((r+ETW)<<ETW)+x] = 0;
125 for (i=0; i<ETW; i++) {
126 if (getbit(buf,i)==OP) {
131 if (fwdtbl[((r+ETW)<<ETW)+x] == ETW) fwdtbl[((r+ETW)<<ETW)+x] = i;
135 for (i=ETW-1; i>=0; i--) {
136 if (getbit(buf,i)==OP) {
141 if (bwdtbl[((r+ETW)<<ETW)+x] == ETW) bwdtbl[((r+ETW)<<ETW)+x] = ETW-1-i;
145 for (i=0; i<ETW; i++) {
146 if (getbit(buf,i)==OP) {
151 depthtbl[((r+ETW)<<ETW)+x] += (1<<(ETW-1));
155 for (i=0; i<ETW; i++) {
156 if (getbit(buf,i)==OP) r++;
161 m = ETW+1; M = -ETW-1;
162 //maxtbl_lv[x] = -ETW-1;
163 //mintbl_lv[x] = ETW+1;
164 minmaxtbl_v[OPT_MAX | OPT_LEFT][x] = -ETW-1;
165 minmaxtbl_v[OPT_MIN | OPT_LEFT][x] = ETW+1;
167 for (i=0; i<ETW; i++) {
168 if (getbit(buf,i)==OP) {
172 //maxtbl_li[x] = i; maxtbl_lv[x] = r;
173 minmaxtbl_i[OPT_MAX | OPT_LEFT][x] = i;
174 minmaxtbl_v[OPT_MAX | OPT_LEFT][x] = r;
180 childtbl[((deg-1)<<ETW) + x] = i;
184 //mintbl_li[x] = i; mintbl_lv[x] = r;
185 minmaxtbl_i[OPT_MIN | OPT_LEFT][x] = i;
186 minmaxtbl_v[OPT_MIN | OPT_LEFT][x] = r;
188 childtbl[((deg-1)<<ETW) + x] = i;
191 if (r <= m) degtbl2[((r+ETW)<<ETW)+x]++;
196 //maxtbl_rv[x] = -ETW-1;
197 //mintbl_rv[x] = ETW+1;
198 minmaxtbl_v[OPT_MAX | OPT_RIGHT][x] = -ETW-1;
199 minmaxtbl_v[OPT_MIN | OPT_RIGHT][x] = ETW+1;
200 for (i=0; i<ETW; i++) {
201 if (getbit(buf,i)==OP) {
205 //maxtbl_ri[x] = i; maxtbl_rv[x] = r;
206 minmaxtbl_i[OPT_MAX | OPT_RIGHT][x] = i;
207 minmaxtbl_v[OPT_MAX | OPT_RIGHT][x] = r;
213 //mintbl_ri[x] = i; mintbl_rv[x] = r;
214 minmaxtbl_i[OPT_MIN | OPT_RIGHT][x] = i;
215 minmaxtbl_v[OPT_MIN | OPT_RIGHT][x] = r;
220 for (i = 0; i < ETW; i++) {
221 for (j = -ETW; j <= ETW; j++) {
222 childtbl2[j+ETW][i][x] = -1;
226 for (j=-ETW; j<=ETW; j++) {
230 for (i = 0; i < ETW; i++) {
231 if (getbit(buf,i)==OP) {
238 childtbl2[j+ETW][ith-1][x] = i;
248 int bp_construct(bp *b,int n, pb *B, int opt)
258 int r; // # of minimum values
262 printf("warning: SB=%d should be a multiple of D=%d\n",SB,D);
266 printf("warning: SB=%d should be a multiple of RRR=%d\n",SB,RRR);
281 b->da_inorder = NULL;
282 b->da_postorder = NULL;
283 b->da_dfuds_leaf = NULL;
285 darray_construct(b->da,n,B, opt & OPT_FAST_PREORDER_SELECT);
286 b->idx_size += b->da->idx_size;
287 //Kim: comment this and the following, they polute the printing of the xpath library
288 //printf("preorder rank/select table: %d bytes (%1.2f bpc)\n",b->da->idx_size,(double)b->da->idx_size*8/n);
293 mymalloc(sm, ns, 0); b->idx_size += ns * sizeof(*sm);
294 mymalloc(sM, ns, 0); b->idx_size += ns * sizeof(*sM);
297 if (opt & OPT_DEGREE) {
298 mymalloc(sd, ns, 0); b->idx_size += ns * sizeof(*sd);
300 //printf("SB degree table: %d bytes (%1.2f bpc)\n",ns * sizeof(*sd), (double)ns * sizeof(*sd) * 8/n);
302 //printf("SB table: %d bytes (%1.2f bpc)\n",ns * sizeof(*sm) * 2, (double)ns * sizeof(*sm)*2 * 8/n);
304 for (i=0; i<n; i++) {
318 if (i % SB == SB-1 || i==n-1) {
319 ds = depth(b,(i/SB)*SB-1);
320 if (m - ds + SB < 0 || m - ds + SB > 255) {
321 printf("error m=%d ds=%d\n",m,ds);
323 if (M - ds + 1 < 0 || M - ds + 1 > 255) {
324 printf("error M=%d ds=%d\n",M,ds);
326 sm[i/SB] = m - ds + SB;
327 sM[i/SB] = M - ds + 1;
328 if (opt & OPT_DEGREE) sd[i/SB] = r;
334 for (i=0;i<n/SB;i++) printf("%d ",sd[i]);
340 m_ofs = 1 << blog(nm-1);
343 mymalloc(mm, nm + m_ofs, 0); b->idx_size += (nm+m_ofs) * sizeof(*mm);
344 mymalloc(mM, nm + m_ofs, 0); b->idx_size += (nm+m_ofs) * sizeof(*mM);
347 if (opt & OPT_DEGREE) {
348 mymalloc(md, nm + m_ofs, 0); b->idx_size += (nm+m_ofs) * sizeof(*md);
350 //printf("MB degree table: %d bytes (%1.2f bpc)\n",(nm+m_ofs) * sizeof(*md), (double)(nm+m_ofs) * sizeof(*md) * 8/n);
352 //printf("MB table: %d bytes (%1.2f bpc)\n",(nm+m_ofs) * sizeof(*mm) * 2, (double)(nm+m_ofs) * sizeof(*mm)*2 * 8/n);
354 for (i=0; i<n; i++) {
367 if (i % MB == MB-1 || i==n-1) {
370 if (opt & OPT_DEGREE) md[m_ofs+ i/MB] = r;
374 for (j=m_ofs-1; j > 0; j--) {
376 if (j*2 < nm + m_ofs) m = mm[j*2];
377 if (j*2+1 < nm + m_ofs) m = min(m,mm[j*2+1]);
379 if (j*2 < nm + m_ofs) M = mM[j*2];
380 if (j*2+1 < nm + m_ofs) M = max(M,mM[j*2+1]);
381 mm[j] = m; mM[j] = M;
382 if (opt & OPT_DEGREE) {
384 if (j*2 < nm + m_ofs) d = md[j*2];
385 if (j*2+1 < nm + m_ofs) {
386 if (mm[j*2] == mm[j*2+1]) d += md[j*2+1];
387 if (mm[j*2] > mm[j*2+1]) d = md[j*2+1];
394 if (opt & OPT_DEGREE) {
401 for (i=0;i<m_ofs + n/MB;i++) printf("%d ",md[i]);
405 if (opt & OPT_LEAF) {
406 mymalloc(b->da_leaf,1,0);
407 darray_pat_construct(b->da_leaf, n, B, 2, 0x2, opt & OPT_FAST_LEAF_SELECT);
408 //printf("leaf rank/select table: %d bytes (%1.2f bpc)\n",b->da_leaf->idx_size,(double)b->da_leaf->idx_size*8/n);
409 b->idx_size += b->da_leaf->idx_size;
414 if (opt & OPT_INORDER) {
415 mymalloc(b->da_inorder,1,0);
416 darray_pat_construct(b->da_inorder, n, B, 2, 0x1, opt & OPT_FAST_INORDER_SELECT);
417 //printf("inorder rank/select table: %d bytes (%1.2f bpc)\n",b->da_inorder->idx_size,(double)b->da_inorder->idx_size*8/n);
418 b->idx_size += b->da_inorder->idx_size;
420 b->da_inorder = NULL;
423 if (opt & OPT_FAST_POSTORDER_SELECT) {
424 mymalloc(b->da_postorder,1,0);
425 darray_pat_construct(b->da_postorder, n, B, 1, 0x0, (opt & OPT_FAST_POSTORDER_SELECT) | OPT_NO_RANK);
426 //printf("postorder rank/select table: %d bytes (%1.2f bpc)\n",b->da_postorder->idx_size,(double)b->da_postorder->idx_size*8/n);
427 b->idx_size += b->da_postorder->idx_size;
429 b->da_postorder = NULL;
432 if (opt & OPT_DFUDS_LEAF) {
433 mymalloc(b->da_dfuds_leaf,1,0);
434 darray_pat_construct(b->da_dfuds_leaf, n, B, 2, 0x0, opt & OPT_FAST_DFUDS_LEAF_SELECT);
435 //printf("dfuds leaf rank/select table: %d bytes (%1.2f bpc)\n",b->da_dfuds_leaf->idx_size,(double)b->da_dfuds_leaf->idx_size*8/n);
436 b->idx_size += b->da_dfuds_leaf->idx_size;
438 b->da_dfuds_leaf = NULL;
444 // destroyTree: frees the memory of tree.
445 void destroyTree(bp *b) {
446 if (!b) return; // nothing to free
448 destroyDarray(b->da); // destroys da data structure
449 if (b->da) free(b->da);
451 if (b->sm) free(b->sm);
452 if (b->sM) free(b->sM);
453 if (b->sd) free(b->sd);
454 if (b->mm) free(b->mm);
455 if (b->mM) free(b->mM);
456 if (b->md) free(b->md);
458 destroyDarray(b->da_leaf);
459 if (b->da_leaf) free(b->da_leaf);
461 destroyDarray(b->da_inorder);
462 if (b->da_inorder) free(b->da_inorder);
464 destroyDarray(b->da_postorder);
465 if (b->da_postorder) free(b->da_postorder);
467 destroyDarray(b->da_dfuds_leaf);
468 if (b->da_dfuds_leaf) free(b->da_dfuds_leaf);
472 // saveTree: saves parentheses data structure to file
473 // By Diego Arroyuelo
474 void saveTree(bp *b, FILE *fp) {
476 if (fwrite(&(b->n), sizeof(int), 1, fp) != 1) {
477 printf("Error: cannot save number of parentheses to file\n");
481 if (fwrite(b->B, sizeof(pb), (b->n+D-1)/D, fp) != ((b->n+D-1)/D)) {
482 printf("Error: cannot save parentheses sequence to file\n");
486 if (fwrite(&(b->opt), sizeof(int), 1, fp) != 1) {
487 printf("Error: cannot save opt in parentheses to file\n");
492 // loadTree: load parentheses data structure from file
493 // By Diego Arroyuelo
494 void loadTree(bp *b, FILE *fp) {
499 if (fread(&n, sizeof(int), 1, fp) != 1) {
500 printf("Error: cannot read number of parentheses from file\n");
504 mymalloc(B,(n+D-1)/D,0);
506 if (fread(B, sizeof(pb), (n+D-1)/D, fp) != ((n+D-1)/D)) {
507 printf("Error: cannot read parentheses sequence from file\n");
511 if (fread(&opt, sizeof(int), 1, fp) != 1) {
512 printf("Error: cannot read opt in parentheses from file\n");
516 bp_construct(b, n, B, opt);
522 int naive_fwd_excess(bp *b,int s, int rel)
528 for (i=s+1; i<n; i++) {
529 if (getbit(B,i)==OP) {
534 if (v == rel) return i;
539 int naive_bwd_excess(bp *b,int s, int rel)
545 for (i=s; i>=0; i--) {
546 if (getbit(B,i)==OP) {
551 if (v == rel) return i-1;
556 int naive_search_SB_l(bp *b, int i, int rel)
562 if (getbit(b->B,i)==OP) {
567 if (rel == 0) return i-1;
569 if (i < 0) return -2;
573 int naive_rmq(bp *b, int s, int t,int opt)
577 if (opt & OPT_RIGHT) {
578 d = dm = depth(b,t); im = t;
581 if (getbit(b->B,i+1)==CP) {
590 if (!(opt & OPT_MAX)) {
599 d = dm = depth(b,s); im = s;
602 if (getbit(b->B,i)==OP) {
611 if (!(opt & OPT_MAX)) {
629 int rank_open(bp *b, int s)
631 return darray_rank(b->da,s);
634 int rank_close(bp *b, int s)
636 return s+1 - darray_rank(b->da,s);
639 int select_open(bp *b, int s)
641 if (b->opt & OPT_FAST_PREORDER_SELECT) {
642 return darray_select(b->da,s,1);
644 return darray_select_bsearch(b->da,s,getpat_preorder);
648 int select_close(bp *b, int s)
650 if (b->opt & OPT_FAST_POSTORDER_SELECT) {
651 return darray_pat_select(b->da_postorder,s,getpat_postorder);
653 return postorder_select_bsearch(b,s);
657 ///////////////////////////////////////////
658 // find_close(bp *b,int s)
659 // returns the matching close parenthesis of s
660 ///////////////////////////////////////////
661 int find_close(bp *b,int s)
663 return fwd_excess(b,s,-1);
666 ///////////////////////////////////////////
667 // find_open(bp *b,int s)
668 // returns the matching open parenthesis of s
669 ///////////////////////////////////////////
670 int find_open(bp *b,int s)
673 r = bwd_excess(b,s,0);
674 if (r >= -1) return r+1;
678 ///////////////////////////////////////////
679 // parent(bp *b,int s)
680 // returns the parent of s
681 // -1 if s is the root
682 ///////////////////////////////////////////
683 int parent(bp *b,int s)
686 r = bwd_excess(b,s,-2);
687 if (r >= -1) return r+1;
691 int enclose(bp *b,int s)
696 ///////////////////////////////////////////
697 // level_ancestor(bp *b,int s,int d)
698 // returns the ancestor of s with relative depth d (d < 0)
699 // -1 if no such node
700 ///////////////////////////////////////////
701 int level_ancestor(bp *b,int s,int d)
704 r = bwd_excess(b,s,d-1);
705 if (r >= -1) return r+1;
709 ///////////////////////////////////////////
710 // lca(bp *b, int s, int t)
711 // returns the lowest common ancestor of s and t
712 ///////////////////////////////////////////
713 int lca(bp *b, int s, int t)
715 return parent(b,rmq(b,s,t,0)+1);
719 ///////////////////////////////////////////
720 // preorder_rank(bp *b,int s)
721 // returns the preorder (>= 1) of node s (s >= 0)
722 ///////////////////////////////////////////
723 int preorder_rank(bp *b,int s)
725 return darray_rank(b->da,s);
728 ///////////////////////////////////////////
729 // preorder_select(bp *b,int s)
730 // returns the node with preorder s (s >= 1)
731 // -1 if no such node
732 ///////////////////////////////////////////
733 int preorder_select(bp *b,int s)
736 if (b->opt & OPT_FAST_PREORDER_SELECT) {
737 return darray_select(b->da,s,1);
739 return darray_select_bsearch(b->da,s,getpat_preorder);
743 ///////////////////////////////////////////
744 // postorder_rank(bp *b,int s)
745 // returns the postorder (>= 1) of node s (s >= 0)
746 // -1 if s-th bit is not OP
747 ///////////////////////////////////////////
748 int postorder_rank(bp *b,int s)
751 if (inspect(b,s) == CP) return -1;
753 // return t+1 - darray_rank(b->da,t);
754 return rank_close(b,t);
757 int postorder_select_bsearch(bp *b,int s)
761 if (s == 0) return -1;
763 if (s > b->da->n - b->da->m) {
766 l = 0; r = b->da->n - 1;
770 //printf("m=%d rank=%d s=%d\n",m,m+1 - darray_rank(b->da,m),s);
771 if (m+1 - darray_rank(b->da,m) >= s) {
780 ///////////////////////////////////////////
781 // postorder_select(bp *b,int s)
782 // returns the position of CP of the node with postorder s (>= 1)
783 ///////////////////////////////////////////
784 int postorder_select(bp *b,int s)
787 if (b->opt & OPT_FAST_POSTORDER_SELECT) {
788 return darray_pat_select(b->da_postorder,s,getpat_postorder);
790 return postorder_select_bsearch(b->da,s);
793 return select_close(b,s);
797 ///////////////////////////////////////////
798 // leaf_rank(bp *b,int s)
799 // returns the number of leaves to the left of s
800 ///////////////////////////////////////////
801 int leaf_rank(bp *b,int s)
803 if ((b->opt & OPT_LEAF) == 0) {
804 printf("leaf_rank: error!!! not supported\n");
810 return darray_pat_rank(b->da_leaf,s,getpat_leaf);
813 ///////////////////////////////////////////
814 // leaf_select(bp *b,int s)
815 // returns the position of s-th leaf
816 ///////////////////////////////////////////
817 int leaf_select(bp *b,int s)
819 if ((b->opt & OPT_LEAF) == 0) {
820 printf("leaf_select: error!!! not supported\n");
823 if (s > b->da_leaf->m) return -1;
824 if (b->opt & OPT_FAST_LEAF_SELECT) {
825 return darray_pat_select(b->da_leaf,s,getpat_leaf);
827 return darray_select_bsearch(b->da_leaf,s,getpat_leaf);
832 ///////////////////////////////////////////
833 // inorder_rank(bp *b,int s)
834 // returns the number of ")(" (s >= 0)
835 ///////////////////////////////////////////
836 int inorder_rank(bp *b,int s)
838 if ((b->opt & OPT_INORDER) == 0) {
839 printf("inorder_rank: error!!! not supported\n");
845 return darray_pat_rank(b->da_inorder,s,getpat_inorder);
848 ///////////////////////////////////////////
849 // inorder_select(bp *b,int s)
850 // returns the s-th position of ")(" (s >= 1)
851 ///////////////////////////////////////////
852 int inorder_select(bp *b,int s)
854 if ((b->opt & OPT_INORDER) == 0) {
855 printf("inorder_select: error!!! not supported\n");
858 if (b->opt & OPT_FAST_INORDER_SELECT) {
859 return darray_pat_select(b->da_inorder,s,getpat_inorder);
861 return darray_select_bsearch(b->da_inorder,s,getpat_inorder);
865 ///////////////////////////////////////////
866 // leftmost_leaf(bp *b, int s)
867 ///////////////////////////////////////////
868 int leftmost_leaf(bp *b, int s)
870 if ((b->opt & OPT_LEAF) == 0) {
871 printf("leftmost_leaf: error!!! not supported\n");
874 return leaf_select(b,leaf_rank(b,s)+1);
877 ///////////////////////////////////////////
878 // rightmost_leaf(bp *b, int s)
879 ///////////////////////////////////////////
880 int rightmost_leaf(bp *b, int s)
883 if ((b->opt & OPT_LEAF) == 0) {
884 printf("leftmost_leaf: error!!! not supported\n");
888 return leaf_select(b,leaf_rank(b,t));
893 ///////////////////////////////////////////
894 // inspect(bp *b, int s)
895 // returns OP (==1) or CP (==0) at s-th bit (0 <= s < n)
896 ///////////////////////////////////////////
897 int inspect(bp *b, int s)
899 if (s < 0 || s >= b->n) {
900 printf("inspect: error s=%d is out of [%d,%d]\n",s,0,b->n-1);
902 return getbit(b->B,s);
905 int isleaf(bp *b, int s)
907 if (inspect(b,s) != OP) {
908 printf("isleaf: error!!! B[%d] = OP\n",s);
910 if (inspect(b,s+1) == CP) return 1;
915 ///////////////////////////////////////////
916 // subtree_size(bp *b, int s)
917 // returns the number of nodes in the subtree of s
918 ///////////////////////////////////////////
919 int subtree_size(bp *b, int s)
921 return (find_close(b,s) - s + 1) / 2;
924 ///////////////////////////////////////////
925 // first_child(bp *b, int s)
926 // returns the first child
928 ///////////////////////////////////////////
929 int first_child(bp *b, int s)
931 if (inspect(b,s+1) == CP) return -1;
935 ///////////////////////////////////////////
936 // next_sibling(bp *b,int s)
937 // returns the next sibling of parent(s)
938 // -1 if s is the last child
939 //////////////////////////////////////////
940 int next_sibling(bp *b, int s)
943 t = find_close(b,s)+1;
945 printf("next_sibling: error s=%d t=%d\n",s,t);
947 if (inspect(b,t) == CP) return -1;
951 ///////////////////////////////////////////
952 // prev_sibling(bp *b,int s)
953 // returns the previous sibling of parent(s)
954 // -1 if s is the first child
955 //////////////////////////////////////////
956 int prev_sibling(bp *b, int s)
960 printf("prev_sibling: error s=%d\n",s);
962 if (s == 0) return -1;
963 if (inspect(b,s-1) == OP) return -1;
964 t = find_open(b,s-1);
968 ///////////////////////////////////////////
969 // deepest_node(bp *b,int s)
970 // returns the first node with the largest depth in the subtree of s
971 ///////////////////////////////////////////
972 int deepest_node(bp *b,int s)
976 m = rmq(b,s,t, OPT_MAX);
980 ///////////////////////////////////////////
981 // subtree_height(bp *b,int s)
982 // returns the height of the subtree of s
984 ///////////////////////////////////////////
985 int subtree_height(bp *b,int s)
988 t = deepest_node(b,s);
989 return depth(b,t) - depth(b,s);
992 int naive_degree(bp *b, int s)
996 t = first_child(b,s);
999 t = next_sibling(b,t);
1004 ///////////////////////////////////////////
1005 // degree(bp *b, int s)
1006 // returns the number of children of s
1008 ///////////////////////////////////////////
1009 int degree(bp *b, int s)
1011 if (b->opt & OPT_DEGREE) {
1012 return fast_degree(b,s,b->n,0);
1014 return naive_degree(b,s);
1018 int naive_child(bp *b, int s, int d)
1021 t = first_child(b,s);
1022 for (i = 1; i < d; i++) {
1024 t = next_sibling(b,t);
1029 ///////////////////////////////////////////
1030 // child(bp *b, int s, int d)
1031 // returns the d-th child of s (1 <= d <= degree(s))
1032 // -1 if no such node
1033 ///////////////////////////////////////////
1034 int child(bp *b, int s, int d)
1037 if (b->opt & OPT_DEGREE) {
1038 //return find_open(b,fast_degree(b,s,b->n,d));
1039 if (d==1) return first_child(b,s);
1040 r = fast_degree(b,s,b->n,d-1)+1;
1041 if (inspect(b,r) == CP) return -1;
1044 return naive_child(b,s,d);
1050 int naive_child_rank(bp *b, int t)
1056 t = prev_sibling(b,t);
1061 ///////////////////////////////////////////
1062 // child_rank(bp *b, int t)
1063 // returns d if t is the d-th child of the parent of t (d >= 1)
1064 // 1 if t is the root
1065 ///////////////////////////////////////////
1066 int child_rank(bp *b, int t)
1069 if (t == root_node(b)) return 1;
1070 if (b->opt & OPT_DEGREE) {
1072 return fast_degree(b,r,t,0)+1;
1074 return naive_child_rank(b,t);
1080 ///////////////////////////////////////////
1081 // is_ancestor(bp *b, int s, int t)
1082 // returns 1 if s is an ancestor of t
1084 ///////////////////////////////////////////
1085 int is_ancestor(bp *b, int s, int t)
1088 v = find_close(b,s);
1089 if (s <= t && t <= v) return 1;
1093 ///////////////////////////////////////////
1094 // distance(bp *b, int s, int t)
1095 // returns the length of the shortest path from s to t in the tree
1096 ///////////////////////////////////////////
1097 int distance(bp *b, int s, int t)
1102 return (depth(b,s) - d) + (depth(b,t) - d);
1105 ///////////////////////////////////////////
1106 // level_next(bp *b, int d)
1107 ///////////////////////////////////////////
1108 int level_next(bp *b,int s)
1111 t = fwd_excess(b,s,0);
1115 ///////////////////////////////////////////
1116 // level_prev(bp *b, int d)
1117 ///////////////////////////////////////////
1118 int level_prev(bp *b,int s)
1121 t = bwd_excess(b,s,0);
1125 ///////////////////////////////////////////
1126 // level_leftmost(bp *b, int d)
1127 ///////////////////////////////////////////
1128 int level_leftmost(bp *b, int d)
1131 if (d < 1) return -1;
1132 if (d == 1) return 0;
1133 t = fwd_excess(b,0,d);
1137 ///////////////////////////////////////////
1138 // level_rigthmost(bp *b, int d)
1139 ///////////////////////////////////////////
1140 int level_rigthmost(bp *b, int d)
1143 if (d < 1) return -1;
1144 if (d == 1) return 0;
1145 t = bwd_excess(b,0,d-1);
1146 return find_open(b,t);
1149 ///////////////////////////////////////////
1150 // leaf_size(bp *b, int s)
1151 ///////////////////////////////////////////
1152 int leaf_size(bp *b, int s)
1155 if ((b->opt & OPT_LEAF) == 0) {
1156 printf("leaf_size: error!!! not supported\n");
1159 t = find_close(b,s);
1160 return leaf_rank(b,t) - leaf_rank(b,s);