mirror of
https://github.com/apple/foundationdb.git
synced 2025-06-03 03:41:53 +08:00
Address review comments
This commit is contained in:
parent
f887e3e364
commit
21b041317c
@ -114,7 +114,7 @@ private:
|
||||
|
||||
fdb::Result res = ctx->tx().readBlobGranules(
|
||||
begin, end, 0 /* beginVersion */, -2 /* latest read version */, granuleContext);
|
||||
auto out = fdb::Result::NativeKeyValueArray{};
|
||||
auto out = fdb::Result::KeyValueRefArray{};
|
||||
fdb::Error err = res.getKeyValueArrayNothrow(out);
|
||||
if (err.code() == error_code_blob_granule_transaction_too_old) {
|
||||
info("BlobGranuleCorrectness::randomReadOp bg too old\n");
|
||||
@ -182,7 +182,7 @@ private:
|
||||
ctx->continueAfter(
|
||||
f,
|
||||
[ctx, f, results]() {
|
||||
*results = f.get<fdb::future_var::KeyRangeArray>();
|
||||
*results = copyKeyRangeArray(f.get<fdb::future_var::KeyRangeRefArray>());
|
||||
ctx->done();
|
||||
},
|
||||
true);
|
||||
|
@ -65,7 +65,7 @@ private:
|
||||
fdb::Future f = futures[i];
|
||||
auto expectedVal = store.get((*keys)[i]);
|
||||
ctx->continueAfter(f, [expectedVal, f, this, ctx]() {
|
||||
auto val = f.get<fdb::future_var::OptionalValue>();
|
||||
auto val = f.get<fdb::future_var::ValueRef>();
|
||||
if (expectedVal != val) {
|
||||
error(fmt::format("cancelAfterFirstResTx mismatch. expected: {:.80} actual: {:.80}",
|
||||
fdb::toCharsRef(expectedVal.value()),
|
||||
|
@ -63,7 +63,7 @@ private:
|
||||
ctx->continueAfterAll(*futures, [ctx, futures, results]() {
|
||||
results->clear();
|
||||
for (auto& f : *futures) {
|
||||
results->push_back(f.get<fdb::future_var::OptionalValue>());
|
||||
results->push_back(copyValueRef(f.get<fdb::future_var::ValueRef>()));
|
||||
}
|
||||
ASSERT(results->size() == futures->size());
|
||||
ctx->done();
|
||||
@ -104,7 +104,7 @@ private:
|
||||
ctx->continueAfterAll(*futures, [ctx, futures, results]() {
|
||||
results->clear();
|
||||
for (auto& f : *futures) {
|
||||
results->push_back(f.get<fdb::future_var::OptionalValue>());
|
||||
results->push_back(copyValueRef(f.get<fdb::future_var::ValueRef>()));
|
||||
}
|
||||
ASSERT(results->size() == futures->size());
|
||||
ctx->done();
|
||||
|
@ -490,7 +490,7 @@ protected:
|
||||
};
|
||||
|
||||
// Map for keeping track of future waits and holding necessary object references
|
||||
std::unordered_map<fdb::Future, CallbackInfo, fdb::FutureHash, fdb::FutureEquals> callbackMap;
|
||||
std::unordered_map<fdb::Future, CallbackInfo> callbackMap;
|
||||
|
||||
// Holding reference to this for onError future C callback
|
||||
std::shared_ptr<AsyncTransactionContext> onErrorThisRef;
|
||||
|
@ -65,4 +65,45 @@ void print_internal_error(const char* msg, const char* file, int line) {
|
||||
fflush(stderr);
|
||||
}
|
||||
|
||||
std::optional<fdb::Value> copyValueRef(fdb::future_var::ValueRef::Type value) {
|
||||
if (value) {
|
||||
return std::make_optional(fdb::Value(value.value()));
|
||||
} else {
|
||||
return std::nullopt;
|
||||
}
|
||||
}
|
||||
|
||||
KeyValueArray copyKeyValueArray(fdb::future_var::KeyValueRefArray::Type array) {
|
||||
auto& [in_kvs, in_count, in_more] = array;
|
||||
|
||||
KeyValueArray out;
|
||||
auto& [out_kv, out_more] = out;
|
||||
|
||||
out_more = in_more;
|
||||
out_kv.clear();
|
||||
for (int i = 0; i < in_count; ++i) {
|
||||
fdb::native::FDBKeyValue nativeKv = *in_kvs++;
|
||||
fdb::KeyValue kv;
|
||||
kv.key = fdb::Key(nativeKv.key, nativeKv.key_length);
|
||||
kv.value = fdb::Value(nativeKv.value, nativeKv.value_length);
|
||||
out_kv.push_back(kv);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
KeyRangeArray copyKeyRangeArray(fdb::future_var::KeyRangeRefArray::Type array) {
|
||||
auto& [in_ranges, in_count] = array;
|
||||
|
||||
KeyRangeArray out;
|
||||
|
||||
for (int i = 0; i < in_count; ++i) {
|
||||
fdb::native::FDBKeyRange nativeKr = *in_ranges++;
|
||||
fdb::KeyRange range;
|
||||
range.beginKey = fdb::Key(nativeKr.begin_key, nativeKr.begin_key_length);
|
||||
range.endKey = fdb::Key(nativeKr.end_key, nativeKr.end_key_length);
|
||||
out.push_back(range);
|
||||
}
|
||||
return out;
|
||||
};
|
||||
|
||||
} // namespace FdbApiTester
|
@ -31,6 +31,11 @@
|
||||
|
||||
#include "test/fdb_api.hpp"
|
||||
|
||||
#undef ERROR
|
||||
#define ERROR(name, number, description) enum { error_code_##name = number };
|
||||
|
||||
#include "flow/error_definitions.h"
|
||||
|
||||
namespace fmt {
|
||||
|
||||
// fmt::format formatting for std::optional<T>
|
||||
@ -107,6 +112,14 @@ static inline double microsecToSec(TimeDuration timeUs) {
|
||||
return timeUs / 1000000.0;
|
||||
}
|
||||
|
||||
std::optional<fdb::Value> copyValueRef(fdb::future_var::ValueRef::Type value);
|
||||
|
||||
using KeyValueArray = std::pair<std::vector<fdb::KeyValue>, bool>;
|
||||
KeyValueArray copyKeyValueArray(fdb::future_var::KeyValueRefArray::Type array);
|
||||
|
||||
using KeyRangeArray = std::vector<fdb::KeyRange>;
|
||||
KeyRangeArray copyKeyRangeArray(fdb::future_var::KeyRangeRefArray::Type array);
|
||||
|
||||
} // namespace FdbApiTester
|
||||
|
||||
#endif
|
||||
|
@ -39,11 +39,6 @@
|
||||
// introduce the option enums
|
||||
#include <fdb_c_options.g.h>
|
||||
|
||||
#undef ERROR
|
||||
#define ERROR(name, number, description) enum { error_code_##name = number };
|
||||
|
||||
#include "flow/error_definitions.h"
|
||||
|
||||
namespace fdb {
|
||||
|
||||
// hide C API to discourage mixing C/C++ API
|
||||
@ -133,40 +128,24 @@ struct Int64 {
|
||||
return Error(native::fdb_future_get_int64(f, &out));
|
||||
}
|
||||
};
|
||||
struct NativeKey {
|
||||
using Type = std::pair<uint8_t const*, int>;
|
||||
struct KeyRef {
|
||||
using Type = fdb::KeyRef;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
auto& [out_key, out_key_length] = out;
|
||||
return Error(native::fdb_future_get_key(f, &out_key, &out_key_length));
|
||||
}
|
||||
};
|
||||
struct Key {
|
||||
using Type = fdb::Key;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
NativeKey::Type native_out{};
|
||||
auto err = NativeKey::extract(f, native_out);
|
||||
auto& [out_key, out_key_length] = native_out;
|
||||
out = fdb::Key(out_key, out_key_length);
|
||||
uint8_t const* out_key = nullptr;
|
||||
int out_key_length = 0;
|
||||
auto err = Error(native::fdb_future_get_key(f, &out_key, &out_key_length));
|
||||
out = fdb::KeyRef(out_key, out_key_length);
|
||||
return Error(err);
|
||||
}
|
||||
};
|
||||
struct NativeValue {
|
||||
using Type = std::tuple<bool, uint8_t const*, int>;
|
||||
struct ValueRef {
|
||||
using Type = std::optional<fdb::ValueRef>;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
auto& [out_present, out_value, out_value_length] = out;
|
||||
auto out_present_native = native::fdb_bool_t{};
|
||||
auto err = native::fdb_future_get_value(f, &out_present_native, &out_value, &out_value_length);
|
||||
out_present = (out_present_native != 0);
|
||||
return Error(err);
|
||||
}
|
||||
};
|
||||
struct OptionalValue {
|
||||
using Type = std::optional<fdb::Value>;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
NativeValue::Type native_out{};
|
||||
auto err = NativeValue::extract(f, native_out);
|
||||
auto& [out_present, out_value, out_value_length] = native_out;
|
||||
out = out_present ? std::make_optional(fdb::Value(out_value, out_value_length)) : std::nullopt;
|
||||
auto out_present = native::fdb_bool_t{};
|
||||
uint8_t const* out_value = nullptr;
|
||||
int out_value_length = 0;
|
||||
auto err = native::fdb_future_get_value(f, &out_present, &out_value, &out_value_length);
|
||||
out = out_present != 0 ? std::make_optional(fdb::ValueRef(out_value, out_value_length)) : std::nullopt;
|
||||
return Error(err);
|
||||
}
|
||||
};
|
||||
@ -177,58 +156,31 @@ struct StringArray {
|
||||
return Error(native::fdb_future_get_string_array(f, &out_strings, &out_count));
|
||||
}
|
||||
};
|
||||
struct NativeKeyValueArray {
|
||||
using Type = std::tuple<native::FDBKeyValue const*, int, bool>;
|
||||
struct KeyValueRef : native::FDBKeyValue {
|
||||
fdb::KeyRef key() const noexcept { return fdb::KeyRef(native::FDBKeyValue::key, key_length); }
|
||||
fdb::ValueRef value() const noexcept { return fdb::ValueRef(native::FDBKeyValue::value, value_length); }
|
||||
};
|
||||
struct KeyValueRefArray {
|
||||
using Type = std::tuple<KeyValueRef const*, int, bool>;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
auto& [out_kv, out_count, out_more] = out;
|
||||
auto out_more_native = native::fdb_bool_t{};
|
||||
auto err = native::fdb_future_get_keyvalue_array(f, &out_kv, &out_count, &out_more_native);
|
||||
auto err = native::fdb_future_get_keyvalue_array(
|
||||
f, reinterpret_cast<const native::FDBKeyValue**>(&out_kv), &out_count, &out_more_native);
|
||||
out_more = (out_more_native != 0);
|
||||
return Error(err);
|
||||
}
|
||||
};
|
||||
struct KeyValueArray {
|
||||
using Type = std::pair<std::vector<KeyValue>, bool>;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
NativeKeyValueArray::Type native_out{};
|
||||
auto err = NativeKeyValueArray::extract(f, native_out);
|
||||
auto [kvs, count, more] = native_out;
|
||||
|
||||
auto& [out_kv, out_more] = out;
|
||||
out_more = more;
|
||||
out_kv.clear();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
fdb::native::FDBKeyValue nativeKv = *kvs++;
|
||||
KeyValue kv;
|
||||
kv.key = fdb::Key(nativeKv.key, nativeKv.key_length);
|
||||
kv.value = fdb::Value(nativeKv.value, nativeKv.value_length);
|
||||
out_kv.push_back(kv);
|
||||
}
|
||||
return Error(err);
|
||||
}
|
||||
struct KeyRangeRef : native::FDBKeyRange {
|
||||
fdb::KeyRef beginKey() const noexcept { return fdb::KeyRef(native::FDBKeyRange::begin_key, begin_key_length); }
|
||||
fdb::KeyRef endKey() const noexcept { return fdb::KeyRef(native::FDBKeyRange::end_key, end_key_length); }
|
||||
};
|
||||
struct NativeKeyRangeArray {
|
||||
using Type = std::tuple<native::FDBKeyRange const*, int>;
|
||||
struct KeyRangeRefArray {
|
||||
using Type = std::tuple<KeyRangeRef const*, int>;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
auto& [out_kv, out_count] = out;
|
||||
auto err = native::fdb_future_get_keyrange_array(f, &out_kv, &out_count);
|
||||
return Error(err);
|
||||
}
|
||||
};
|
||||
struct KeyRangeArray {
|
||||
using Type = std::vector<KeyRange>;
|
||||
static Error extract(native::FDBFuture* f, Type& out) noexcept {
|
||||
NativeKeyRangeArray::Type native_out{};
|
||||
auto err = NativeKeyRangeArray::extract(f, native_out);
|
||||
auto [ranges, count] = native_out;
|
||||
out.clear();
|
||||
for (int i = 0; i < count; ++i) {
|
||||
fdb::native::FDBKeyRange nativeKr = *ranges++;
|
||||
KeyRange range;
|
||||
range.beginKey = fdb::Key(nativeKr.begin_key, nativeKr.begin_key_length);
|
||||
range.endKey = fdb::Key(nativeKr.end_key, nativeKr.end_key_length);
|
||||
out.push_back(range);
|
||||
}
|
||||
auto& [out_ranges, out_count] = out;
|
||||
auto err = native::fdb_future_get_keyrange_array(
|
||||
f, reinterpret_cast<const native::FDBKeyRange**>(&out_ranges), &out_count);
|
||||
return Error(err);
|
||||
}
|
||||
};
|
||||
@ -331,18 +283,19 @@ class Result {
|
||||
}
|
||||
|
||||
public:
|
||||
using NativeKeyValueArray = future_var::NativeKeyValueArray::Type;
|
||||
using KeyValueRefArray = future_var::KeyValueRefArray::Type;
|
||||
|
||||
Error getKeyValueArrayNothrow(NativeKeyValueArray& out) const noexcept {
|
||||
Error getKeyValueArrayNothrow(KeyValueRefArray& out) const noexcept {
|
||||
auto out_more_native = native::fdb_bool_t{};
|
||||
auto& [out_kv, out_count, out_more] = out;
|
||||
auto err_raw = native::fdb_result_get_keyvalue_array(r.get(), &out_kv, &out_count, &out_more_native);
|
||||
auto err_raw = native::fdb_result_get_keyvalue_array(
|
||||
r.get(), reinterpret_cast<const native::FDBKeyValue**>(&out_kv), &out_count, &out_more_native);
|
||||
out_more = out_more_native != 0;
|
||||
return Error(err_raw);
|
||||
}
|
||||
|
||||
NativeKeyValueArray getKeyValueArray() const {
|
||||
auto ret = NativeKeyValueArray{};
|
||||
KeyValueRefArray getKeyValueArray() const {
|
||||
auto ret = KeyValueRefArray{};
|
||||
if (auto err = getKeyValueArrayNothrow(ret))
|
||||
throwError("ERROR: result_get_keyvalue_array(): ", err);
|
||||
return ret;
|
||||
@ -352,8 +305,7 @@ public:
|
||||
class Future {
|
||||
protected:
|
||||
friend class Transaction;
|
||||
friend struct FutureHash;
|
||||
friend struct FutureEquals;
|
||||
friend std::hash<Future>;
|
||||
std::shared_ptr<native::FDBFuture> f;
|
||||
|
||||
Future(native::FDBFuture* future) {
|
||||
@ -361,6 +313,8 @@ protected:
|
||||
f = std::shared_ptr<native::FDBFuture>(future, &native::fdb_future_destroy);
|
||||
}
|
||||
|
||||
native::FDBFuture* nativeHandle() const noexcept { return f.get(); }
|
||||
|
||||
// wrap any capturing lambda as callback passable to fdb_future_set_callback().
|
||||
// destroy after invocation.
|
||||
template <class Fn>
|
||||
@ -434,14 +388,9 @@ public:
|
||||
void then(UserFunc&& fn) {
|
||||
then<Future>(std::forward<UserFunc>(fn));
|
||||
}
|
||||
};
|
||||
|
||||
struct FutureHash {
|
||||
size_t operator()(const Future& f) const { return std::hash<native::FDBFuture*>{}(f.f.get()); }
|
||||
};
|
||||
|
||||
struct FutureEquals {
|
||||
bool operator()(const Future& a, const Future& b) const { return a.f.get() == b.f.get(); }
|
||||
bool operator==(const Future& other) const { return nativeHandle() == other.nativeHandle(); }
|
||||
bool operator!=(const Future& other) const { return !(*this == other); }
|
||||
};
|
||||
|
||||
template <typename VarTraits>
|
||||
@ -566,24 +515,24 @@ public:
|
||||
return out;
|
||||
}
|
||||
|
||||
TypedFuture<future_var::Key> getKey(KeySelector sel, bool snapshot) {
|
||||
TypedFuture<future_var::KeyRef> getKey(KeySelector sel, bool snapshot) {
|
||||
return native::fdb_transaction_get_key(tr.get(), sel.key, sel.keyLength, sel.orEqual, sel.offset, snapshot);
|
||||
}
|
||||
|
||||
TypedFuture<future_var::OptionalValue> get(KeyRef key, bool snapshot) {
|
||||
TypedFuture<future_var::ValueRef> get(KeyRef key, bool snapshot) {
|
||||
return native::fdb_transaction_get(tr.get(), key.data(), intSize(key), snapshot);
|
||||
}
|
||||
|
||||
// Usage: tx.getRange(key_select::firstGreaterOrEqual(firstKey), key_select::lastLessThan(lastKey), ...)
|
||||
// gets key-value pairs in key range [begin, end)
|
||||
TypedFuture<future_var::KeyValueArray> getRange(KeySelector first,
|
||||
KeySelector last,
|
||||
int limit,
|
||||
int target_bytes,
|
||||
FDBStreamingMode mode,
|
||||
int iteration,
|
||||
bool snapshot,
|
||||
bool reverse) {
|
||||
TypedFuture<future_var::KeyValueRefArray> getRange(KeySelector first,
|
||||
KeySelector last,
|
||||
int limit,
|
||||
int target_bytes,
|
||||
FDBStreamingMode mode,
|
||||
int iteration,
|
||||
bool snapshot,
|
||||
bool reverse) {
|
||||
return native::fdb_transaction_get_range(tr.get(),
|
||||
first.key,
|
||||
first.keyLength,
|
||||
@ -601,7 +550,7 @@ public:
|
||||
reverse);
|
||||
}
|
||||
|
||||
TypedFuture<future_var::KeyRangeArray> getBlobGranuleRanges(KeyRef begin, KeyRef end) {
|
||||
TypedFuture<future_var::KeyRangeRefArray> getBlobGranuleRanges(KeyRef begin, KeyRef end) {
|
||||
return native::fdb_transaction_get_blob_granule_ranges(
|
||||
tr.get(), begin.data(), intSize(begin), end.data(), intSize(end));
|
||||
}
|
||||
@ -687,4 +636,9 @@ public:
|
||||
|
||||
} // namespace fdb
|
||||
|
||||
template <>
|
||||
struct std::hash<fdb::Future> {
|
||||
size_t operator()(const fdb::Future& f) const { return std::hash<fdb::native::FDBFuture*>{}(f.nativeHandle()); }
|
||||
};
|
||||
|
||||
#endif /*FDB_API_HPP*/
|
||||
|
@ -51,7 +51,7 @@ const std::array<Operation, MAX_OP> opTable{
|
||||
},
|
||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||
if (f && !f.error()) {
|
||||
f.get<future_var::NativeValue>();
|
||||
f.get<future_var::ValueRef>();
|
||||
}
|
||||
} } },
|
||||
1,
|
||||
@ -72,7 +72,7 @@ const std::array<Operation, MAX_OP> opTable{
|
||||
},
|
||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||
if (f && !f.error()) {
|
||||
f.get<future_var::NativeKeyValueArray>();
|
||||
f.get<future_var::KeyValueRefArray>();
|
||||
}
|
||||
} } },
|
||||
1,
|
||||
@ -84,7 +84,7 @@ const std::array<Operation, MAX_OP> opTable{
|
||||
},
|
||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||
if (f && !f.error()) {
|
||||
f.get<future_var::NativeValue>();
|
||||
f.get<future_var::ValueRef>();
|
||||
}
|
||||
} } },
|
||||
1,
|
||||
@ -107,7 +107,7 @@ const std::array<Operation, MAX_OP> opTable{
|
||||
},
|
||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||
if (f && !f.error()) {
|
||||
f.get<future_var::NativeKeyValueArray>();
|
||||
f.get<future_var::KeyValueRefArray>();
|
||||
}
|
||||
} } },
|
||||
1,
|
||||
@ -119,7 +119,7 @@ const std::array<Operation, MAX_OP> opTable{
|
||||
},
|
||||
[](Future& f, Transaction&, Arguments const&, ByteString&, ByteString&, ByteString& val) {
|
||||
if (f && !f.error()) {
|
||||
f.get<future_var::NativeValue>();
|
||||
f.get<future_var::ValueRef>();
|
||||
}
|
||||
} },
|
||||
{ StepKind::IMM,
|
||||
@ -257,7 +257,7 @@ const std::array<Operation, MAX_OP> opTable{
|
||||
|
||||
user_context.clear();
|
||||
|
||||
auto out = Result::NativeKeyValueArray{};
|
||||
auto out = Result::KeyValueRefArray{};
|
||||
err = r.getKeyValueArrayNothrow(out);
|
||||
if (!err || err.is(2037 /*blob_granule_not_materialized*/))
|
||||
return Future();
|
||||
|
Loading…
x
Reference in New Issue
Block a user