Commit graph

4668 commits

Author SHA1 Message Date
Seebs
5c8106bead drop slice implementation
The actually-a-slice implementation of Container was useful in
debugging but does not spark joy.
2019-03-22 16:31:29 -05:00
Seebs
45e8978835 messing around with the performance of unmap
Noticed in profiling that unmap wasn't being inlined. Also noticed
that every call is on a specific container type, so now they're
specialized and small enough to inline.
2019-03-22 16:31:29 -05:00
Seebs
117942c0f3 Add stash-based implementation of Container
This implementation, controlled by the build flag "container24s",
is similar to the single-slice container implementation, but goes
a bit further. First, instead of using a native slice as its internal
storage, it uses pointer/len/cap as distinct values, and only int32
ranges for len and cap. Second, it has a small region of additional
storage which it uses as a backing store by default for arrays or
runs. The idea is that, if you request a new empty array container,
you get one with a pre-allocated virtual slice big enough for five
values, actually stored in the Container. This is useful because
Go's allocator has size classes for 16 and 32 bytes, and the
Container comes in at 24 bytes worth of storage -- meaning that if
you allocate a container, you're allocating 32 bytes anyway, so we
might as well use that space to avoid extra allocations.

This includes some test fixups because DeepEqual was testing
too much equality in some tests.

Also, we simplify unionArrayArray to postpone creating a Container
until we're ready.
2019-03-22 16:31:29 -05:00
Seebs
47dcb5b4a7 Abstract away access to container slices
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.
2019-03-22 16:31:29 -05:00
Matthew Jaffee
86ea040639
Merge pull request #1908 from jaffee/bitmap-any-quick-fix
quick fix for Bitmap.Any bug [no changelog]
2019-03-21 16:09:59 -05:00
Matt Jaffee
d202e6a1a0
quick fix for Bitmap.Any bug
Want to make empty containers a thing of the past, but that can wait for another
day.
2019-03-21 15:46:19 -05:00
Matthew Jaffee
7550b5445a
Merge pull request #1900 from jaffee/validate-shard
Validate shard
2019-03-20 23:06:22 -05:00
Matt Jaffee
33b54c68d5
add lock on cluster.OwnsShard 2019-03-20 22:04:20 -05:00
Matt Jaffee
97ba8771bc
add test for only opening owned shards 2019-03-20 22:04:20 -05:00
Todd Gruben
418a8788ed
gofmt missing 2019-03-20 22:04:20 -05:00
Todd Gruben
186f034b16
missed commit 2019-03-20 22:04:20 -05:00
Todd Gruben
8edd2b3d13
applied travis suggestions 2019-03-20 22:04:20 -05:00
Todd Gruben
27492a11cc
some formating issues 2019-03-20 22:04:19 -05:00
Todd Gruben
38de65eac0
only load shards that are applicable to node 2019-03-20 22:04:19 -05:00
Matthew Jaffee
66d750bd53
Merge pull request #1904 from jaffee/mmap-fail-docs
add config docs for max-map-count
2019-03-19 20:04:51 -05:00
Matt Jaffee
a7e77566a4
add config docs for max-map-count 2019-03-19 16:21:24 -05:00
Matthew Jaffee
f299473658
Merge pull request #1903 from jaffee/mmap-fail
Mmap fail
2019-03-19 14:02:14 -05:00
Matt Jaffee
226f15446b
lock MaxMapCount and fix unused var 2019-03-19 12:55:26 -05:00
Matt Jaffee
e469285fe3
add fragment mmap tracking and limiting
in the case that the map limit is reached, we'll fall back to reading the file
into memory normally.
2019-03-19 12:55:26 -05:00
Todd Gruben
327aa70924
add failure path for mmap 2019-03-19 12:55:25 -05:00
seebs
b2eff07d8d
Merge pull request #1897 from seebs/seebs/inplace
Address UnionInPlace performance regressions
2019-03-15 12:02:10 -05:00
Seebs
cf5f9f9a57 add clarifying comment 2019-03-15 11:19:49 -05:00
Seebs
97486f410b WIP: Union/UnionInPlace performance improvements
This consolidates a number of changes. The first is significant
reductions in allocation and copying during UnionInPlace
operations on very sparse containers -- for instance, combining
two array containers with one item each.

We fix up the logic for identifying and handling cases where
only one of the containers being unioned together has a given
key.

We generally favor cloning an existing container over unioning
it into a new empty container.

When unioning two containers, we were using unionIntoTargetSingle
on those two containers, into an empty bitmap. For more, we were
creating an empty bitmap, then unioning all the others into
it; it's faster to clone the first, then union the others into
it.

The overall logic for UnionInPlace is cleaned up and simplified
a bit. However, it's then complexified a bit, because it turns
out that while it's a bad idea to convert single-item arrays to
bitmaps to union them, by a few hundred items, the bitmap
conversion saves a lot of time even if it costs an allocation.

The value of N picked here is sort of arbitrary, but
512 seems to be about right. The big problem is a massive
performance hit in cases where, say, there's only a
couple of items per container, and the bitmap conversion
is extremely expensive. If you wait until N reaches
the array size cap, though, you take a very noticeable
performance hit (can be a factor of 2.5-3 in simple
testing).

We also add some stat counters, and rename an internal
method on the `handledIters` type.
2019-03-14 15:17:38 -05:00
Seebs
054cb206d5 improve union-related benchmarking
Add a benchmark to test a specific case where UnionInPlace is
underperforming the naive union operation badly.

