Skip to content

Commit

Permalink
Introduce GetRangeAndHop to support index prefetch optimization
Browse files Browse the repository at this point in the history
  • Loading branch information
nblintao committed Oct 26, 2021
1 parent 2208b04 commit 36091b9
Show file tree
Hide file tree
Showing 38 changed files with 1,925 additions and 117 deletions.
101 changes: 101 additions & 0 deletions bindings/c/fdb_c.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -511,6 +511,106 @@ FDBFuture* fdb_transaction_get_range_impl(FDBTransaction* tr,
.extractPtr());
}

FDBFuture* fdb_transaction_get_range_and_hop_impl(FDBTransaction* tr,
uint8_t const* begin_key_name,
int begin_key_name_length,
fdb_bool_t begin_or_equal,
int begin_offset,
uint8_t const* end_key_name,
int end_key_name_length,
fdb_bool_t end_or_equal,
int end_offset,
uint8_t const* hop_info_name,
int hop_info_name_length,
int limit,
int target_bytes,
FDBStreamingMode mode,
int iteration,
fdb_bool_t snapshot,
fdb_bool_t reverse) {
/* This method may be called with a runtime API version of 13, in
which negative row limits are a reverse range read */
if (g_api_version <= 13 && limit < 0) {
limit = -limit;
reverse = true;
}

/* Zero at the C API maps to "infinity" at lower levels */
if (!limit)
limit = GetRangeLimits::ROW_LIMIT_UNLIMITED;
if (!target_bytes)
target_bytes = GetRangeLimits::BYTE_LIMIT_UNLIMITED;

/* Unlimited/unlimited with mode _EXACT isn't permitted */
if (limit == GetRangeLimits::ROW_LIMIT_UNLIMITED && target_bytes == GetRangeLimits::BYTE_LIMIT_UNLIMITED &&
mode == FDB_STREAMING_MODE_EXACT)
return TSAV_ERROR(Standalone<RangeResultRef>, exact_mode_without_limits);

/* _ITERATOR mode maps to one of the known streaming modes
depending on iteration */
const int mode_bytes_array[] = { GetRangeLimits::BYTE_LIMIT_UNLIMITED, 256, 1000, 4096, 80000 };

/* The progression used for FDB_STREAMING_MODE_ITERATOR.
Goes 1.5 * previous. */
static const int iteration_progression[] = { 4096, 6144, 9216, 13824, 20736, 31104, 46656, 69984, 80000, 120000 };

/* length(iteration_progression) */
static const int max_iteration = sizeof(iteration_progression) / sizeof(int);

if (mode == FDB_STREAMING_MODE_WANT_ALL)
mode = FDB_STREAMING_MODE_SERIAL;

int mode_bytes;
if (mode == FDB_STREAMING_MODE_ITERATOR) {
if (iteration <= 0)
return TSAV_ERROR(Standalone<RangeResultRef>, client_invalid_operation);

iteration = std::min(iteration, max_iteration);
mode_bytes = iteration_progression[iteration - 1];
} else if (mode >= 0 && mode <= FDB_STREAMING_MODE_SERIAL)
mode_bytes = mode_bytes_array[mode];
else
return TSAV_ERROR(Standalone<RangeResultRef>, client_invalid_operation);

if (target_bytes == GetRangeLimits::BYTE_LIMIT_UNLIMITED)
target_bytes = mode_bytes;
else if (mode_bytes != GetRangeLimits::BYTE_LIMIT_UNLIMITED)
target_bytes = std::min(target_bytes, mode_bytes);

return (
FDBFuture*)(TXN(tr)
->getRangeAndHop(
KeySelectorRef(KeyRef(begin_key_name, begin_key_name_length), begin_or_equal, begin_offset),
KeySelectorRef(KeyRef(end_key_name, end_key_name_length), end_or_equal, end_offset),
StringRef(hop_info_name, hop_info_name_length),
GetRangeLimits(limit, target_bytes),
snapshot,
reverse)
.extractPtr());
}

// TODO: Support FDB_API_ADDED in generate_asm.py and then this can be replaced with fdb_api_ptr_unimpl.
FDBFuture* fdb_transaction_get_range_and_hop_v709(FDBTransaction* tr,
uint8_t const* begin_key_name,
int begin_key_name_length,
fdb_bool_t begin_or_equal,
int begin_offset,
uint8_t const* end_key_name,
int end_key_name_length,
fdb_bool_t end_or_equal,
int end_offset,
uint8_t const* hop_info_name,
int hop_info_name_length,
int limit,
int target_bytes,
FDBStreamingMode mode,
int iteration,
fdb_bool_t snapshot,
fdb_bool_t reverse) {
fprintf(stderr, "UNIMPLEMENTED FDB API FUNCTION\n");
abort();
}

