Commit graph

160 commits

Author SHA1 Message Date
Travis
d0de49ef39
handle edge cases in range queries 2020-05-16 10:35:35 -05:00
Travis
8a22a3ede3 fix some range query problems 2020-04-15 14:42:16 -05:00
Travis
79a6c1e5ab upgrade decimal min/max with scale 2020-04-15 00:14:07 -05:00
Todd Gruben
5590f1d954 lint fix 2020-04-10 19:07:01 -05:00
Todd Gruben
ef5a8cefef Added request Close and optimized availble shard with new view capabilities 2020-04-10 17:59:44 -05:00
Seebs
017e65cd99 Return empty rows for impossible ranges
If the high end of a range is below the low end of the range, there's
no values in it, so we can short-circuit that. If we don't, if the
low end is zero or higher, and the high end is below zero, we can
get very surprising behaviors, such as accepting values up to the
inverse of the high end. Add a test case for this and treat it the
same as a low range end above the field's maximum or a high end
below the field's minimum, returning an empty row immediately.
2020-04-10 13:24:08 -05:00
Seebs
be379e7806 cache AvailableShards
The computation of available shards is cheap, because realistically, virtually
no one has enough shards that the resulting bitmap is more than one container.

We don't try to fix this at the field/index levels because it's significantly
harder to do there, but I think the creation of these bitmaps is probably
the most expensive part, and switching the unions to union-in-place probably
reduces cost significantly.

Note that the bitmaps being unioned almost certainly have exactly one small
container in them.
2020-04-07 19:33:21 -05:00
Todd Gruben
6bd81b87eb unexport availableShardFileFlushDuration 2020-04-05 18:37:11 -05:00
Todd Gruben
000ea90877 unbuffer channel 2020-04-05 18:34:43 -05:00
Todd Gruben
af068e08e7 cleanup and comments 2020-04-05 18:34:43 -05:00
Todd Gruben
40a3dce93c Co-authored-by: Travis Turner <github@calfrope.com> 2020-04-05 18:34:43 -05:00
Todd Gruben
bb04f7f6ac limit frequency of writes for available shards 2020-04-05 18:31:28 -05:00
Travis
b7fcfb41d9 add proto OldMin/OldMax for backward compatibility 2020-04-03 12:25:07 -05:00
Travis
b4f1781d30 make sure frag.maxRow() call is lock-protected 2020-04-02 23:25:57 -05:00
Travis
182c1d3c42 alter tests to allow for shardwidth22
also, reset BitDepth on field and bsiGroup during
importRoaringOverwrite
2020-04-02 17:32:49 -05:00
Travis
4d985653ae convert grpc response to use pql.Decimal 2020-04-01 23:59:50 -05:00
Travis
22cca67d6a Revert "back out the pql.Decimal changes"
This reverts commit 741ba9b268.
2020-04-01 17:46:46 -05:00
Travis
741ba9b268 back out the pql.Decimal changes 2020-04-01 11:10:33 -05:00
Travis
1da7cf09bb support pql.Decimal for decimal field min/max arguments 2020-03-27 16:02:47 -05:00
Travis
57c30b9dae support mutex/bool fields in anti-entropy 2020-03-19 11:11:33 -05:00
Travis
298f290e86
Avoid overflow on decimal min/max default values
If the min/max provided are already on the boundary of int64,
then we don't want to operate on them and cause overflow.
there are still overflow scenarios where a user provides a
min/max which is not on the boundary, but overflow once the
scale is applied. This does not address those cases, but at
least it addresses the default case (where a min/max is not
provided)
2020-03-18 07:41:35 -05:00
Travis
513edeae9c fix min/max bug for decimal fields 2020-03-14 22:35:24 -05:00
Travis
3863ab4b41 Fixes the min/max bug for int fields with offset.
Methods `MinForShard` and `MaxForShard` were not adjusting
their return value by the offset.
2020-03-14 14:01:40 -05:00
Travis
cbf80370cb support fragment sync for int and decimal fields
This PR adds support for anti-entropy syncing for integer
and decimal fields. It differs from the logic for other
field types in that it does not rely on a consensus to determine
what the value should be; instead, it considers the correct
values to be those of the primary replica. From there, data
is pushed to all non-primary replicas.
2020-03-13 12:15:54 -05:00
Matthew Jaffee
8c9b717b05
fix "worhtless" typo in comment 2020-02-21 16:00:31 -06:00
Matt Jaffee
7321f9427c
min and max should properly scale their output for decimal fields
this involved adding an optional float value to the ValCount struct
which complicated result types, necessitated grpc changes, and needed
quite a few tests at different layers.
2020-02-21 14:11:29 -06:00
Kuba Podgórski
57eb741c24
Don't allow an int and decimal fields to be created with keys=true (#118) 2020-02-14 08:47:31 +01:00
Travis
e40400b130 Ensure ForeignIndex key translation happens in API.
For Fields with ForeignIndex (which have keys), the API was missing
the logic to do that translation against the translateStore of
the foreign index. This commit adds that logic, as well as some
missing translateStore-related logic in the gRPC code.
2020-01-28 22:46:12 -06:00
Travis
b620e37e51 move the foreign index key check into applyTranslateStore() 2020-01-17 14:41:41 -06:00
Travis
efffa39c2c check foreign index on field open 2020-01-17 11:42:21 -06:00
Ben Johnson
10ccb6d523 translate foreign index 2020-01-16 13:53:12 -06:00
Travis
54679c12c4 post merge, needs review of TODOs 2020-01-14 22:10:12 -06:00
Travis
df51f07f96 Merge branch 'enterprise' into translation-sharding 2020-01-14 20:05:12 -06:00
Travis
a6a2f84bd5 During Holder.Open, apply foreign index after all indexes open
In the case where a field with a foreign index opens before the
foreign index has opened (and is available as a reference in the
holder), push the field into a queue to have its foreign index
applied once all indexes have opened.
2020-01-10 12:28:28 -06:00
Travis
742135dc10 Get ForeignIndex string value when reading BSI field.
In the `Inspect` function in `server/grpc.go`, getting
the value of an `int` field with a foreign index to
an index with `Keys()`, we need to return the string
key value instead of the BSI int value for the field.

