9 ({ __typeof__ (a) _a = (a); \
10 __typeof__ (b) _b = (b); \
15 ({ __typeof__ (a) _a = (a); \
16 __typeof__ (b) _b = (b); \
17 _a <= _b ? _a : _b; })
21 static int postorder_select_bsearch(bp *b,int s);
23 static int naive_depth(bp *b, int s)
28 for (i=0; i<=s; i++) {
29 if (bp_getbit(b->B,i)==OP) {
38 void bp_print(bp *b, int s, int t)
42 for (i=s; i<=t; i++) {
43 if (bp_getbit(b->B,i)==OP) {
54 int *matchtbl,*parenttbl;
55 static void make_naivetbl(pb *B,int n)
60 bp_xmalloc(matchtbl,n);
61 bp_xmalloc(parenttbl,n);
64 for (i=0; i<n; i++) matchtbl[i] = parenttbl[i] = -1;
70 if (bp_getbit(B,i)==OP) {
73 parenttbl[i] = stack[v-1];
78 matchtbl[stack[v]] = i; // close
79 matchtbl[i] = stack[v]; // open
89 int fwdtbl[(2*ETW+1)*(1<<ETW)];
90 int bwdtbl[(2*ETW+1)*(1<<ETW)];
92 int mintbl_li[1<<ETW], mintbl_lv[1<<ETW];
93 int mintbl_ri[1<<ETW], mintbl_rv[1<<ETW];
94 int maxtbl_li[1<<ETW], maxtbl_lv[1<<ETW];
95 int maxtbl_ri[1<<ETW], maxtbl_rv[1<<ETW];
97 int minmaxtbl_i[4][1<<ETW], minmaxtbl_v[4][1<<ETW];
99 int degtbl2[(2*ETW+1)*(1<<ETW)];
100 int childtbl[(ETW)*(1<<ETW)];
101 int childtbl2[2*ETW+1][ETW][(1<<ETW)];
102 int depthtbl[(2*ETW+1)*(1<<ETW)];
105 static void make_matchtbl(void)
114 for (x = 0; x < (1<<ETW); x++) {
115 bp_setbits(buf,0,ETW,x);
116 for (r=-ETW; r<=ETW; r++) fwdtbl[((r+ETW)<<ETW)+x] = ETW;
117 for (r=-ETW; r<=ETW; r++) bwdtbl[((r+ETW)<<ETW)+x] = ETW;
118 for (r=-ETW; r<=ETW; r++) degtbl2[((r+ETW)<<ETW)+x] = 0;
119 for (r=-ETW; r<=ETW; r++) depthtbl[((r+ETW)<<ETW)+x] = 0;
122 for (i=0; i<ETW; i++) {
123 if (bp_getbit(buf,i)==OP) {
128 if (fwdtbl[((r+ETW)<<ETW)+x] == ETW) fwdtbl[((r+ETW)<<ETW)+x] = i;
132 for (i=ETW-1; i>=0; i--) {
133 if (bp_getbit(buf,i)==OP) {
138 if (bwdtbl[((r+ETW)<<ETW)+x] == ETW) bwdtbl[((r+ETW)<<ETW)+x] = ETW-1-i;
142 for (i=0; i<ETW; i++) {
143 if (bp_getbit(buf,i)==OP) {
148 depthtbl[((r+ETW)<<ETW)+x] += (1<<(ETW-1));
153 m = ETW+1; M = -ETW-1;
154 //maxtbl_lv[x] = -ETW-1;
155 //mintbl_lv[x] = ETW+1;
156 minmaxtbl_v[OPT_MAX | OPT_LEFT][x] = -ETW-1;
157 minmaxtbl_v[OPT_MIN | OPT_LEFT][x] = ETW+1;
159 for (i=0; i<ETW; i++) {
160 if (bp_getbit(buf,i)==OP) {
164 //maxtbl_li[x] = i; maxtbl_lv[x] = r;
165 minmaxtbl_i[OPT_MAX | OPT_LEFT][x] = i;
166 minmaxtbl_v[OPT_MAX | OPT_LEFT][x] = r;
172 childtbl[((deg-1)<<ETW) + x] = i;
176 //mintbl_li[x] = i; mintbl_lv[x] = r;
177 minmaxtbl_i[OPT_MIN | OPT_LEFT][x] = i;
178 minmaxtbl_v[OPT_MIN | OPT_LEFT][x] = r;
180 childtbl[((deg-1)<<ETW) + x] = i;
183 if (r <= m) degtbl2[((r+ETW)<<ETW)+x]++;
188 //maxtbl_rv[x] = -ETW-1;
189 //mintbl_rv[x] = ETW+1;
190 minmaxtbl_v[OPT_MAX | OPT_RIGHT][x] = -ETW-1;
191 minmaxtbl_v[OPT_MIN | OPT_RIGHT][x] = ETW+1;
192 for (i=0; i<ETW; i++) {
193 if (bp_getbit(buf,i)==OP) {
197 //maxtbl_ri[x] = i; maxtbl_rv[x] = r;
198 minmaxtbl_i[OPT_MAX | OPT_RIGHT][x] = i;
199 minmaxtbl_v[OPT_MAX | OPT_RIGHT][x] = r;
205 //mintbl_ri[x] = i; mintbl_rv[x] = r;
206 minmaxtbl_i[OPT_MIN | OPT_RIGHT][x] = i;
207 minmaxtbl_v[OPT_MIN | OPT_RIGHT][x] = r;
212 for (i = 0; i < ETW; i++) {
213 for (j = -ETW; j <= ETW; j++) {
214 childtbl2[j+ETW][i][x] = -1;
218 for (j=-ETW; j<=ETW; j++) {
222 for (i = 0; i < ETW; i++) {
223 if (bp_getbit(buf,i)==OP) {
230 childtbl2[j+ETW][ith-1][x] = i;
240 bp * bp_construct(int n, pb *B, int opt)
251 int r; // # of minimum values
265 b->da_inorder = NULL;
266 b->da_postorder = NULL;
267 b->da_dfuds_leaf = NULL;
268 b->da = bp_darray_construct(n,B, opt & OPT_FAST_PREORDER_SELECT);
269 b->idx_size += b->da->idx_size;
277 b->idx_size += ns * sizeof(*sm);
280 b->idx_size += ns * sizeof(*sM);
285 if (opt & OPT_DEGREE) {
287 b->idx_size += ns * sizeof(*sd);
291 for (i=0; i<n; i++) {
305 if (i % SB == SB-1 || i==n-1) {
306 ds = bp_depth(b,(i/SB)*SB-1);
307 if (m - ds + SB < 0 || m - ds + SB > 255) {
308 printf("error m=%d ds=%d\n",m,ds);
310 if (M - ds + 1 < 0 || M - ds + 1 > 255) {
311 printf("error M=%d ds=%d\n",M,ds);
313 sm[i/SB] = m - ds + SB;
314 sM[i/SB] = M - ds + 1;
315 if (opt & OPT_DEGREE) sd[i/SB] = r;
321 m_ofs = 1 << blog(nm-1);
324 bp_xmalloc(mm, nm + m_ofs);
325 b->idx_size += (nm+m_ofs) * sizeof(*mm);
327 bp_xmalloc(mM, nm + m_ofs);
328 b->idx_size += (nm+m_ofs) * sizeof(*mM);
332 if (opt & OPT_DEGREE) {
333 bp_xmalloc(md, nm + m_ofs);
334 b->idx_size += (nm+m_ofs) * sizeof(*md);
338 for (i=0; i<n; i++) {
351 if (i % MB == MB-1 || i==n-1) {
354 if (opt & OPT_DEGREE) md[m_ofs+ i/MB] = r;
358 for (j=m_ofs-1; j > 0; j--) {
360 if (j*2 < nm + m_ofs) m = mm[j*2];
361 if (j*2+1 < nm + m_ofs) m = min(m,mm[j*2+1]);
363 if (j*2 < nm + m_ofs) M = mM[j*2];
364 if (j*2+1 < nm + m_ofs) M = max(M,mM[j*2+1]);
365 mm[j] = m; mM[j] = M;
366 if (opt & OPT_DEGREE) {
368 if (j*2 < nm + m_ofs) d = md[j*2];
369 if (j*2+1 < nm + m_ofs) {
370 if (mm[j*2] == mm[j*2+1]) d += md[j*2+1];
371 if (mm[j*2] > mm[j*2+1]) d = md[j*2+1];
378 if (opt & OPT_DEGREE) {
383 if (opt & OPT_LEAF) {
384 b->da_leaf = bp_darray_pat_construct(n, B, 2, 0x2, opt & OPT_FAST_LEAF_SELECT);
385 b->idx_size += b->da_leaf->idx_size;
390 if (opt & OPT_INORDER) {
392 b->da_inorder = bp_darray_pat_construct(n, B, 2, 0x1, opt & OPT_FAST_INORDER_SELECT);
393 b->idx_size += b->da_inorder->idx_size;
396 b->da_inorder = NULL;
399 if (opt & OPT_FAST_POSTORDER_SELECT) {
401 b->da_postorder = bp_darray_pat_construct(n, B, 1, 0x0, (opt & OPT_FAST_POSTORDER_SELECT) | OPT_NO_RANK);
402 b->idx_size += b->da_postorder->idx_size;
405 b->da_postorder = NULL;
408 if (opt & OPT_DFUDS_LEAF) {
409 b->da_dfuds_leaf = bp_darray_pat_construct( n, B, 2, 0x0, opt & OPT_FAST_DFUDS_LEAF_SELECT);
410 b->idx_size += b->da_dfuds_leaf->idx_size;
413 b->da_dfuds_leaf = NULL;
419 void bp_delete(bp *b) {
420 if (!b) return; // nothing to free
422 bp_darray_free(b->da); // destroys da data structure
423 if (b->sm) free(b->sm);
424 if (b->sM) free(b->sM);
425 if (b->sd) free(b->sd);
426 if (b->mm) free(b->mm);
427 if (b->mM) free(b->mM);
428 if (b->md) free(b->md);
430 bp_darray_free(b->da_leaf);
432 bp_darray_free(b->da_inorder);
434 bp_darray_free(b->da_postorder);
436 bp_darray_free(b->da_dfuds_leaf);
442 // saveTree: saves parentheses data structure to file
443 // By Diego Arroyuelo
444 void saveTree(bp *b, FILE *fp) {
446 if (fwrite(&(b->n), sizeof(int), 1, fp) != 1) {
447 printf("Error: cannot save number of parentheses to file\n");
450 if (fwrite(b->B, sizeof(pb), (b->n+D-1)/D, fp) != ((b->n+D-1)/D)) {
451 printf("Error: cannot save parentheses sequence to file\n");
455 if (fwrite(&(b->opt), sizeof(int), 1, fp) != 1) {
456 printf("Error: cannot save opt in parentheses to file\n");
461 static ssize_t uwrite(int fd, const void* buff, size_t count)
464 char *p = (char *) buff;
466 written = write(fd, p, count);
469 } while (written > 0);
471 return (written == -1);
474 static ssize_t uread(int fd, const void* buff, size_t count)
477 char *p = (char *) buff;
479 loaded = read(fd, p, count);
482 } while (loaded > 0);
484 return (loaded == -1);
487 int bp_save(bp *b, int fd)
489 if (uwrite(fd, &b->n, sizeof(int))) return 1;
490 if (uwrite(fd, b->B, sizeof(pb) * (b->n+D-1)/D)) return 1;
491 if (uwrite(fd, &b->opt, sizeof(int))) return 1;
499 if (uread(fd, &n, sizeof(int))) return NULL;
500 bp_xmalloc(B, (n+D-1)/D);
502 if (B == NULL) return NULL;
504 if (uread(fd, B, sizeof(pb) * (n+D-1)/D)) {
509 if (uread(fd, &opt, sizeof(int))){
514 return bp_construct(n, B, opt);
518 // loadTree: load parentheses data structure from file
519 // By Diego Arroyuelo
520 bp * loadTree(FILE *fp) {
525 if (fread(&n, sizeof(int), 1, fp) != 1) {
526 printf("Error: cannot read number of parentheses from file\n");
530 bp_xmalloc(B, (n+D-1)/D);
532 if (fread(B, sizeof(pb), (n+D-1)/D, fp) != ((n+D-1)/D)) {
533 printf("Error: cannot read parentheses sequence from file\n");
537 if (fread(&opt, sizeof(int), 1, fp) != 1) {
538 printf("Error: cannot read opt in parentheses from file\n");
542 return bp_construct(n, B, opt);
547 static int naive_fwd_excess(bp *b,int s, int rel)
553 for (i=s+1; i<n; i++) {
554 if (bp_getbit(B,i)==OP) {
559 if (v == rel) return i;
564 static int naive_bwd_excess(bp *b,int s, int rel)
570 for (i=s; i>=0; i--) {
571 if (bp_getbit(B,i)==OP) {
576 if (v == rel) return i-1;
581 static int naive_search_SB_l(bp *b, int i, int rel)
587 if (bp_getbit(b->B,i)==OP) {
592 if (rel == 0) return i-1;
594 if (i < 0) return -2;
598 int bp_naive_rmq(bp *b, int s, int t,int opt)
602 if (opt & OPT_RIGHT) {
603 d = dm = bp_depth(b,t); im = t;
606 if (bp_getbit(b->B,i+1)==CP) {
615 if (!(opt & OPT_MAX)) {
624 d = dm = bp_depth(b,s); im = s;
627 if (bp_getbit(b->B,i)==OP) {
636 if (!(opt & OPT_MAX)) {
650 int bp_rank_open(bp *b, int s)
652 return bp_darray_rank(b->da, s);
655 int bp_rank_close(bp *b, int s)
657 return s+1 - bp_darray_rank(b->da, s);
660 int bp_select_open(bp *b, int s)
662 if (b->opt & OPT_FAST_PREORDER_SELECT) {
663 return bp_darray_select(b->da,s,1);
665 return bp_darray_select_bsearch(b->da, s, getpat_preorder);
669 int bp_select_close(bp *b, int s)
671 if (b->opt & OPT_FAST_POSTORDER_SELECT) {
672 return bp_darray_pat_select(b->da_postorder, s, getpat_postorder);
674 return postorder_select_bsearch(b,s);
679 ///////////////////////////////////////////
680 // bp_postorder_rank(bp *b,int s)
681 // returns the postorder (>= 1) of node s (s >= 0)
682 // -1 if s-th bit is not OP
683 ///////////////////////////////////////////
684 int bp_postorder_rank(bp *b,int s)
687 if (bp_inspect(b,s) == CP) return -1;
688 t = bp_find_close(b,s);
689 // return t+1 - darray_rank(b->da,t);
690 return bp_rank_close(b,t);
693 static int postorder_select_bsearch(bp *b,int s)
697 if (s == 0) return -1;
699 if (s > b->da->n - b->da->m) {
702 l = 0; r = b->da->n - 1;
706 //printf("m=%d rank=%d s=%d\n",m,m+1 - darray_rank(b->da,m),s);
707 if (m+1 - bp_darray_rank(b->da,m) >= s) {
716 ///////////////////////////////////////////
717 // bp_postorder_select(bp *b,int s)
718 // returns the position of CP of the node with postorder s (>= 1)
719 ///////////////////////////////////////////
720 int bp_postorder_select(bp *b,int s)
723 if (b->opt & OPT_FAST_POSTORDER_SELECT) {
724 return bp_darray_pat_select(b->da_postorder,s,getpat_postorder);
726 return postorder_select_bsearch(b->da,s);
729 return bp_select_close(b,s);
733 ///////////////////////////////////////////
734 // bp_leaf_rank(bp *b,int s)
735 // returns the number of leaves to the left of s
736 ///////////////////////////////////////////
737 int bp_leaf_rank(bp *b,int s)
739 if ((b->opt & OPT_LEAF) == 0) {
740 printf("leaf_rank: error!!! not supported\n");
746 return bp_darray_pat_rank(b->da_leaf,s,getpat_leaf);
749 ///////////////////////////////////////////
750 // leaf_select(bp *b,int s)
751 // returns the position of s-th leaf
752 ///////////////////////////////////////////
753 int bp_leaf_select(bp *b,int s)
755 if ((b->opt & OPT_LEAF) == 0) {
756 printf("leaf_select: error!!! not supported\n");
759 if (s > b->da_leaf->m) return -1;
760 if (b->opt & OPT_FAST_LEAF_SELECT) {
761 return bp_darray_pat_select(b->da_leaf,s,getpat_leaf);
763 return bp_darray_select_bsearch(b->da_leaf,s,getpat_leaf);
768 ///////////////////////////////////////////
769 // bp_inorder_rank(bp *b,int s)
770 // returns the number of ")(" (s >= 0)
771 ///////////////////////////////////////////
772 int bp_inorder_rank(bp *b,int s)
774 if ((b->opt & OPT_INORDER) == 0) {
775 printf("inorder_rank: error!!! not supported\n");
781 return bp_darray_pat_rank(b->da_inorder,s,getpat_inorder);
784 ///////////////////////////////////////////
785 // bp_inorder_select(bp *b,int s)
786 // returns the s-th position of ")(" (s >= 1)
787 ///////////////////////////////////////////
788 int bp_inorder_select(bp *b,int s)
790 if ((b->opt & OPT_INORDER) == 0) {
791 printf("inorder_select: error!!! not supported\n");
794 if (b->opt & OPT_FAST_INORDER_SELECT) {
795 return bp_darray_pat_select(b->da_inorder,s,getpat_inorder);
797 return bp_darray_select_bsearch(b->da_inorder,s,getpat_inorder);
801 ///////////////////////////////////////////
802 // bp_leftmost_leaf(bp *b, int s)
803 ///////////////////////////////////////////
804 int bp_leftmost_leaf(bp *b, int s)
806 if ((b->opt & OPT_LEAF) == 0) {
807 printf("leftmost_leaf: error!!! not supported\n");
810 return bp_leaf_select(b, bp_leaf_rank(b,s)+1);
813 ///////////////////////////////////////////
814 // rightmost_leaf(bp *b, int s)
815 ///////////////////////////////////////////
816 int bp_rightmost_leaf(bp *b, int s)
819 if ((b->opt & OPT_LEAF) == 0) {
820 printf("leftmost_leaf: error!!! not supported\n");
823 t = bp_find_close(b,s);
824 return bp_leaf_select(b, bp_leaf_rank(b,t));
828 ///////////////////////////////////////////
829 // bp_prev_sibling(bp *b,int s)
830 // returns the previous sibling of parent(s)
831 // -1 if s is the first child
832 //////////////////////////////////////////
833 int bp_prev_sibling(bp *b, int s)
836 if (s == 0) return -1;
837 if (bp_inspect(b,s-1) == OP) return -1;
838 t = bp_find_open(b,s-1);
842 ///////////////////////////////////////////
843 // bp_deepest_node(bp *b,int s)
844 // returns the first node with the largest depth in the subtree of s
845 ///////////////////////////////////////////
846 int bp_deepest_node(bp *b,int s)
849 t = bp_find_close(b,s);
850 m = bp_rmq(b,s,t, OPT_MAX);
854 ///////////////////////////////////////////
855 // bp_subtree_height(bp *b,int s)
856 // returns the height of the subtree of s
858 ///////////////////////////////////////////
859 int bp_subtree_height(bp *b,int s)
862 t = bp_deepest_node(b,s);
863 return bp_depth(b,t) - bp_depth(b,s);
866 int bp_naive_degree(bp *b, int s)
870 t = bp_first_child(b,s);
873 t = bp_next_sibling(b,t);
878 ///////////////////////////////////////////
879 // bp_degree(bp *b, int s)
880 // returns the number of children of s
882 ///////////////////////////////////////////
883 int bp_degree(bp *b, int s)
885 if (b->opt & OPT_DEGREE) {
886 return bp_fast_degree(b,s,b->n,0);
888 return bp_naive_degree(b,s);
892 int bp_naive_child(bp *b, int s, int d)
895 t = bp_first_child(b,s);
896 for (i = 1; i < d; i++) {
898 t = bp_next_sibling(b,t);
903 ///////////////////////////////////////////
904 // bp_child(bp *b, int s, int d)
905 // returns the d-th child of s (1 <= d <= degree(s))
906 // -1 if no such node
907 ///////////////////////////////////////////
908 int bp_child(bp *b, int s, int d)
911 if (b->opt & OPT_DEGREE) {
912 //return find_open(b,fast_degree(b,s,b->n,d));
913 if (d==1) return bp_first_child(b,s);
914 r = bp_fast_degree(b,s,b->n,d-1)+1;
915 if (bp_inspect(b,r) == CP) return -1;
918 return bp_naive_child(b,s,d);
924 int bp_naive_child_rank(bp *b, int t)
930 t = bp_prev_sibling(b,t);
935 ///////////////////////////////////////////
936 // bp_child_rank(bp *b, int t)
937 // returns d if t is the d-th child of the parent of t (d >= 1)
938 // 1 if t is the root
939 ///////////////////////////////////////////
940 int bp_child_rank(bp *b, int t)
943 if (t == bp_root_node(b)) return 1;
944 if (b->opt & OPT_DEGREE) {
946 return bp_fast_degree(b,r,t,0)+1;
948 return bp_naive_child_rank(b,t);
953 ///////////////////////////////////////////
954 // distance(bp *b, int s, int t)
955 // returns the length of the shortest path from s to t in the tree
956 ///////////////////////////////////////////
957 int bp_distance(bp *b, int s, int t)
962 return (bp_depth(b,s) - d) + (bp_depth(b,t) - d);
965 ///////////////////////////////////////////
966 // level_next(bp *b, int d)
967 ///////////////////////////////////////////
968 int bp_level_next(bp *b,int s)
971 t = bp_fwd_excess(b,s,0);
975 ///////////////////////////////////////////
976 // level_prev(bp *b, int d)
977 ///////////////////////////////////////////
978 int bp_level_prev(bp *b,int s)
981 t = bp_bwd_excess(b,s,0);
985 ///////////////////////////////////////////
986 // bp_level_leftmost(bp *b, int d)
987 ///////////////////////////////////////////
988 int bp_level_leftmost(bp *b, int d)
991 if (d < 1) return -1;
992 if (d == 1) return 0;
993 t = bp_fwd_excess(b,0,d);
997 ///////////////////////////////////////////
998 // bp_level_rigthmost(bp *b, int d)
999 ///////////////////////////////////////////
1000 int level_rigthmost(bp *b, int d)
1003 if (d < 1) return -1;
1004 if (d == 1) return 0;
1005 t = bp_bwd_excess(b,0,d-1);
1006 return bp_find_open(b,t);
1009 ///////////////////////////////////////////
1010 // leaf_size(bp *b, int s)
1011 ///////////////////////////////////////////
1012 int bp_leaf_size(bp *b, int s)
1015 if ((b->opt & OPT_LEAF) == 0) {
1016 printf("leaf_size: error!!! not supported\n");
1019 t = bp_find_close(b,s);
1020 return bp_leaf_rank(b,t) - bp_leaf_rank(b,s);