diff --git a/Facade.h b/Facade.h index 9c399ee..898ded6 100644 --- a/Facade.h +++ b/Facade.h @@ -53,12 +53,13 @@ struct Facade { do { --iter; auto m = *iter; - const auto mBegin = - weaselab::VersionedMap::Key{m.param1, m.param1Len}; - const auto mEnd = + auto mBegin = weaselab::VersionedMap::Key{m.param1, m.param1Len}; + auto mEnd = m.type == weaselab::VersionedMap::Set || m.param2Len == 0 ? weaselab::VersionedMap::Key{m.param1, m.param1Len + 1} : weaselab::VersionedMap::Key{m.param2, m.param2Len}; + + // Read from unversioned down to mEnd if (unversionedIter != beginIter) { --unversionedIter; for (; unversionedIter->first >= mEnd && limit > 0; @@ -73,6 +74,12 @@ struct Facade { if (limit == 0) { return result; } + + bool pointMutation = + m.type == weaselab::VersionedMap::Set || m.param2Len == 0; + + // Read from versioned until non-adjacent + readVersionedReverse: switch (m.type) { case weaselab::VersionedMap::Set: { result.emplace_back(String(mBegin.p, mBegin.len), @@ -85,7 +92,31 @@ struct Facade { case weaselab::VersionedMap::Clear: break; } - if (m.type == weaselab::VersionedMap::Set || m.param2Len == 0) { + + if (iter != endIter) { + --iter; + auto tmpM = *iter; + const auto tmpMBegin = + weaselab::VersionedMap::Key{tmpM.param1, tmpM.param1Len}; + const auto tmpMEnd = + tmpM.type == weaselab::VersionedMap::Set || tmpM.param2Len == 0 + ? weaselab::VersionedMap::Key{tmpM.param1, + tmpM.param1Len + 1} + : weaselab::VersionedMap::Key{tmpM.param2, tmpM.param2Len}; + if (tmpMEnd >= mBegin) { + // Adjacent with last (temporally) mutation + mBegin = tmpMBegin; + mEnd = tmpMEnd; + m = tmpM; + pointMutation = false; + goto readVersionedReverse; + } else { + ++iter; + } + } + + // Advance unversioned iter + if (pointMutation) { if (unversionedIter != facade->unversioned.end() && unversionedIter->first < mBegin) { ++unversionedIter; @@ -135,7 +166,7 @@ struct Facade { m.type == weaselab::VersionedMap::Set || m.param2Len == 0; // Read from versioned until non-adjacent - readVersioned: + readVersionedForward: switch (m.type) { case weaselab::VersionedMap::Set: { result.emplace_back(String(mBegin.p, mBegin.len), @@ -163,7 +194,7 @@ struct Facade { tmpM.param2Len}; m = tmpM; pointMutation = false; - goto readVersioned; + goto readVersionedForward; } }