If VERSION_VECTOR_UNICAST is enabled, one tLog's DV may advance beyond the min(DV) over all tLogs. This function finds the highest recoverable version for each tLog group over all log groups. All prior versions to the chosen RV must also be recoverable. TODO: unit tests to stress UNICAST
| 2004 | // All prior versions to the chosen RV must also be recoverable. |
| 2005 | // TODO: unit tests to stress UNICAST |
| 2006 | Version getRecoverVersionUnicast(std::vector<std::tuple<int, std::vector<TLogLockResult>>>& logGroupResults, |
| 2007 | Version minEnd) { |
| 2008 | Version minLogGroup = std::numeric_limits<Version>::max(); |
| 2009 | for (auto& logGroupResult : logGroupResults) { |
| 2010 | std::unordered_map<Version, int> versionRepCount; |
| 2011 | std::map<Version, int> versionTLogCount; |
| 2012 | int replicationFactor = std::get<0>(logGroupResult); |
| 2013 | for (auto& tLogResult : std::get<1>(logGroupResult)) { |
| 2014 | bool logGroupCandidate = false; |
| 2015 | for (auto& unknownCommittedVersion : tLogResult.unknownCommittedVersions) { |
| 2016 | Version k = std::get<0>(unknownCommittedVersion); |
| 2017 | if (k > minEnd) { |
| 2018 | versionRepCount[k]++; |
| 2019 | versionTLogCount[k] = std::get<1>(unknownCommittedVersion); |
| 2020 | logGroupCandidate = true; |
| 2021 | } |
| 2022 | } |
| 2023 | if (!logGroupCandidate) { |
| 2024 | return minEnd; |
| 2025 | } |
| 2026 | } |
| 2027 | Version minTLogs = minEnd; |
| 2028 | for (auto const& [version, tLogCount] : versionTLogCount) { |
| 2029 | if (versionRepCount[version] >= tLogCount - replicationFactor + 1) { |
| 2030 | minTLogs = version; |
| 2031 | } else { |
| 2032 | break; |
| 2033 | } |
| 2034 | } |
| 2035 | minLogGroup = std::min(minLogGroup, minTLogs); |
| 2036 | } |
| 2037 | return minLogGroup; |
| 2038 | } |
| 2039 | |
| 2040 | ACTOR Future<Void> TagPartitionedLogSystem::epochEnd(Reference<AsyncVar<Reference<ILogSystem>>> outLogSystem, |
| 2041 | UID dbgid, |