Also, the UnionBulk test was reusing a bitmap, meaning that it ended
up doing a lot of unions into a bitmap that already had all the
bits it was supposed to have. This broke a couple of other tests
in unexpected ways.

We also now use UnionInPlace in importRoaring, and test it
in the container combinations tests via a wrapper.
2019-03-14 15:16:49 -05:00
Matthew Jaffee
53d018a2b1
Merge pull request #1892 from jaffee/import-roaring-union
smallWrite path for import-roaring
2019-03-12 08:16:25 -05:00
Matt Jaffee
a28141c466
revert to Union for importRoaring
UnionInPlace is still heavily affected by
https://github.com/pilosa/pilosa/issues/1875 where containers that exist in an
incoming bitmap can cause massive unnecessary allocations of bitmap containers
when an array of short length is all that's needed.
2019-03-11 17:43:55 -05:00
Matt Jaffee
52d43fb4e2
add smallPath for importRoaring
this converts the rowSet to a map from a slice which might be bad... benchmarks
will tell.
2019-03-11 17:43:55 -05:00
Matt Jaffee
d0f8304f1c
add importRoaring small updates benchmark 2019-03-11 17:43:55 -05:00
Matt Jaffee
19807ff3a7
use num containers to decide which direction to union
avoids doing a potentially expensive f.storage.Count()
2019-03-11 17:43:55 -05:00
Matt Jaffee
e33ca2d0ae
use UnionInPlace in import-roaring
get the count of the existing fragment and compare it to the incoming bits to
decide which should be unioned into the other. This should generally result in
far fewer allocations, though there is much work that needs to be done within
UnionInPlace to further improve things.

unrelatedly, I added a TODO to change the long-query-time option to move it out
of cluster. It should probably be happening at the API level so that different
handlers can reuse it, but if we're going to do that we'll want to make sure
that any potentially time intensive operations are pulled into api from
handler (e.g. protobuf decoding)
2019-03-11 17:43:55 -05:00
Matt Jaffee
663c725779
import benchmarking tweaks
importRoaring large fragment benchmark

skip concurrent import benchmarks with testing.short
2019-03-11 17:43:07 -05:00
Matthew Jaffee
6f9bac960e
Merge pull request #1871 from jaffee/1864-random-import-perf
1864 random import perf
2019-03-07 10:55:22 -06:00
Matt Jaffee
9fe58e5e36
exterminate unnecessary sprintf 2019-03-07 10:24:41 -06:00
Matt Jaffee
b71096b688
update licensing and NOTICE to reflect btree being moved to roaring 2019-03-05 15:52:32 -06:00
Matt Jaffee
831195e7d2
update roaring container benchmarks to do both slice and btree 2019-03-05 15:46:13 -06:00
Matt Jaffee
e54dbd6731
simplify row/lastRow comparison in bulkImport 2019-03-05 12:20:21 -06:00
Matt Jaffee
cfb2a80866
write large fragment import benchmark
needed to pull in btree containers to get acceptable perf building the initial
data. Still quite slow though.
2019-03-05 08:48:33 -06:00
Matt Jaffee
6fe1ab45c2
fixup Fragment_Import benchmark
It was doing a fresh import on the first round and then importing the same data
into the fragment over and over.
2019-03-05 08:47:44 -06:00
Matt Jaffee
7af64e382c
comments to make import mutex less confusing 2019-03-04 21:38:09 -06:00
Matt Jaffee
8476fffaa7
always operate on storage in importPositions regardless of smallWrite
This greatly simplifies the code, and with the recent addition of DirectAddN and
DirectRemoveN should be as or more performant than doing the separate bitmap and
union (in most cases, unsorted data could still be slower). Perhaps more
importantly, it is also less allocation heavy than the union approach. Also
makes it trivial to get the counts of changed bits, so I've cleaned up the stats
to show number of bits we're importing/clearing and the number of bits that
actually changed.
2019-03-04 21:38:09 -06:00
Matt Jaffee
868342d338
fix benchmarks broken by import modifying its args in-place 2019-03-04 21:38:08 -06:00
Matt Jaffee
4c42069d5d
implements bitmap batch Direct* operations which are optimized for sorted data
also reset the data on AddN and RemoveN ops if the log write fails
2019-03-04 21:38:08 -06:00
Matt Jaffee
c32c8cda84
only write changed values to op log 2019-03-04 21:38:08 -06:00
Matt Jaffee
9b8a97ccb6
maintain column set in bulkImportMutex to guard against repeats 2019-03-04 21:38:08 -06:00
Matt Jaffee
4082ce655a
wip on adding mutex support to random import perf 2019-03-04 21:38:08 -06:00
Matt Jaffee
f06a9f0e6e
positionsForValue appends to existing slices rather than allocating small ones 2019-03-04 21:38:08 -06:00
Matt Jaffee
a58459cf0f
fix spelling of unnecessary 2019-03-04 21:38:08 -06:00
Matt Jaffee
d429d7c496
code review feedback: add Bitmap.Any and remove unecessary condition 2019-03-04 21:38:07 -06:00
Matt Jaffee
023faebd90
fix bug where opN wasn't getting set/cleared correctly 2019-03-04 21:38:07 -06:00
Matt Jaffee
7037ebf4b3
rename smallPath->smallWrite for consistency 2019-03-04 21:38:07 -06:00