libidset: fix idset_last() at size=32 #2340
This turned out to be a veb bug, which I opened quixotically at mrdomino/libveb#1.
The PR presents a workaround and some tests, one unit test for veb.c (skipping with TODO), and one for libidset which demonstrates the fix and pokes around the edges of it.
I regret that I do not think I am the right person to have a go at the upstream bug, hence the workaround, after satisfying myself that it must be localized to
Before the workaround, the only failure I could make happen was at size 32, but check 31, 32, 33. Check that idset_last() returns correctly for all possible "last" values within those sizes, to be sure the workaround doesn't introduce any issues.
Problem: idset_last() always fails when the idset has a fixed size of 32. This is a vebpred() bug, and appears to be peculiar to size=32 and vebpred(size-1). This commit adds a workaround: if vebpred(size-1) fails, check vebsucc(size-1), then if that fails check vebpred(size-2). The workaround is enabled for all sizes > 1, just in case. Overhead should be low (in fact no overhead for non-empty idsets, when vebpred() works as advertized). Fixes #2336 (using the term loosely)
@@ Coverage Diff @@ ## master #2340 +/- ## ========================================== - Coverage 80.83% 80.82% -0.02% ========================================== Files 215 215 Lines 34236 34240 +4 ========================================== - Hits 27676 27674 -2 - Misses 6560 6566 +6