This commit also changes the method `Field.keys()` to be
exported as `Field.Keys()` so that it's accessible in
the server package.
2020-01-10 12:28:28 -06:00
Travis
881d3bef06 Adjust the FieldOption logic to be in place prior to field.Open().
This commit changes the order of FieldOption application so that
it's always set before field.Open() is called.

This was required because field.Open() now uses some of the values
from FieldOptions to determine if/when to use a particular
translateStore. For example, when FieldOptions.ForeignIndex is set,
the translateStore from the foreign index is retrieved during
field.Open().
2020-01-10 12:28:28 -06:00
Travis
1542cbefc0 Add FieldOption.ForeignIndex
This allows a BSI field to have an option indicating
that it is a foreign key to another index. If the foreign
index has column keys, then this field handles string values
by using the foreign index's translate store.
2020-01-10 12:28:27 -06:00
Ben Johnson
cda2729935 fix bitdepth race 2020-01-08 09:47:43 -07:00
Ben Johnson
1409ab5664 fix data race 2020-01-08 09:47:43 -07:00
Ben Johnson
c0a129979e fix tests 2020-01-08 09:47:43 -07:00
Ben Johnson
e3606d6615 fix id generation 2020-01-08 09:47:43 -07:00
Ben Johnson
82910911dd refactoring id partitioning 2020-01-08 09:47:43 -07:00
Ben Johnson
b3e86e8394 refactoring stores back into index/field 2020-01-08 09:47:43 -07:00
Ben Johnson
7215bfd16c Implement translator store sharding 2020-01-08 09:47:43 -07:00
Todd Gruben
643884aeb3 refactored clear to fix q2;removed unused comment 2020-01-07 12:55:32 -06:00
Todd Gruben
26e3460413 removed view creation from ClearValue 2020-01-07 10:55:45 -06:00
Todd Gruben
7a2d90ade8 add support to clear value for column 2019-12-09 16:28:03 -06:00
Seebs
c5136b14db ensmarten snapshot queue
The snapshot queue needs a bit more subtlety. In some cases,
we really do want to do a snapshot right now -- these shouldn't
have to wait for possibly a hundred or more other snapshots
to complete.

