Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Have indexing by record scan by key ranges instead of by tuple ranges #2655

Draft
wants to merge 2 commits into
base: main
Choose a base branch
from

Conversation

MMcM
Copy link
Collaborator

@MMcM MMcM commented Apr 11, 2024

This avoids having to recover a TupleRange from an unbuilt Range.

See #2651 (comment)

@MMcM MMcM force-pushed the index-by-record-ranges branch from 5a9b5e0 to 954b481 Compare April 11, 2024 18:59
@FoundationDB FoundationDB deleted a comment from foundationdb-ci Apr 11, 2024
@foundationdb-ci
Copy link
Contributor

Result of fdb-record-layer-pr on Linux CentOS 7

  • Commit ID: 954b481
  • Duration 0:49:27
  • Result: ❌ FAILED
  • Error: Error while executing command: ./gradlew --no-daemon --console=plain -b ./build.gradle build destructiveTest -PcoreNotStrict -PreleaseBuild=false -PpublishBuild=false -PspotbugsEnableHtmlReport. Reason: exit status 1
  • Build Log terminal output (available for 30 days)
  • Build Workspace zip file of the working directory (available for 30 days)

@MMcM MMcM requested a review from alecgrieser April 11, 2024 20:18
final byte[] keyPrefix = store.recordsSubspace().pack();
final byte[] rangeStart = ByteArrayUtil.join(keyPrefix, range.begin);
final byte[] rangeEnd = ByteArrayUtil.join(keyPrefix, range.end);
final KeyRange keyRange = new KeyRange(rangeStart, rangeEnd);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm trying to wrap my head around the KeyRange. Looking at TupleRange::toRange (which is still used to translate a KeyRange into an FDB Range), a KeyRange where the low endpoint is RANGE_INCLUSIVE and the end endpoint is always RANGE_EXCLUSIVE will always behave just like a Range over those same two keys. But it also behaves just like a TupleRange with packed elements, so for instance, something like new KeyRange(bytes, EndpointType.RANGE_INCLUSIVE, bytes, EndpointType.RANGE_INCLUSIVE) represents all keys "strictly" prefixed by the range (that is, excluding keys prefixed by bytes + '\xff').

That feels fair enough.

// tupleRange has an inclusive high endpoint, so end isn't a valid tuple.
// But buildRangeOnly needs to convert missing Ranges back to TupleRanges, so round up.
rangeEnd = ByteArrayUtil.strinc(range.end);
rangeEnd = range.end;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Setting up this particular test may be a pain, so it may not be worth it, but I think if we wanted to validate that this fixed anything, we could add a test that used non-integer record type keys. Or a test that used a record type key with what would have been problematic value for its record type key, like 255

* @return a cursor that will scan everything in the range, picking up at continuation, and honoring the given scan properties
*/
@Nonnull
RecordCursor<FDBStoredRecord<M>> scanRecordsKeyRange(@Nonnull KeyRange range,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you think this API should be INTERNAL? Most of the use cases I can think of are probably internal, though there may be some use case for APIs that returns a KeyRange that the user can hand back, or something.

@Nonnull
@SuppressWarnings("PMD.CloseResource")
private <M extends Message> RecordCursor<FDBStoredRecord<M>> scanTypedRecordsInternal(@Nonnull RecordSerializer<M> typedSerializer,
@Nonnull Consumer<KeyValueCursor.Builder> setRange,
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

minor: I was trying to think if there was a better way to structure this than a Consumer. The answer may be "no". The best alternatives I could think of would be to either have this take a KeyValueCursor.Builder than callers would pre-fill with the range already set, or something more exotic like adding a .setRange(KeyValueCursor.Builder) to the TupleRange and KeyValueRange abstractions, or making TupleRange and KeyValueRange implement some common interface that could set the low and high endpoints on a KeyValueCursor.Builder.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants