Move building of KeyRangeMap out of the loop
So that it is only done once.
This commit is contained in:
parent
a187eeebee
commit
d6dd88c2b9
|
@ -111,37 +111,37 @@ public:
|
|||
}
|
||||
Val const& operator[]( const Key& k ) { return rangeContaining(k).value(); }
|
||||
|
||||
Ranges ranges() { return Ranges( Iterator(map.begin()), Iterator(map.lastItem()) ); }
|
||||
Ranges ranges() const { return Ranges(Iterator(map.begin()), Iterator(map.lastItem())); }
|
||||
// intersectingRanges returns [begin, end] where begin <= r.begin and end >= r.end
|
||||
Ranges intersectingRanges( const Range& r ) { return Ranges(rangeContaining(r.begin), Iterator(map.lower_bound(r.end))); }
|
||||
Ranges intersectingRanges(const Range& r) const {
|
||||
return Ranges(rangeContaining(r.begin), Iterator(map.lower_bound(r.end)));
|
||||
}
|
||||
// containedRanges() will return all ranges that are fully contained by the passed range (note that a range fully contains itself)
|
||||
Ranges containedRanges( const Range& r ) {
|
||||
Ranges containedRanges(const Range& r) const {
|
||||
auto s = Iterator( map.lower_bound( r.begin ) );
|
||||
if ( s.begin() >= r.end ) return Ranges(s,s);
|
||||
return Ranges(s, rangeContaining(r.end));
|
||||
}
|
||||
template <class ComparableToKey>
|
||||
Iterator rangeContaining( const ComparableToKey& k ) {
|
||||
return Iterator(map.lastLessOrEqual(k));
|
||||
Iterator rangeContaining(const ComparableToKey& k) const {
|
||||
return Iterator(map.lastLessOrEqual(k));
|
||||
}
|
||||
// Returns the range containing a key infinitesimally before k, or the first range if k==Key()
|
||||
template <class ComparableToKey>
|
||||
Iterator rangeContainingKeyBefore( const ComparableToKey& k ) {
|
||||
Iterator rangeContainingKeyBefore(const ComparableToKey& k) const {
|
||||
Iterator i = map.lower_bound(k);
|
||||
if ( !i->begin().size() ) return i;
|
||||
--i;
|
||||
return i;
|
||||
}
|
||||
Iterator lastItem() {
|
||||
Iterator lastItem() const {
|
||||
auto i = map.lastItem();
|
||||
i.decrementNonEnd();
|
||||
return Iterator(i);
|
||||
}
|
||||
int size() const { return map.size() - 1; } // We always have one range bounded by two entries
|
||||
Iterator randomRange() {
|
||||
return Iterator( map.index( deterministicRandom()->randomInt(0, map.size()-1) ) );
|
||||
}
|
||||
Iterator nthRange(int n) { return Iterator(map.index(n)); }
|
||||
Iterator randomRange() const { return Iterator(map.index(deterministicRandom()->randomInt(0, map.size() - 1))); }
|
||||
Iterator nthRange(int n) const { return Iterator(map.index(n)); }
|
||||
|
||||
bool allEqual( const Range& r, const Val& v );
|
||||
|
||||
|
|
|
@ -36,8 +36,8 @@
|
|||
typedef std::map<Standalone<StringRef>, std::pair<Standalone<StringRef>, uint32_t>> SerializedMutationListMap;
|
||||
|
||||
std::vector<UID> getApplierIDs(std::map<Key, UID>& rangeToApplier);
|
||||
void splitMutation(std::map<Key, UID>* pRangeToApplier, MutationRef m, Arena& mvector_arena,
|
||||
VectorRef<MutationRef>& mvector, Arena& nodeIDs_arena, VectorRef<UID>& nodeIDs);
|
||||
void splitMutation(const KeyRangeMap<UID>& krMap, MutationRef m, Arena& mvector_arena, VectorRef<MutationRef>& mvector,
|
||||
Arena& nodeIDs_arena, VectorRef<UID>& nodeIDs);
|
||||
void _parseSerializedMutation(KeyRangeMap<Version>* pRangeVersions,
|
||||
std::map<LoadingParam, VersionedMutationsMap>::iterator kvOpsIter,
|
||||
SerializedMutationListMap* mutationMap,
|
||||
|
@ -472,6 +472,19 @@ ACTOR Future<Void> handleSendMutationsRequest(RestoreSendMutationsToAppliersRequ
|
|||
return Void();
|
||||
}
|
||||
|
||||
void buildApplierRangeMap(KeyRangeMap<UID>* krMap, std::map<Key, UID>* pRangeToApplier) {
|
||||
std::map<Key, UID>::iterator beginKey = pRangeToApplier->begin();
|
||||
std::map<Key, UID>::iterator endKey = std::next(beginKey, 1);
|
||||
while (endKey != pRangeToApplier->end()) {
|
||||
krMap->insert(KeyRangeRef(beginKey->first, endKey->first), beginKey->second);
|
||||
beginKey = endKey;
|
||||
endKey++;
|
||||
}
|
||||
if (beginKey != pRangeToApplier->end()) {
|
||||
krMap->insert(KeyRangeRef(beginKey->first, normalKeys.end), beginKey->second);
|
||||
}
|
||||
}
|
||||
|
||||
// Assume: kvOps data are from the same RestoreAsset.
|
||||
// Input: pkvOps: versioned kv mutation for the asset in the version batch (batchIndex)
|
||||
// isRangeFile: is pkvOps from range file? Let receiver (applier) know if the mutation is log mutation;
|
||||
|
@ -516,6 +529,8 @@ ACTOR Future<Void> sendMutationsToApplier(VersionedMutationsMap* pkvOps, int bat
|
|||
for (auto& applierID : applierIDs) {
|
||||
applierVersionedMutationsBuffer[applierID] = VersionedMutationsVec();
|
||||
}
|
||||
KeyRangeMap<UID> krMap;
|
||||
buildApplierRangeMap(&krMap, pRangeToApplier);
|
||||
for (kvOp = kvOps.begin(); kvOp != kvOps.end(); kvOp++) {
|
||||
commitVersion = kvOp->first;
|
||||
ASSERT(commitVersion.version >= asset.beginVersion);
|
||||
|
@ -528,8 +543,7 @@ ACTOR Future<Void> sendMutationsToApplier(VersionedMutationsMap* pkvOps, int bat
|
|||
Standalone<VectorRef<UID>> nodeIDs;
|
||||
// Because using a vector of mutations causes overhead, and the range mutation should happen rarely;
|
||||
// We handle the range mutation and key mutation differently for the benefit of avoiding memory copy
|
||||
splitMutation(pRangeToApplier, kvm, mvector.arena(), mvector.contents(), nodeIDs.arena(),
|
||||
nodeIDs.contents());
|
||||
splitMutation(krMap, kvm, mvector.arena(), mvector.contents(), nodeIDs.arena(), nodeIDs.contents());
|
||||
ASSERT(mvector.size() == nodeIDs.size());
|
||||
|
||||
if (debugMutation("RestoreLoader", commitVersion.version, kvm)) {
|
||||
|
@ -628,22 +642,11 @@ ACTOR Future<Void> sendMutationsToApplier(VersionedMutationsMap* pkvOps, int bat
|
|||
|
||||
// Splits a clear range mutation for Appliers and puts results of splitted mutations and
|
||||
// Applier IDs into "mvector" and "nodeIDs" on return.
|
||||
void splitMutation(std::map<Key, UID>* pRangeToApplier, MutationRef m, Arena& mvector_arena,
|
||||
VectorRef<MutationRef>& mvector, Arena& nodeIDs_arena, VectorRef<UID>& nodeIDs) {
|
||||
void splitMutation(const KeyRangeMap<UID>& krMap, MutationRef m, Arena& mvector_arena, VectorRef<MutationRef>& mvector,
|
||||
Arena& nodeIDs_arena, VectorRef<UID>& nodeIDs) {
|
||||
TraceEvent(SevDebug, "FastRestoreSplitMutation").detail("Mutation", m.toString());
|
||||
ASSERT(mvector.empty());
|
||||
ASSERT(nodeIDs.empty());
|
||||
KeyRangeMap<UID> krMap;
|
||||
std::map<Key, UID>::iterator beginKey = pRangeToApplier->begin();
|
||||
std::map<Key, UID>::iterator endKey = std::next(beginKey, 1);
|
||||
while (endKey != pRangeToApplier->end()) {
|
||||
krMap.insert(KeyRangeRef(beginKey->first, endKey->first), beginKey->second);
|
||||
beginKey = endKey;
|
||||
endKey++;
|
||||
}
|
||||
if (beginKey != pRangeToApplier->end()) {
|
||||
krMap.insert(KeyRangeRef(beginKey->first, normalKeys.end), beginKey->second);
|
||||
}
|
||||
auto r = krMap.intersectingRanges(KeyRangeRef(m.param1, m.param2));
|
||||
for (auto i = r.begin(); i != r.end(); ++i) {
|
||||
// Calculate the overlap range
|
||||
|
|
Loading…
Reference in New Issue