Skip to content

Commit

Permalink
[WIP] GetRangeAndMap support serializable & check RYW
Browse files Browse the repository at this point in the history
  • Loading branch information
nblintao committed Dec 22, 2021
1 parent 6613ec2 commit d493067
Show file tree
Hide file tree
Showing 6 changed files with 244 additions and 81 deletions.
41 changes: 41 additions & 0 deletions fdbclient/FDBTypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -475,6 +475,7 @@ using KeyRange = Standalone<KeyRangeRef>;
using KeyValue = Standalone<KeyValueRef>;
using KeySelector = Standalone<struct KeySelectorRef>;
using RangeResult = Standalone<struct RangeResultRef>;
using RangeAndMapResult = Standalone<struct RangeAndMapResultRef>;

enum { invalidVersion = -1, latestVersion = -2, MAX_VERSION = std::numeric_limits<int64_t>::max() };

Expand Down Expand Up @@ -679,6 +680,46 @@ struct Traceable<RangeResultRef> : std::true_type {
}
};

struct GetValueReqAndResultRef {
KeyRef key;
Optional<ValueRef> result;
template <class Ar>
void serialize(Ar& ar) {
serializer(ar, key, result);
}
};

struct GetRangeReqAndResultRef {
KeySelectorRef begin, end;
RangeResultRef result;
//
// KeyRef key;
// ValueRef value;
// KeyValueRef() {}
// KeyValueRef(const KeyRef& key, const ValueRef& value) : key(key), value(value) {}
// KeyValueRef(Arena& a, const KeyValueRef& copyFrom) : key(a, copyFrom.key), value(a, copyFrom.value) {}
// bool operator==(const KeyValueRef& r) const { return key == r.key && value == r.value; }
// bool operator!=(const KeyValueRef& r) const { return key != r.key || value != r.value; }

template <class Ar>
void serialize(Ar& ar) {
serializer(ar, begin, end, result);
}
};

using ReqAndResultRef = std::variant<GetValueReqAndResultRef, GetRangeReqAndResultRef>;

struct RangeAndMapResultRef : VectorRef<ReqAndResultRef> {
RangeResultRef originalRangeResult; // In addition to metadata (including more, readToBegin, and readThroughEnd), it
// only stores the first and the last result. This is useful for the callers to
// know how far it has reached.
RangeAndMapResultRef() {}
template <class Ar>
void serialize(Ar& ar) {
serializer(ar, ((VectorRef<ReqAndResultRef>&)*this), originalRangeResult);
}
};

struct KeyValueStoreType {
constexpr static FileIdentifier file_identifier = 6560359;
// These enumerated values are stored in the database configuration, so should NEVER be changed.
Expand Down
6 changes: 6 additions & 0 deletions fdbclient/NativeAPI.actor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4594,6 +4594,12 @@ Future<RangeResult> Transaction::getRangeInternal(const KeySelector& begin,
return RangeResult();
}

if (!snapshot && !std::is_same_v<GetKeyValuesFamilyRequest, GetKeyValuesRequest>) {
// Currently, NativeAPI does not support serialization for getRangeAndFlatMap. You should consider use
// ReadYourWrites APIs which wraps around NativeAPI and provides serialization for getRangeAndFlatMap. (Even if
// you don't want RYW, you may use ReadYourWrites APIs with RYW disabled.)
throw unsupported_operation();
}
Promise<std::pair<Key, Key>> conflictRange;
if (!snapshot) {
extraConflictRanges.push_back(conflictRange.getFuture());
Expand Down
29 changes: 26 additions & 3 deletions fdbclient/RYWIterator.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ class RYWIterator {
ExtStringRef beginKey();
ExtStringRef endKey();

const KeyValueRef* kv(Arena& arena);
virtual const KeyValueRef* kv(Arena& arena);

RYWIterator& operator++();

Expand All @@ -61,14 +61,14 @@ class RYWIterator {

void bypassUnreadableProtection() { bypassUnreadable = true; }

WriteMap::iterator& extractWriteMapIterator();
virtual WriteMap::iterator& extractWriteMapIterator();
// Really this should return an iterator by value, but for performance it's convenient to actually grab the internal
// one. Consider copying the return value if performance isn't critical. If you modify the returned iterator, it
// invalidates this iterator until the next call to skip()

void dbg();

private:
protected:
int begin_key_cmp; // -1 if cache.beginKey() < writes.beginKey(), 0 if ==, +1 if >
int end_key_cmp; //
SnapshotCache::iterator cache;
Expand All @@ -80,6 +80,29 @@ class RYWIterator {
void updateCmp();
};

//// Check if the read happen to intersect with the write cache. If that's the case, instead of returning the data in
/// the cache, we throw exception. / It should not actually return any data.
// class ShouldNotReadModifiedRange : RYWIterator {
// public:
// ShouldNotReadModifiedRange(SnapshotCache* snapshotCache, WriteMap* writeMap)
// : RYWIterator(snapshotCache, writeMap) {}
//
// const KeyValueRef* kv(Arena& arena) {
// if (is_unreadable() && !bypassUnreadable)
// throw accessed_unreadable();
//
// if (writes.is_unmodified_range()) {
// return cache.kv(arena);
// }
//
// throw get_range_and_map_reads_your_writes();
// }
//
// WriteMap::iterator& extractWriteMapIterator() {
// throw get_range_and_map_reads_your_writes();
// }
//};

class RandomTestImpl {
public:
static ValueRef getRandomValue(Arena& arena) {
Expand Down
Loading

0 comments on commit d493067

Please sign in to comment.