We added the containers_btree implementation to roaring/, which
makes it silly to keep this one. Also, this one is the only reason
that container.Mapped needed to be exported.
So with the switch to a new linter, we get a lot of new warnings,
and the majority of them are harmless probably, but a few might be
real. Variously just use _ to suppress warnings, or report errors.
There's probably things here that deserve better fixes, but we can
always revisit it.
On a 64-bit machine, the slices in a Container consume 72
bytes, and the Container itself is 80. But we only use one
slice at a time! This patch shifts us to keeping a single
slice in the Container, and converting provided slices to
and from that type when we want to update it. (It is not
safe to access the slice through the wrong type.)
We also add some new tests, conditional on a build tag
called `roaringparanoia`. These tests will be optimized
away entirely by the compiler when the tag isn't
present, because the conditionals use a const. These catch
possible errors like trying to access the bitmap slice
of a non-bitmap container.
We also eliminate all direct creation of Container literals,
so we can mess with the internals more. (On reflection
and study, we decided not to go to the fancier design where
references to .n and .typ were also converted to function
calls, which would have allowed packing those attributes
more tightly, because it was a lot more overhead and a lot
of work to keep track of.)
There's some circumstances where we appear to have been
relying on incorrect guesses about the nature of containers.
For instance, in xorBitmapRun, there's logic that makes sense
only if the output's a run container, but it's not, it's a
bitmap container. This creates strange behavior sometimes,
though. Several of these are corrected now.
The cmp() function used to compare btree keys was using the
trick of comparing unsigned values by coercing the result
of subtraction to a signed type. This is fine as long as
the range of differences never actually exceeds the limits
of the signed type. For instance, with int64, as long as
the magnitude of the difference is under 2^63 or so, it
works reasonably well.
Plain int, however, can be a 32-bit type, at which point
the magnitude of difference needed to break it is only
2^31 or so.
Subtraction and type conversion is enough cheaper than
branches that this is worth preserving, but it's worth
preserving by switching to an explicit int64 for the
operation and return type. This will not actually affect
performance except for people using the btree code on
32-bit machines, so it probably won't ever matter.
Which may also be true of the potential wrong answers,
but "might be slower" is a better risk than "might
crash".