In other cases, we don't really care that much whether we do
a snapshot, and just dropping it is probably fine.

To accommodate this, we distinguish between "urgent" and
"normal" snapshots, and between "Immediate" (does an urgent
snapshot, waits for it) and "Enqueue" (might enqueue a snapshot
but *also might not* if we're already busy). There's a
corresponding "Await" to wait for a snapshot, if one is
pending, but not if one isn't.

We also have a background scan that checks the holder. It will
scan pretty actively when it's finding fragments that need
snapshots (no enqueued snapshot, opN > MaxOpN). It pauses
for a second after every hundred fragments that didn't need
snapshots, and for a minute after each holder scan that didn't
find any. So, if you don't need snapshots, it does basically
nothing, if you do, it'll be moderately aggressive about
submitting tasks -- but it always waits if there's *any*
requested snapshots in the queues.

Updates since initial draft:

Check results from Await more consistently, and in one case, use Immediate
instead and then check its error.

Fix a race condition.  The race condition comes about if:

1. You have a limited enough worker pool that this can happen.
(In testing we tend to have a worker pool of 1.)
2. A fragment is in the normal, non-urgent, queue already.
3. An immediate request comes in for that fragment. This always
happens *with the fragment lock held*.
4. A worker thread grabs that fragment from the queue.
5. The worker thread now waits on the lock. Meanwhile, the
immediate request blocks on sending the fragment to the urgent
queue.
6. The worker can't read the urgent queue, and the immediate
request can't send it, so the immediate request can't proceed.

What's supposed to happen is that the immediate request sends
the thing, and gets into Await(), which sleeps on a condition
variable using the lock, which is to say, releases the lock.

The obvious resolution is to let go of the lock, send the
message, and then reclaim the lock. But then we have the
possibility that the message sent ends up with a timestamp
right after a snapshot that happened *after* the Immediate
request was started. Oops. So we create the request, then let
go of the lock, then send the request, then reclaim the lock
and go into the Await state. All is well.

This is on top of more general use of wait groups, etcetera,
to allow us to ensure that any holder scans terminate *before*
we close the channels they might otherwise be trying to write to.
So, shutdown process is now:

* grab lock on queue (workers and scanners don't use the lock)
* mark snapshotqueue done
* wait for holder scans to complete/exit
* close and nil out all the channels
* release lock

Anything trying to submit to this needs to hold the lock, unless
it's a holder scan, so either it got the lock before we did and already
submitted the thing, or it will get the lock after this and not find
a channel to write to; it's just the holder scanner that has an
ongoing thing that might have started a write to the channel *without*
a lock held, because it's expected that it might have to wait minutes
or hours before the write will complete because it's a background task.

Also, rework the background holder scan to grab lists of
indexes/fields/views/fragments, then scan the grabbed/copied lists,
rather than iterating over maps, allowing us to grab the lock when
we're about to access a thing and let it go when done.

There might be a simpler/cleaner way to do this but opinions on how
safe it is are very mixed, so in the mean time, I'm making the range
behavior not depend at all on there being no writes to the various tiers
of holder/index/view/fragment during the background scans.
2019-11-12 12:15:13 -06:00
Seebs
538768ea9d handle truncated/damaged .available.shards
The available shards file is just a hint to save us a bit
of time later; we don't need it to run and it can get updated
pretty easily later. If we have problems reading it, we
should just report the error, nuke the file, and continue
without it.
2019-11-12 12:14:29 -06:00
Seebs
a804a0dfb1 always treat BSI fields as having at least their depth
If you imported only small values, BSI fields could end up
not bothering to clear higher bits in existing values, which
produced strange behaviors.

We also move the computation of requiredDepth, and the change
to the field, down, combining it with the other checks of the
values for min/max being in range.

Without this, a data set with a ludicrously large value in it
could break a BSI field's depth even though the import would then
reject it.
2019-11-11 16:55:26 -06:00