Many bug fixes.

This commit is contained in:
Stephen Atherton 2017-08-28 01:57:01 -07:00
parent 1070a5ed66
commit 0fd57e9183
1 changed files with 30 additions and 16 deletions

View File

@ -137,7 +137,7 @@ struct KeyVersionValue {
Version version;
Optional<Value> value;
bool valid() { return version != invalidVersion; }
bool valid() const { return version != invalidVersion; }
inline KeyValue pack() const {
Tuple k;
@ -402,7 +402,7 @@ private:
* without adding an additional key to the buffer.
*/
void printMutationBuffer(MutationBufferT::const_iterator begin, MutationBufferT::const_iterator end) {
void printMutationBuffer(MutationBufferT::const_iterator begin, MutationBufferT::const_iterator end) const {
#if REDWOOD_DEBUG
debug_printf("-------------------------------------\n");
debug_printf("BUFFER\n");
@ -414,7 +414,7 @@ private:
#endif
}
void printMutationBuffer() {
void printMutationBuffer() const {
return printMutationBuffer(m_buffer.begin(), m_buffer.end());
}
@ -447,7 +447,10 @@ private:
// for it in which case we would have returned above.
MutationBufferT::iterator iPrevious = ib;
--iPrevious;
ib->second.rangeClearVersion = iPrevious->second.rangeClearVersion;
if(iPrevious->second.rangeClearVersion.present()) {
ib->second.rangeClearVersion = iPrevious->second.rangeClearVersion;
ib->second.startKeyMutations[iPrevious->second.rangeClearVersion.get()] = SingleKeyMutation();
}
return ib;
}
@ -485,7 +488,7 @@ private:
// Returns list of (version, list of (lower_bound, list of children) )
ACTOR static Future<VersionedChildrenT> commitSubtree(VersionedBTree *self, Reference<IPagerSnapshot> snapshot, LogicalPageID root, Key lowerBoundKey, Key upperBoundKey) {
state std::string printPrefix = format("commit subtree(lowerboundkey %s, page %u) ", lowerBoundKey.toString().c_str(), root);
state std::string printPrefix = format("commit subtree root=%lld lower='%s' upper='%s'", root, printable(lowerBoundKey).c_str(), printable(upperBoundKey).c_str());
debug_printf("%s\n", printPrefix.c_str());
// Decode the upper and lower bound keys for this subtree
@ -509,7 +512,7 @@ private:
// If the mutation buffer key found is greater than the lower bound key then go to the previous mutation
// buffer key because it may cover deletion of some keys at the start of this subtree.
if(iMutationBoundary->first > lowerBoundKVV.key)
if(iMutationBoundary != self->m_buffer.begin() && iMutationBoundary->first > lowerBoundKVV.key)
--iMutationBoundary;
else {
// If the there are no mutations, we're done
@ -552,7 +555,7 @@ private:
if(iExisting != iExistingEnd)
existing = KeyVersionValue::unpack(*iExisting);
// If replacement pages are written they will be at the minimum version seen in the mutations for this leaf
Version minVersion = std::numeric_limits<Version>::max();
Version minVersion = invalidVersion;
// Now, process each mutation range and merge changes with existing data.
while(iMutationBoundary != iMutationBoundaryEnd) {
@ -580,9 +583,10 @@ private:
existing = KeyVersionValue::unpack(*iExisting);
}
// TODO: If a mutation set is equal to the previous existing value of the key, don't write it.
// Output mutations for the mutation boundary start key
while(iMutations != iMutationsEnd) {
if(iMutations->first < minVersion)
if(iMutations->first < minVersion || minVersion == invalidVersion)
minVersion = iMutations->first;
merged.push_back(iMutations->second.toKVV(iMutationBoundary->first, iMutations->first).pack());
debug_printf("Added mutation of boundary start key: %s\n", KeyVersionValue::unpack(merged.back()).toString().c_str());
@ -609,7 +613,10 @@ private:
nextEntry = upperBoundKVV;
if(clearRangeVersion.present() && existing.key != nextEntry.key) {
merged.push_back(KeyVersionValue(existing.key, clearRangeVersion.get()).pack());
Version clearVersion = clearRangeVersion.get();
if(clearVersion < minVersion || minVersion == invalidVersion)
minVersion = clearVersion;
merged.push_back(KeyVersionValue(existing.key, clearVersion).pack());
debug_printf("Added clear of existing key in mutation range: %s\n", KeyVersionValue::unpack(merged.back()).toString().c_str());
}
@ -628,6 +635,11 @@ private:
existing = KeyVersionValue::unpack(*iExisting);
}
// No changes were actually made. This could happen if there is a single-key clear which turns out
// to not actually exist in the leaf page.
if(minVersion == invalidVersion)
return VersionedChildrenT({ {0,{{lowerBoundKey,root}}} });
debug_printf("%s DONE MERGING MUTATIONS WITH EXISTING LEAF CONTENTS\n", printPrefix.c_str());
// TODO: Make version and key splits based on contents of merged list
@ -663,7 +675,9 @@ private:
results.push_back({minVersion, {}});
for(int i=0; i<pages.size(); i++) {
results.back().second.push_back( {merged[pages[i].first].key, logicalPages[i]} );
// The lower bound of the first page is the lower bound of the subtree, not the first entry in the page
Key lowerBound = (i == 0) ? lowerBoundKey : merged[pages[i].first].key;
results.back().second.push_back( {lowerBound, logicalPages[i]} );
}
debug_printf("%s DONE.\n", printPrefix.c_str());
@ -673,12 +687,12 @@ private:
state std::vector<Future<VersionedChildrenT>> m_futureChildren;
for(int i=0; i<map.entries.size(); i++) {
Key currentUpperBound;
if(i + 1 < map.entries.size())
currentUpperBound = map.entries[i].key;
else
currentUpperBound = upperBoundKey;
m_futureChildren.push_back(self->commitSubtree(self, snapshot, *(uint32_t*)map.entries[i].value.begin(), map.entries[i].key, currentUpperBound));
// The lower bound for the first child is lowerBoundKey, and entries[i] for the rest.
Key childLowerBound = (i == 0) ? lowerBoundKey : map.entries[i].key;
// The upper bound for the last child is upperBoundKey, and entries[i+1] for the others.
Key childUpperBound = ( (i + 1) == map.entries.size()) ? upperBoundKey : map.entries[i + 1].key;
m_futureChildren.push_back(self->commitSubtree(self, snapshot, *(uint32_t*)map.entries[i].value.begin(), childLowerBound, childUpperBound));
}
Void _ = wait(waitForAll(m_futureChildren));