Branch Coverage

Shared.xs
Criterion Covered Total %
branch 280 446 62.7


line true false branch
38 0 78 if ((items - first) % 2 != 0) croak("range options must be key => value pairs");
39 15 78 for (int ai = first; ai + 1 < items; ai += 2) {
41 5 10 if (!strcmp(k, "withscores")) *ws = SvTRUE(sp[ai+1]);
42 10 0 else if (limit && !strcmp(k, "limit")) *limit = SvIV(sp[ai+1]);
5 5 else if (limit && !strcmp(k, "limit")) *limit = SvIV(sp[ai+1]);
43 5 0 else if (offset && !strcmp(k, "offset")) *offset = SvIV(sp[ai+1]);
5 0 else if (offset && !strcmp(k, "offset")) *offset = SvIV(sp[ai+1]);
52 1 13 if (*a < 0) *a += (IV)cnt;
53 6 8 if (*b < 0) *b += (IV)cnt;
54 0 14 if (*a < 0) *a = 0;
55 1 13 if (*b >= (IV)cnt) *b = (IV)cnt - 1;
56 13 1 return cnt > 0 && *a <= *b;
12 1 return cnt > 0 && *a <= *b;
71 10 25 const char *p = SvOK(path) ? SvPV_nolen(path) : NULL;
72 0 35 if (max_entries > UINT32_MAX) croak("Data::SortedSet::Shared->new: max_entries exceeds 2^32");
74 2 33 if (!h) croak("Data::SortedSet::Shared->new: %s", errbuf);
87 0 1 if (max_entries > UINT32_MAX) croak("Data::SortedSet::Shared->new_memfd: max_entries exceeds 2^32");
89 0 1 if (!h) croak("Data::SortedSet::Shared->new_memfd: %s", errbuf);
102 0 1 if (!h) croak("Data::SortedSet::Shared->new_from_fd: %s", errbuf);
111 36 0 if (sv_isobject(self) && sv_derived_from(self, "Data::SortedSet::Shared")) {
36 0 if (sv_isobject(self) && sv_derived_from(self, "Data::SortedSet::Shared")) {
113 35 1 if (h) { sv_setiv(SvRV(self), 0); ss_destroy(h); } /* null first: activates EXTRACT's use-after-destroy croak + makes a double DESTROY a no-op */
120 25 0 EXTRACT(self);
0 25 EXTRACT(self);
1 24 EXTRACT(self);
132 3 0 EXTRACT(self);
0 3 EXTRACT(self);
0 3 EXTRACT(self);
134 0 3 RETVAL = h->hdr->max_entries;
142 3 0 EXTRACT(self);
0 3 EXTRACT(self);
0 3 EXTRACT(self);
154 94352 0 EXTRACT(self);
0 94352 EXTRACT(self);
0 94352 EXTRACT(self);
157 1 94351 if (score != score) croak("add: score must not be NaN");
162 94349 2 RETVAL = (rc < 0) ? &PL_sv_undef : newSViv(rc);
171 65720 0 EXTRACT(self);
0 65720 EXTRACT(self);
0 65720 EXTRACT(self);
177 65719 1 RETVAL = found ? newSVnv(sc) : &PL_sv_undef;
186 5 0 EXTRACT(self);
0 5 EXTRACT(self);
0 5 EXTRACT(self);
200 23436 0 EXTRACT(self);
0 23436 EXTRACT(self);
0 23436 EXTRACT(self);
215 16396 0 EXTRACT(self);
0 16396 EXTRACT(self);
0 16396 EXTRACT(self);
219 1 16395 if (delta != delta) croak("incr: delta must not be NaN");
224 0 16395 if (rc == -1) croak("incr: max_entries exhausted");
225 1 16394 if (rc == -2) croak("incr: result is NaN");
226 16388 6 RETVAL = out;
234 14950 0 EXTRACT(self);
0 14950 EXTRACT(self);
0 14950 EXTRACT(self);
240 14949 1 if (ok) __atomic_fetch_add(&h->hdr->stat_ops, 1, __ATOMIC_RELAXED);
242 14949 1 if (ok) { EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv((IV)m))); PUSHs(sv_2mortal(newSVnv(s))); }
0 14949 if (ok) { EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv((IV)m))); PUSHs(sv_2mortal(newSVnv(s))); }
249 8834 0 EXTRACT(self);
0 8834 EXTRACT(self);
0 8834 EXTRACT(self);
255 8833 1 if (ok) __atomic_fetch_add(&h->hdr->stat_ops, 1, __ATOMIC_RELAXED);
257 8833 1 if (ok) { EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv((IV)m))); PUSHs(sv_2mortal(newSVnv(s))); }
0 8833 if (ok) { EXTEND(SP, 2); PUSHs(sv_2mortal(newSViv((IV)m))); PUSHs(sv_2mortal(newSVnv(s))); }
264 105 0 EXTRACT(self);
0 105 EXTRACT(self);
0 105 EXTRACT(self);
277 9833 0 EXTRACT(self);
0 9833 EXTRACT(self);
0 9833 EXTRACT(self);
282 9831 2 ? newSVuv(ss_rank_of(h, sc, (int64_t)member)) : &PL_sv_undef;
292 302 0 EXTRACT(self);
0 302 EXTRACT(self);
0 302 EXTRACT(self);
297 302 0 ? newSVuv(h->hdr->count - 1 - ss_rank_of(h, sc, (int64_t)member)) : &PL_sv_undef;
307 308 0 EXTRACT(self);
0 308 EXTRACT(self);
0 308 EXTRACT(self);
312 2 306 IV r = rank; if (r < 0) r += (IV)cnt;
313 308 0 if (r >= 0 && (uint64_t)r < cnt) { /* compare in 64-bit; large r must not truncate to an in-range index */
304 4 if (r >= 0 && (uint64_t)r < cnt) { /* compare in 64-bit; large r must not truncate to an in-range index */
328 40 0 EXTRACT(self);
0 40 EXTRACT(self);
0 40 EXTRACT(self);
342 10 0 EXTRACT(self);
0 10 EXTRACT(self);
0 10 EXTRACT(self);
350 8 2 if (ss_rank_window(h->hdr->count, start, stop, &a, &b)) { s0 = (uint32_t)a; len = (uint32_t)(b - a + 1); }
351 0 10 EMIT_COLLECTED(s0, len, 0, ws);
3 7 EMIT_COLLECTED(s0, len, 0, ws);
10 0 EMIT_COLLECTED(s0, len, 0, ws);
3 7 EMIT_COLLECTED(s0, len, 0, ws);
0 10 EMIT_COLLECTED(s0, len, 0, ws);
0 0 EMIT_COLLECTED(s0, len, 0, ws);
8 22 EMIT_COLLECTED(s0, len, 0, ws);
30 10 EMIT_COLLECTED(s0, len, 0, ws);
360 4 0 EXTRACT(self);
0 4 EXTRACT(self);
0 4 EXTRACT(self);
368 4 0 if (ss_rank_window(cnt, start, stop, &a, &b)) { s0 = (uint32_t)((IV)cnt - 1 - b); len = (uint32_t)(b - a + 1); }
369 0 4 EMIT_COLLECTED(s0, len, 1, ws);
1 3 EMIT_COLLECTED(s0, len, 1, ws);
4 0 EMIT_COLLECTED(s0, len, 1, ws);
1 3 EMIT_COLLECTED(s0, len, 1, ws);
0 4 EMIT_COLLECTED(s0, len, 1, ws);
0 0 EMIT_COLLECTED(s0, len, 1, ws);
2 15 EMIT_COLLECTED(s0, len, 1, ws);
17 4 EMIT_COLLECTED(s0, len, 1, ws);
378 41 0 EXTRACT(self);
0 41 EXTRACT(self);
0 41 EXTRACT(self);
386 3 38 uint32_t off = (offset > 0) ? (offset >= (IV)win ? win : (uint32_t)offset) : 0;
2 1 uint32_t off = (offset > 0) ? (offset >= (IV)win ? win : (uint32_t)offset) : 0;
388 38 3 if (off < win) { s0 = lo + off; len = win - off; if (limit >= 0 && limit < (IV)len) len = (uint32_t)limit; }
4 34 if (off < win) { s0 = lo + off; len = win - off; if (limit >= 0 && limit < (IV)len) len = (uint32_t)limit; }
3 1 if (off < win) { s0 = lo + off; len = win - off; if (limit >= 0 && limit < (IV)len) len = (uint32_t)limit; }
389 0 41 EMIT_COLLECTED(s0, len, 0, ws);
1 40 EMIT_COLLECTED(s0, len, 0, ws);
41 0 EMIT_COLLECTED(s0, len, 0, ws);
1 40 EMIT_COLLECTED(s0, len, 0, ws);
0 41 EMIT_COLLECTED(s0, len, 0, ws);
0 0 EMIT_COLLECTED(s0, len, 0, ws);
2 42525 EMIT_COLLECTED(s0, len, 0, ws);
42527 41 EMIT_COLLECTED(s0, len, 0, ws);
398 23 0 EXTRACT(self);
0 23 EXTRACT(self);
0 23 EXTRACT(self);
406 2 21 uint32_t off = (offset > 0) ? (offset >= (IV)win ? win : (uint32_t)offset) : 0;
1 1 uint32_t off = (offset > 0) ? (offset >= (IV)win ? win : (uint32_t)offset) : 0;
408 22 1 if (off < win) { len = win - off; if (limit >= 0 && limit < (IV)len) len = (uint32_t)limit;
1 21 if (off < win) { len = win - off; if (limit >= 0 && limit < (IV)len) len = (uint32_t)limit;
1 0 if (off < win) { len = win - off; if (limit >= 0 && limit < (IV)len) len = (uint32_t)limit;
410 0 23 EMIT_COLLECTED(s0, len, 1, ws);
0 23 EMIT_COLLECTED(s0, len, 1, ws);
23 0 EMIT_COLLECTED(s0, len, 1, ws);
0 23 EMIT_COLLECTED(s0, len, 1, ws);
0 23 EMIT_COLLECTED(s0, len, 1, ws);
0 0 EMIT_COLLECTED(s0, len, 1, ws);
0 33330 EMIT_COLLECTED(s0, len, 1, ws);
33330 23 EMIT_COLLECTED(s0, len, 1, ws);
417 5 0 EXTRACT(self);
0 5 EXTRACT(self);
0 5 EXTRACT(self);
420 4 1 if (h->hdr->root != SS_NONE) {
424 0 4 EXTEND(SP, 2);
433 3 0 EXTRACT(self);
0 3 EXTRACT(self);
0 3 EXTRACT(self);
436 3 0 if (h->hdr->root != SS_NONE) {
440 0 3 EXTEND(SP, 2);
450 5 0 EXTRACT(self);
0 5 EXTRACT(self);
0 5 EXTRACT(self);
452 5 0 if (!SvROK(cb) || SvTYPE(SvRV(cb)) != SVt_PVCV) croak("each: callback must be a code ref");
0 5 if (!SvROK(cb) || SvTYPE(SvRV(cb)) != SVt_PVCV) croak("each: callback must be a code ref");
458 0 5 if (!ok) { free(col.members); free(col.scores); croak("each: out of memory"); }
459 9830 4 for (size_t i = 0; i < col.n; i++) {
460 0 9830 dSP; ENTER; SAVETMPS; PUSHMARK(SP);
461 0 9830 XPUSHs(sv_2mortal(newSViv((IV)col.members[i])));
462 0 9830 XPUSHs(sv_2mortal(newSVnv(col.scores[i])));
465 9830 0 FREETMPS; LEAVE;
466 9830 0 if (SvTRUE(ERRSV)) { free(col.members); free(col.scores); croak_sv(ERRSV); }
1 9829 if (SvTRUE(ERRSV)) { free(col.members); free(col.scores); croak_sv(ERRSV); }
1 0 if (SvTRUE(ERRSV)) { free(col.members); free(col.scores); croak_sv(ERRSV); }
475 2 0 EXTRACT(self);
0 2 EXTRACT(self);
0 2 EXTRACT(self);
477 1 1 RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
485 1 0 EXTRACT(self);
0 1 EXTRACT(self);
0 1 EXTRACT(self);
487 0 1 RETVAL = h->backing_fd;
495 5 0 EXTRACT(self);
0 5 EXTRACT(self);
0 5 EXTRACT(self);
497 0 5 if (ss_msync(h) != 0) croak("sync: %s", strerror(errno));
505 1 1 if (sv_isobject(self) && sv_derived_from(self, "Data::SortedSet::Shared")) {
1 0 if (sv_isobject(self) && sv_derived_from(self, "Data::SortedSet::Shared")) {
507 1 0 if (h) p = h->path;
508 1 0 } else if (items >= 2 && SvOK(ST(1))) {
1 0 } else if (items >= 2 && SvOK(ST(1))) {
511 2 0 if (p && unlink(p) != 0 && errno != ENOENT) croak("unlink: %s", strerror(errno));
0 2 if (p && unlink(p) != 0 && errno != ENOENT) croak("unlink: %s", strerror(errno));
0 0 if (p && unlink(p) != 0 && errno != ENOENT) croak("unlink: %s", strerror(errno));
518 1 0 EXTRACT(self);
0 1 EXTRACT(self);
0 1 EXTRACT(self);
521 0 1 if (RETVAL < 0) croak("eventfd: %s", strerror(errno));
529 2 0 EXTRACT(self);
0 2 EXTRACT(self);
0 2 EXTRACT(self);
531 0 2 RETVAL = h->notify_fd;
539 1 0 EXTRACT(self);
0 1 EXTRACT(self);
0 1 EXTRACT(self);
541 1 0 RETVAL = ss_notify(h);
549 1 0 EXTRACT(self);
0 1 EXTRACT(self);
0 1 EXTRACT(self);
553 1 0 RETVAL = (v < 0) ? &PL_sv_undef : newSVuv((UV)v);
563 6 0 EXTRACT(self);
0 6 EXTRACT(self);
0 6 EXTRACT(self);
564 6 0 int added = 0;
566 5 1 if (!SvROK(rows) || SvTYPE(SvRV(rows)) != SVt_PVAV)
0 5 if (!SvROK(rows) || SvTYPE(SvRV(rows)) != SVt_PVAV)
572 3017 4 for (SSize_t i = 0; i < nr; i++) {
574 3017 0 if (!rv || !SvROK(*rv) || SvTYPE(SvRV(*rv)) != SVt_PVAV) continue; /* skip malformed */
3016 1 if (!rv || !SvROK(*rv) || SvTYPE(SvRV(*rv)) != SVt_PVAV) continue; /* skip malformed */
0 3016 if (!rv || !SvROK(*rv) || SvTYPE(SvRV(*rv)) != SVt_PVAV) continue; /* skip malformed */
576 2 3014 if (av_len(row) + 1 < 2) continue;
578 3014 0 if (!ms || !sv) continue;
0 3014 if (!ms || !sv) continue;
580 1 3013 if (score != score) continue; /* skip NaN */
582 3010 3 if (rc == 1) added++;
583 1 2 else if (rc == -1) break; /* pool full */
588 1 4 RETVAL = added;
596 2 0 EXTRACT(self);
0 2 EXTRACT(self);
0 2 EXTRACT(self);
603 1315 2 while (f != SS_NONE) { nfree++; f = h->nodes[f].parent; }