Branch Coverage

TreeRBXS.xs
Criterion Covered Total %
branch 473 876 54.0


line true false branch
39 27 8 if (SvIOK(type_sv)) {
40 27 0 key_type= SvIV(type_sv);
41 27 0 if (key_type < 1 || key_type > KEY_TYPE_MAX)
0 27 if (key_type < 1 || key_type > KEY_TYPE_MAX)
44 8 0 else if (SvPOK(type_sv)) {
45 8 0 str= SvPV(type_sv, len);
46 2 6 if (len > 9 && foldEQ(str, "KEY_TYPE_", 9)) {
2 0 if (len > 9 && foldEQ(str, "KEY_TYPE_", 9)) {
50 7 0 key_type= (len == 3 && foldEQ(str, "ANY", 3))? KEY_TYPE_ANY
51 7 1 : (len == 5 && foldEQ(str, "CLAIM", 5))? KEY_TYPE_CLAIM
0 0 : (len == 5 && foldEQ(str, "CLAIM", 5))? KEY_TYPE_CLAIM
52 0 8 : (len == 3 && foldEQ(str, "INT", 3))? KEY_TYPE_INT
0 7 : (len == 3 && foldEQ(str, "INT", 3))? KEY_TYPE_INT
53 7 1 : (len == 5 && foldEQ(str, "FLOAT", 5))? KEY_TYPE_FLOAT
0 0 : (len == 5 && foldEQ(str, "FLOAT", 5))? KEY_TYPE_FLOAT
54 0 1 : (len == 4 && foldEQ(str, "BSTR", 4))? KEY_TYPE_BSTR
0 1 : (len == 4 && foldEQ(str, "BSTR", 4))? KEY_TYPE_BSTR
55 1 0 : (len == 4 && foldEQ(str, "USTR", 4))? KEY_TYPE_USTR
0 0 : (len == 4 && foldEQ(str, "USTR", 4))? KEY_TYPE_USTR
56 0 0 : -1;
95 4 3 if (SvROK(cmp_sv) && SvTYPE(SvRV(cmp_sv)) == SVt_PVCV)
4 0 if (SvROK(cmp_sv) && SvTYPE(SvRV(cmp_sv)) == SVt_PVCV)
97 2 1 else if (SvIOK(cmp_sv)) {
98 2 0 cmp_id= SvIV(cmp_sv);
99 2 0 if (cmp_id < 1 || cmp_id > CMP_MAX || cmp_id == CMP_SUB)
2 0 if (cmp_id < 1 || cmp_id > CMP_MAX || cmp_id == CMP_SUB)
0 2 if (cmp_id < 1 || cmp_id > CMP_MAX || cmp_id == CMP_SUB)
102 1 0 else if (SvPOK(cmp_sv)) {
103 1 0 str= SvPV(cmp_sv, len);
104 1 0 if (len > 4 && foldEQ(str, "CMP_", 4)) {
0 1 if (len > 4 && foldEQ(str, "CMP_", 4)) {
108 0 0 cmp_id= (len == 4 && foldEQ(str, "PERL", 4))? CMP_PERL
109 0 1 : (len == 3 && foldEQ(str, "INT", 3))? CMP_INT
0 0 : (len == 3 && foldEQ(str, "INT", 3))? CMP_INT
110 0 1 : (len == 5 && foldEQ(str, "FLOAT", 5))? CMP_FLOAT
0 0 : (len == 5 && foldEQ(str, "FLOAT", 5))? CMP_FLOAT
111 0 1 : (len == 6 && foldEQ(str, "MEMCMP", 6))? CMP_MEMCMP
0 0 : (len == 6 && foldEQ(str, "MEMCMP", 6))? CMP_MEMCMP
112 0 1 : (len == 4 && foldEQ(str, "UTF8", 4))? CMP_UTF8
0 0 : (len == 4 && foldEQ(str, "UTF8", 4))? CMP_UTF8
113 0 1 : (len == 8 && foldEQ(str, "NUMSPLIT", 8))? CMP_NUMSPLIT
1 0 : (len == 8 && foldEQ(str, "NUMSPLIT", 8))? CMP_NUMSPLIT
115 1 0 : -1;
149 34 0 if (SvIOK(mode_sv)) {
150 34 0 mode= SvIV(mode_sv);
151 34 0 if (mode < 0 || mode > GET_MAX)
0 34 if (mode < 0 || mode > GET_MAX)
153 0 0 } else if (SvPOK(mode_sv)) {
154 0 0 mode_str= SvPV(mode_sv, len);
155 0 0 if (len > 4 && foldEQ(mode_str, "GET_", 4)) {
0 0 if (len > 4 && foldEQ(mode_str, "GET_", 4)) {
161 0 0 case '<': mode= len == 1? GET_LT : len == 2 && mode_str[1] == '='? GET_LE : -1; break;
0 0 case '<': mode= len == 1? GET_LT : len == 2 && mode_str[1] == '='? GET_LE : -1; break;
0 0 case '<': mode= len == 1? GET_LT : len == 2 && mode_str[1] == '='? GET_LE : -1; break;
162 0 0 case '>': mode= len == 1? GET_GT : len == 2 && mode_str[1] == '='? GET_GE : -1; break;
0 0 case '>': mode= len == 1? GET_GT : len == 2 && mode_str[1] == '='? GET_GE : -1; break;
0 0 case '>': mode= len == 1? GET_GT : len == 2 && mode_str[1] == '='? GET_GE : -1; break;
163 0 0 case '=': mode= len == 2 && mode_str[1] == '='? GET_EQ : -1; break;
0 0 case '=': mode= len == 2 && mode_str[1] == '='? GET_EQ : -1; break;
164 0 0 case '-': mode= len == 2 && mode_str[1] == '-'? GET_PREV : -1; break;
0 0 case '-': mode= len == 2 && mode_str[1] == '-'? GET_PREV : -1; break;
165 0 0 case '+': mode= len == 2 && mode_str[1] == '+'? GET_NEXT : -1; break;
0 0 case '+': mode= len == 2 && mode_str[1] == '+'? GET_NEXT : -1; break;
167 0 0 mode= len == 2 && (mode_str[1] == 'q' || mode_str[1] == 'Q')? GET_EQ
0 0 mode= len == 2 && (mode_str[1] == 'q' || mode_str[1] == 'Q')? GET_EQ
168 0 0 : len == 7 && foldEQ(mode_str, "EQ_LAST", 7)? GET_EQ_LAST
0 0 : len == 7 && foldEQ(mode_str, "EQ_LAST", 7)? GET_EQ_LAST
169 0 0 : -1;
172 0 0 mode= len == 2 && (mode_str[1] == 't' || mode_str[1] == 'T')? GET_GT
0 0 mode= len == 2 && (mode_str[1] == 't' || mode_str[1] == 'T')? GET_GT
173 0 0 : len == 2 && (mode_str[1] == 'e' || mode_str[1] == 'E')? GET_GE
0 0 : len == 2 && (mode_str[1] == 'e' || mode_str[1] == 'E')? GET_GE
0 0 : len == 2 && (mode_str[1] == 'e' || mode_str[1] == 'E')? GET_GE
174 0 0 : -1;
177 0 0 mode= len == 2 && (mode_str[1] == 't' || mode_str[1] == 'T')? GET_LT
0 0 mode= len == 2 && (mode_str[1] == 't' || mode_str[1] == 'T')? GET_LT
178 0 0 : len == 2 && (mode_str[1] == 'e' || mode_str[1] == 'E')? GET_LE
0 0 : len == 2 && (mode_str[1] == 'e' || mode_str[1] == 'E')? GET_LE
0 0 : len == 2 && (mode_str[1] == 'e' || mode_str[1] == 'E')? GET_LE
179 0 0 : len == 7 && foldEQ(mode_str, "LE_LAST", 7)? GET_LE_LAST
0 0 : len == 7 && foldEQ(mode_str, "LE_LAST", 7)? GET_LE_LAST
180 0 0 : -1;
182 0 0 case 'P': case 'p': mode= foldEQ(mode_str, "PREV", 4)? GET_PREV : -1; break;
183 0 0 case 'N': case 'n': mode= foldEQ(mode_str, "NEXT", 4)? GET_NEXT : -1; break;
191 234 0 SvUPGRADE(name, SVt_PVNV);
279 0 15 if (!tree) croak("tree is NULL");
280 0 15 if (!tree->owner) croak("no owner");
281 15 0 if (tree->key_type < 0 || tree->key_type > KEY_TYPE_MAX) croak("bad key_type");
0 15 if (tree->key_type < 0 || tree->key_type > KEY_TYPE_MAX) croak("bad key_type");
282 0 15 if (!tree->compare) croak("no compare function");
283 0 15 if ((err= rbtree_check_structure(&tree->root_sentinel, (int(*)(void*,void*,void*)) tree->compare, tree, -OFS_TreeRBXS_item_FIELD_rbnode)))
285 15 0 if (TreeRBXS_get_count(tree)) {
287 470008 15 while (node) {
289 0 470008 if (item->key_type != tree->key_type)
291 0 470008 if (!item->value)
293 0 470008 if (item->iter) {
295 0 0 while (iter) {
296 0 0 if (!iter->owner) croak("Iterator lacks owner reference");
297 0 0 if (iter->item != item) croak("Iterator referenced by wrong item");
309 1 27 if (!tree->hashiter) {
333 110168 0 case KEY_TYPE_INT: item->keyunion.ikey= SvIV(key); break;
334 100054 10001 case KEY_TYPE_FLOAT: item->keyunion.nkey= SvNV(key); break;
339 0 10023 item->keyunion.ckey= SvPVutf8(key, len);
342 100078 10001 item->keyunion.ckey= SvPVbyte(key, len);
344 0 120102 if (len > CKEYLEN_MAX)
363 460189 10023 if (src->key_type == KEY_TYPE_USTR || src->key_type == KEY_TYPE_BSTR) {
110026 350163 if (src->key_type == KEY_TYPE_USTR || src->key_type == KEY_TYPE_BSTR) {
393 21 2 return node? GET_TreeRBXS_FROM_root_sentinel(node) : NULL;
398 130084 340128 switch (item->key_type) {
402 470212 0 if (item->value)
417 10 80 if (!rbtree_node_is_in_tree(&item->rbnode))
425 15330 0 for (cur= &item->iter; *cur; cur= &((*cur)->next_iter)) {
426 1499 13831 if (*cur == iter) {
439 2 4 : rbtree_node_left_leaf(TreeRBXS_get_root(iter->tree));
440 6 0 TreeRBXS_iter_set_item(iter, node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL);
446 19 1724 if (iter->item == item)
449 1484 240 if (iter->item)
452 1533 191 if (item) {
464 0 1520 if (!iter->tree)
467 761 759 if (ofs == 1) {
468 746 15 if (iter->item) {
470 365 381 node= iter->reverse? rbtree_node_prev(node) : rbtree_node_next(node);
471 680 66 TreeRBXS_iter_set_item(iter, node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL);
484 737 22 : !iter->reverse? rbtree_node_index(&iter->item->rbnode)
486 371 366 : cnt - 1 - rbtree_node_index(&iter->item->rbnode);
487 754 5 if (ofs > 0) {
488 612 142 newpos= (UV)ofs < (cnt-pos)? pos + ofs : cnt;
491 5 0 newpos= (pos < ofs)? 0 : pos - ofs;
494 378 381 if (iter->reverse) newpos= cnt - 1 - newpos;
496 617 142 TreeRBXS_iter_set_item(iter, node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL);
509 76 12 for (iter= item->iter; iter; iter= next) {
512 30 46 if (iter->reverse) {
513 20 10 if (!prev_item) {
515 3 17 if (node)
531 25 21 if (!next_item) {
533 8 17 if (node)
553 26 470186 if (rbtree_node_is_in_tree(&item->rbnode)) {
555 12 14 if (item->iter)
562 470202 10 if (!item->owner)
567 15 215 if (iter->item)
569 230 0 if (iter->tree) {
570 1 229 if (iter->tree->hashiter == iter)
581 4 41 if (tree->compare_callback)
583 1 44 if (tree->hashiter)
593 241 9 if (rbtree_find_all(
628 245 5 return node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
644 3149640 55429 return diff < 0? -1 : diff > 0? 1 : 0; /* shrink from IV to int might lose upper bits */
650 55378 3149282 return diff < 0? -1 : diff > 0? 1 : 0;
658 122752 2933187 return cmp? cmp : alen < blen? -1 : alen > blen? 1 : 0;
119199 3553 return cmp? cmp : alen < blen? -1 : alen > blen? 1 : 0;
692 78 0 apos= SvPV(a->keyunion.svkey, alen);
693 78 0 bpos= SvPV(b->keyunion.svkey, blen);
702 285 0 while (apos < alim && bpos < blim) {
273 12 while (apos < alim && bpos < blim) {
704 372 3 while (apos < alim && bpos < blim && *apos == *bpos && !isdigit(*apos))
372 0 while (apos < alim && bpos < blim && *apos == *bpos && !isdigit(*apos))
192 180 while (apos < alim && bpos < blim && *apos == *bpos && !isdigit(*apos))
102 90 while (apos < alim && bpos < blim && *apos == *bpos && !isdigit(*apos))
708 558 9 while (apos < alim && !isdigit(*apos)) apos++;
294 264 while (apos < alim && !isdigit(*apos)) apos++;
710 408 9 while (bpos < blim && !isdigit(*bpos)) bpos++;
144 264 while (bpos < blim && !isdigit(*bpos)) bpos++;
714 207 66 if (alen || blen) {
12 195 if (alen || blen) {
717 12 66 if (alen == 0) { DEBUG_NUMSPLIT("a EOF or digit, b has chars, -1"); return -1; }
718 42 24 if (blen == 0) { DEBUG_NUMSPLIT("b EOF or digit, a has chars, 1"); return 1; }
721 0 24 if (a_utf8 != b_utf8) {
723 0 0 : bytes_cmp_utf8(amark, alen, bmark, blen);
724 0 0 if (cmp) { DEBUG_NUMSPLIT("bytes_cmp_utf8('%.*s','%.*s')= %d", (int)alen, amark, (int)blen, bmark, cmp); return cmp; }
729 24 0 if (cmp) { DEBUG_NUMSPLIT("memcmp('%.*s','%.*s') = %d", (int)alen, amark, (int)blen, bmark, cmp); return cmp; }
730 0 0 if (alen < blen) { DEBUG_NUMSPLIT("alen < blen = -1"); return -1; }
731 0 0 if (alen > blen) { DEBUG_NUMSPLIT("alen > blen = 1"); return -1; }
735 192 3 if (!(apos < alim && bpos < blim)) break;
192 0 if (!(apos < alim && bpos < blim)) break;
738 567 0 while (apos < alim && *apos == '0') apos++;
375 192 while (apos < alim && *apos == '0') apos++;
739 195 0 while (bpos < blim && *bpos == '0') bpos++;
3 192 while (bpos < blim && *bpos == '0') bpos++;
743 354 0 while (apos < alim && bpos < blim && *apos == *bpos && isdigit(*apos))
339 15 while (apos < alim && bpos < blim && *apos == *bpos && isdigit(*apos))
201 138 while (apos < alim && bpos < blim && *apos == *bpos && isdigit(*apos))
162 39 while (apos < alim && bpos < blim && *apos == *bpos && isdigit(*apos))
747 192 0 if ((apos < alim && isdigit(*apos)) || (bpos < blim && isdigit(*bpos))) {
60 132 if ((apos < alim && isdigit(*apos)) || (bpos < blim && isdigit(*bpos))) {
48 12 if ((apos < alim && isdigit(*apos)) || (bpos < blim && isdigit(*bpos))) {
9 39 if ((apos < alim && isdigit(*apos)) || (bpos < blim && isdigit(*bpos))) {
748 0 141 if (apos == alim) { DEBUG_NUMSPLIT("b has more digits = -1"); return -1; }
749 3 138 if (bpos == blim) { DEBUG_NUMSPLIT("a has more digits = 1"); return 1; }
753 336 6 while (apos < alim && isdigit(*apos)) apos++;
204 132 while (apos < alim && isdigit(*apos)) apos++;
754 279 45 while (bpos < blim && isdigit(*bpos)) bpos++;
186 93 while (bpos < blim && isdigit(*bpos)) bpos++;
758 42 96 if (alen < blen) { DEBUG_NUMSPLIT("b numerically greater = -1"); return -1; }
759 45 51 if (alen > blen) { DEBUG_NUMSPLIT("a numerically greater = 1"); return 1; }
767 0 15 if (bpos < blim) { DEBUG_NUMSPLIT("b is longer '%.*s' = -1", (int)(blim-bpos), bpos); return -1; }
768 12 3 if (apos < alim) { DEBUG_NUMSPLIT("a is longer '%.*s' = 1", (int)(alim-apos), apos); return 1; }
785 0 3204664 PUSHMARK(SP);
786 0 3204664 EXTEND(SP, 2);
790 0 3204664 if (call_sv(tree->compare_callback, G_SCALAR) != 1)
793 3204664 0 ret= POPi;
808 45 0 if (mg->mg_ptr) {
840 90 0 if (mg->mg_ptr) {
863 229 0 if (mg->mg_ptr)
889 0 470896 if (!sv_isobject(obj)) {
890 0 0 if (flags & OR_DIE)
895 470851 45 if (SvMAGICAL(sv)) {
897 470851 0 for (magic= SvMAGIC(sv); magic; magic = magic->mg_moremagic)
898 470851 0 if (magic->mg_type == PERL_MAGIC_ext && magic->mg_virtual == &TreeRBXS_magic_vt)
470851 0 if (magic->mg_type == PERL_MAGIC_ext && magic->mg_virtual == &TreeRBXS_magic_vt)
902 45 0 if (flags & AUTOCREATE) {
912 0 0 else if (flags & OR_DIE)
923 19 390 if (!sv_isobject(obj)) {
924 0 19 if (flags & OR_DIE)
929 390 0 if (SvMAGICAL(sv)) {
931 390 214 for (magic= SvMAGIC(sv); magic; magic = magic->mg_moremagic)
932 390 0 if (magic->mg_type == PERL_MAGIC_ext && magic->mg_virtual == &TreeRBXS_item_magic_vt)
176 214 if (magic->mg_type == PERL_MAGIC_ext && magic->mg_virtual == &TreeRBXS_item_magic_vt)
936 0 214 if (flags & OR_DIE)
948 30 98 if (!item)
951 8 90 if (item->owner)
967 7 106 if (!item)
1015 0 2044 if (!sv_isobject(obj)) {
1016 0 0 if (flags & OR_DIE)
1021 2044 0 if (SvMAGICAL(sv)) {
1023 2044 458 for (magic= SvMAGIC(sv); magic; magic = magic->mg_moremagic)
1024 1815 229 if (magic->mg_type == PERL_MAGIC_ext && magic->mg_virtual == &TreeRBXS_iter_magic_vt)
1586 229 if (magic->mg_type == PERL_MAGIC_ext && magic->mg_virtual == &TreeRBXS_iter_magic_vt)
1028 229 229 if (flags & AUTOCREATE) {
1037 0 229 else if (flags & OR_DIE)
1059 45 0 if (!sv_isobject(obj) || SvTYPE(SvRV(obj)) != SVt_PVHV)
0 45 if (!sv_isobject(obj) || SvTYPE(SvRV(obj)) != SVt_PVHV)
1063 10 35 key_type= SvOK(key_type_sv)? parse_key_type(key_type_sv) : 0;
10 0 key_type= SvOK(key_type_sv)? parse_key_type(key_type_sv) : 0;
0 10 key_type= SvOK(key_type_sv)? parse_key_type(key_type_sv) : 0;
1064 0 45 if (key_type < 0)
1065 0 0 croak("invalid key_type %s", SvPV_nolen(key_type_sv));
1067 38 7 if (SvOK(compare_fn)) {
38 0 if (SvOK(compare_fn)) {
0 38 if (SvOK(compare_fn)) {
1069 0 7 if (cmp_id < 0)
1070 0 0 croak("invalid compare_fn %s", SvPV_nolen(compare_fn));
1073 25 13 : key_type == KEY_TYPE_FLOAT? CMP_FLOAT
1074 20 5 : key_type == KEY_TYPE_BSTR? CMP_MEMCMP
1075 14 6 : key_type == KEY_TYPE_USTR? CMP_UTF8
1076 3 11 : key_type == KEY_TYPE_ANY? CMP_PERL /* use Perl's cmp operator */
1081 0 45 if (tree->owner != SvRV(obj))
1090 0 4 tree->key_type= key_type == KEY_TYPE_CLAIM? key_type : KEY_TYPE_ANY;
1098 1 10 tree->key_type= key_type == KEY_TYPE_CLAIM? key_type : KEY_TYPE_ANY;
1114 1 1 tree->key_type= key_type == KEY_TYPE_BSTR || key_type == KEY_TYPE_USTR
1115 2 1 || key_type == KEY_TYPE_ANY || key_type == KEY_TYPE_CLAIM? key_type : KEY_TYPE_BSTR;
0 1 || key_type == KEY_TYPE_ANY || key_type == KEY_TYPE_CLAIM? key_type : KEY_TYPE_BSTR;
0 0 || key_type == KEY_TYPE_ANY || key_type == KEY_TYPE_CLAIM? key_type : KEY_TYPE_BSTR;
1145 1 8 : sv_2mortal(new_enum_dualvar(id, newSVpv(get_cmp_name(id), 0)));
1153 5 6 if (items > 1) {
1154 5 0 tree->allow_duplicates= SvTRUE(allow);
0 5 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 5 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 5 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
5 0 tree->allow_duplicates= SvTRUE(allow);
5 0 tree->allow_duplicates= SvTRUE(allow);
0 5 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
5 0 tree->allow_duplicates= SvTRUE(allow);
0 0 tree->allow_duplicates= SvTRUE(allow);
1166 0 0 if (items > 1) {
1167 0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
0 0 tree->compat_list_get= SvTRUE(allow);
1193 0 70094 if (!SvOK(key))
0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
1198 70000 94 if (!tree->allow_duplicates) {
1206 69993 101 if (hint && cmp == 0) {
0 69993 if (hint && cmp == 0) {
1210 101 69993 if (!rbtree_node_insert(
0 70094 if (!rbtree_node_insert(
1235 0 400129 if (!SvOK(key))
0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
1239 11 400118 if (rbtree_find_all(
1248 0 11 while (last != first) {
1262 29 400089 if (!rbtree_node_insert(
0 400118 if (!rbtree_node_insert(
1263 26 3 first? first : last? last : &tree->root_sentinel,
1283 0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
1293 0 0 ST(0)= (node && cmp == 0)? &PL_sv_yes : &PL_sv_no;
0 0 ST(0)= (node && cmp == 0)? &PL_sv_yes : &PL_sv_no;
1316 0 250 if (!SvOK(key))
0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
1321 0 202 if (tree->compat_list_get) {
1324 21 0 case 0: if (GIMME_V == G_SCALAR) ix= 1;
21 0 case 0: if (GIMME_V == G_SCALAR) ix= 1;
1327 34 203 mode= mode_sv? parse_lookup_mode(mode_sv) : GET_EQ;
1328 0 237 if (mode < 0)
1329 0 0 croak("Invalid lookup mode %s", SvPV_nolen(mode_sv));
1337 0 0 if (mode_sv) croak("extra get-mode argument");
1345 245 5 if (item) {
1346 0 245 if (ix == 0) { // lookup in list context
1350 231 14 } else if (ix == 1) { // get, or lookup in scalar context
1358 0 5 if (ix == 0) { // lookup in list context
1376 0 1 if (!SvOK(key))
0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
1379 1 0 if (rbtree_find_all(
1386 0 1 EXTEND(SP, count);
1387 6 1 for (i= 0; i < count; i++) {
1406 0 15 if (!SvOK(key1))
0 0 if (!SvOK(key1))
0 0 if (!SvOK(key1))
1409 0 15 if ((item= TreeRBXS_get_magic_item(key1, 0))) {
1412 0 0 for (node= first; rbtree_node_is_in_tree(node) && node->parent; node= node->parent);
0 0 for (node= first; rbtree_node_is_in_tree(node) && node->parent; node= node->parent);
1413 0 0 if (node != &tree->root_sentinel)
1418 12 3 if (rbtree_find_all(
1425 1 11 if (key2)
1431 2 1 if (key2) {
1439 3 12 if (key2 && first) {
3 0 if (key2 && first) {
1440 0 3 if ((item= TreeRBXS_get_magic_item(key2, 0))) {
1443 0 0 for (node= last; rbtree_node_is_in_tree(node) && node->parent; node= node->parent);
0 0 for (node= last; rbtree_node_is_in_tree(node) && node->parent; node= node->parent);
1444 0 0 if (node != &tree->root_sentinel)
1449 2 1 if (rbtree_find_all(
1463 3 0 if (last && rbtree_node_index(first) > rbtree_node_index(last))
1 2 if (last && rbtree_node_index(first) > rbtree_node_index(last))
1468 15 0 if (first && last) {
13 2 if (first && last) {
1471 3 13 first= (first == last)? NULL : rbtree_node_next(first);
1474 3 13 } while (first);
1496 17 0 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1506 3 0 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1517 1 6 if (ofs < 0) ofs += TreeRBXS_get_count(tree);
1519 6 1 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1528 4 0 : GET_TreeRBXS_item_FROM_rbnode(TreeRBXS_get_root(tree));
1539 1 5 if (tree->hashiterset)
1554 2 17 if (tree->hashiterset)
1572 2 1 if (item && (TreeRBXS_item_get_tree(item) != tree))
0 2 if (item && (TreeRBXS_item_get_tree(item) != tree))
1576 1 2 if (!item) TreeRBXS_iter_rewind(iter);
1596 0 1 if (!SvOK(key))
0 0 if (!SvOK(key))
0 0 if (!SvOK(key))
1599 1 0 if (rbtree_find_all(
1609 0 1 first= (first == last)? NULL : rbtree_node_next(first);
1611 0 1 } while (first);
1636 0 19 if (newval)
1656 1 3 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1666 39 12 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1674 0 1 RETVAL= rbtree_node_is_in_tree(&item->rbnode) && item->rbnode.parent->count?
1675 1 1 GET_TreeRBXS_item_FROM_rbnode(item->rbnode.parent) : NULL;
1685 0 1 ST(0)= tree && tree->owner? sv_2mortal(newRV_inc(tree->owner)) : &PL_sv_undef;
0 0 ST(0)= tree && tree->owner? sv_2mortal(newRV_inc(tree->owner)) : &PL_sv_undef;
1692 2 4 RETVAL= rbtree_node_is_in_tree(&item->rbnode) && item->rbnode.left->count?
1693 6 1 GET_TreeRBXS_item_FROM_rbnode(item->rbnode.left) : NULL;
1701 2 4 RETVAL= rbtree_node_is_in_tree(&item->rbnode) && item->rbnode.right->count?
1702 6 1 GET_TreeRBXS_item_FROM_rbnode(item->rbnode.right) : NULL;
1712 1 1 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1722 1 1 RETVAL= node? GET_TreeRBXS_item_FROM_rbnode(node) : NULL;
1749 4 1 if (tree) {
1773 229 0 if (iter->item || iter->tree)
0 229 if (iter->item || iter->tree)
1775 108 121 if (!(direction == 1 || direction == -1))
0 108 if (!(direction == 1 || direction == -1))
1780 0 229 if ((iter2= TreeRBXS_get_magic_iter(target, 0))) {
1782 0 0 if (items < 2) iter->reverse= iter2->reverse;
1786 15 214 else if ((item= TreeRBXS_get_magic_item(target, 0))) {
1789 214 0 else if ((tree= TreeRBXS_get_magic_tree(target, 0))) {
1791 214 0 : iter->reverse? rbtree_node_right_leaf(TreeRBXS_get_root(tree))
1792 102 112 : rbtree_node_left_leaf(TreeRBXS_get_root(tree));
1793 214 0 if (node)
1796 0 229 if (!tree)
1799 229 0 if (tree->owner)
1818 23 2 RETVAL= iter->item? SvREFCNT_inc_simple_NN(iter->item->value) : &PL_sv_undef;
1826 0 0 RETVAL= !iter->item || !rbtree_node_is_in_tree(&iter->item->rbnode)? &PL_sv_undef
1827 0 1 : newSViv(rbtree_node_index(&iter->item->rbnode));
1835 0 0 RETVAL= iter->tree && iter->tree->owner? newRV_inc(iter->tree->owner) : &PL_sv_undef;
0 0 RETVAL= iter->tree && iter->tree->owner? newRV_inc(iter->tree->owner) : &PL_sv_undef;
1860 4 15 rbtree_node_t *(*step)(rbtree_node_t *)= iter->reverse? &rbtree_node_prev : rbtree_node_next;
1862 19 0 if (iter->item) {
1863 13 6 request= !count_sv? 1
6 7 request= !count_sv? 1
7 0 request= !count_sv? 1
1864 6 0 : SvPOK(count_sv) && *SvPV_nolen(count_sv) == '*'? tree_count
0 6 : SvPOK(count_sv) && *SvPV_nolen(count_sv) == '*'? tree_count
1866 1 18 if (request < 1) {
1871 18 0 else if (GIMME_V == G_VOID) {
0 18 else if (GIMME_V == G_VOID) {
1877 7 11 else if (request == 1) {
1880 6 1 : ix == 2? iter->item->value
1881 0 1 : sv_2mortal(TreeRBXS_item_wrap_key(iter->item));
1882 0 7 if (ix == 3) {
1883 0 0 EXTEND(SP, 2);
1890 1 10 n= iter->reverse? 1 + pos : tree_count - pos;
1891 3 8 if (n > request) n= request;
1893 1 10 nret= ix == 3? 2*n : n;
1894 0 11 EXTEND(SP, nret); // EXTEND macro declares a temp 'ix' internally - GitHub #2
1895 1 10 if (ix == 0) { // Return N node references
1896 2 1 for (i= 0; i < n && node; i++, node= step(node))
2 0 for (i= 0; i < n && node; i++, node= step(node))
1899 4 6 else if (ix == 1) { // Return N keys
1900 16 4 for (i= 0; i < n && node; i++, node= step(node))
16 0 for (i= 0; i < n && node; i++, node= step(node))
1903 5 1 else if (ix == 2) { // Return N values
1904 91 5 for (i= 0; i < n && node; i++, node= step(node))
91 0 for (i= 0; i < n && node; i++, node= step(node))
1908 2 1 for (i= 0; i < n && node; i++, node= step(node)) {
2 0 for (i= 0; i < n && node; i++, node= step(node)) {
1913 0 11 if (i != n)
1917 1 18 XSRETURN(ix == 3? 2*i : i);
1940 5 0 if (iter->item) {