FDBFuture* fdb_transaction_get_range_selector_v13(FDBTransaction* tr,
uint8_t const* begin_key_name,
int begin_key_name_length,
Expand Down Expand Up @@ -702,6 +802,7 @@ extern "C" DLLEXPORT fdb_error_t fdb_select_api_version_impl(int runtime_version
// WARNING: use caution when implementing removed functions by calling public API functions. This can lead to
// undesired behavior when using the multi-version API. Instead, it is better to have both the removed and public
// functions call an internal implementation function. See fdb_create_database_impl for an example.
FDB_API_CHANGED(fdb_transaction_get_range_and_hop, 710);
FDB_API_REMOVED(fdb_future_get_version, 620);
FDB_API_REMOVED(fdb_create_cluster, 610);
FDB_API_REMOVED(fdb_cluster_create_database, 610);
Expand Down
18 changes: 18 additions & 0 deletions bindings/c/foundationdb/fdb_c.h
Original file line number Diff line number Diff line change
Expand Up @@ -244,6 +244,24 @@ DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_transaction_get_range(FDBTransaction
fdb_bool_t reverse);
#endif

DLLEXPORT WARN_UNUSED_RESULT FDBFuture* fdb_transaction_get_range_and_hop(FDBTransaction* tr,
uint8_t const* begin_key_name,
int begin_key_name_length,
fdb_bool_t begin_or_equal,
int begin_offset,
uint8_t const* end_key_name,
int end_key_name_length,
fdb_bool_t end_or_equal,
int end_offset,
uint8_t const* hop_info_name,
int hop_info_name_length,
int limit,
int target_bytes,
FDBStreamingMode mode,
int iteration,
fdb_bool_t snapshot,
fdb_bool_t reverse);

DLLEXPORT void fdb_transaction_set(FDBTransaction* tr,
uint8_t const* key_name,
int key_name_length,
Expand Down
35 changes: 35 additions & 0 deletions bindings/c/test/unit/fdb_api.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -193,6 +193,41 @@ KeyValueArrayFuture Transaction::get_range(const uint8_t* begin_key_name,
reverse));
}

KeyValueArrayFuture Transaction::get_range_and_hop(const uint8_t* begin_key_name,
int begin_key_name_length,
fdb_bool_t begin_or_equal,
int begin_offset,
const uint8_t* end_key_name,
int end_key_name_length,
fdb_bool_t end_or_equal,
int end_offset,
const uint8_t* hop_info_name,
int hop_info_name_length,
int limit,
int target_bytes,
FDBStreamingMode mode,
int iteration,
fdb_bool_t snapshot,
fdb_bool_t reverse) {
return KeyValueArrayFuture(fdb_transaction_get_range_and_hop(tr_,
begin_key_name,
begin_key_name_length,
begin_or_equal,
begin_offset,
end_key_name,
end_key_name_length,
end_or_equal,
end_offset,
hop_info_name,
hop_info_name_length,
limit,
target_bytes,
mode,
iteration,
snapshot,
reverse));
}

EmptyFuture Transaction::watch(std::string_view key) {
return EmptyFuture(fdb_transaction_watch(tr_, (const uint8_t*)key.data(), key.size()));
}
Expand Down
18 changes: 18 additions & 0 deletions bindings/c/test/unit/fdb_api.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,24 @@ class Transaction final {
fdb_bool_t snapshot,
fdb_bool_t reverse);

// Returns a future which will be set to an FDBKeyValue array.
KeyValueArrayFuture get_range_and_hop(const uint8_t* begin_key_name,
int begin_key_name_length,
fdb_bool_t begin_or_equal,
int begin_offset,
const uint8_t* end_key_name,
int end_key_name_length,
fdb_bool_t end_or_equal,
int end_offset,
const uint8_t* hop_info_name,
int hop_info_name_length,
int limit,
int target_bytes,
FDBStreamingMode mode,
int iteration,
fdb_bool_t snapshot,
fdb_bool_t reverse);

// Wrapper around fdb_transaction_watch. Returns a future representing an
// empty value.
EmptyFuture watch(std::string_view key);
Expand Down
Loading

0 comments on commit 36091b9

Please sign in to comment.