2017-05-26 04:48:44 +08:00
/*
* LogSystemConfig . h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013 - 2018 Apple Inc . and the FoundationDB project authors
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* Licensed under the Apache License , Version 2.0 ( the " License " ) ;
* you may not use this file except in compliance with the License .
* You may obtain a copy of the License at
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* http : //www.apache.org/licenses/LICENSE-2.0
2018-02-22 02:25:11 +08:00
*
2017-05-26 04:48:44 +08:00
* Unless required by applicable law or agreed to in writing , software
* distributed under the License is distributed on an " AS IS " BASIS ,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND , either express or implied .
* See the License for the specific language governing permissions and
* limitations under the License .
*/
# ifndef FDBSERVER_LOGSYSTEMCONFIG_H
# define FDBSERVER_LOGSYSTEMCONFIG_H
# pragma once
2019-06-01 07:14:58 +08:00
# include "fdbserver/BackupInterface.h"
2018-10-20 01:30:13 +08:00
# include "fdbserver/TLogInterface.h"
2017-05-26 04:48:44 +08:00
# include "fdbrpc/ReplicationPolicy.h"
2018-04-09 12:24:05 +08:00
# include "fdbclient/DatabaseConfiguration.h"
2017-05-26 04:48:44 +08:00
template < class Interface >
struct OptionalInterface {
2019-08-01 07:51:35 +08:00
friend struct serializable_traits < OptionalInterface < Interface > > ;
2017-05-26 04:48:44 +08:00
// Represents an interface with a known id() and possibly known actual endpoints.
// For example, an OptionalInterface<TLogInterface> represents a particular tlog by id, which you might or might not presently know how to communicate with
UID id ( ) const { return ident ; }
bool present ( ) const { return iface . present ( ) ; }
Interface const & interf ( ) const { return iface . get ( ) ; }
explicit OptionalInterface ( UID id ) : ident ( id ) { }
explicit OptionalInterface ( Interface const & i ) : ident ( i . id ( ) ) , iface ( i ) { }
OptionalInterface ( ) { }
std : : string toString ( ) const { return ident . toString ( ) ; }
bool operator = = ( UID const & r ) const { return ident = = r ; }
template < class Ar >
void serialize ( Ar & ar ) {
2018-12-29 02:49:26 +08:00
serializer ( ar , iface ) ;
if ( ! iface . present ( ) ) serializer ( ar , ident ) ;
2017-05-26 04:48:44 +08:00
else ident = iface . get ( ) . id ( ) ;
}
protected :
UID ident ;
Optional < Interface > iface ;
} ;
2019-04-12 02:36:24 +08:00
class LogSet ;
2019-04-19 04:41:37 +08:00
struct OldLogData ;
2019-04-12 02:36:24 +08:00
2019-01-29 11:38:13 +08:00
template < class Interface >
struct serializable_traits < OptionalInterface < Interface > > : std : : true_type {
template < class Archiver >
static void serialize ( Archiver & ar , OptionalInterface < Interface > & m ) {
if constexpr ( ! Archiver : : isDeserializing ) {
if ( m . iface . present ( ) ) {
m . ident = m . iface . get ( ) . id ( ) ;
}
}
: : serializer ( ar , m . iface , m . ident ) ;
if constexpr ( Archiver : : isDeserializing ) {
if ( m . iface . present ( ) ) {
m . ident = m . iface . get ( ) . id ( ) ;
}
}
}
} ;
2020-12-16 06:42:07 +08:00
// Contains a generation of tLogs for an individual DC.
2017-07-10 05:46:16 +08:00
struct TLogSet {
2019-04-10 05:29:21 +08:00
constexpr static FileIdentifier file_identifier = 6302317 ;
2017-07-10 05:46:16 +08:00
std : : vector < OptionalInterface < TLogInterface > > tLogs ;
2017-07-11 08:41:32 +08:00
std : : vector < OptionalInterface < TLogInterface > > logRouters ;
2019-05-16 07:13:04 +08:00
std : : vector < OptionalInterface < BackupInterface > > backupWorkers ;
2017-05-26 04:48:44 +08:00
int32_t tLogWriteAntiQuorum , tLogReplicationFactor ;
std : : vector < LocalityData > tLogLocalities ; // Stores the localities of the log servers
2019-02-27 08:47:04 +08:00
TLogVersion tLogVersion ;
2019-03-14 04:14:39 +08:00
Reference < IReplicationPolicy > tLogPolicy ;
2017-07-10 05:46:16 +08:00
bool isLocal ;
2018-03-30 06:12:38 +08:00
int8_t locality ;
Version startVersion ;
2018-06-17 08:39:02 +08:00
std : : vector < std : : vector < int > > satelliteTagLocations ;
2017-05-26 04:48:44 +08:00
2018-06-16 03:36:19 +08:00
TLogSet ( ) : tLogWriteAntiQuorum ( 0 ) , tLogReplicationFactor ( 0 ) , isLocal ( true ) , locality ( tagLocalityInvalid ) , startVersion ( invalidVersion ) { }
2019-04-12 02:36:24 +08:00
explicit TLogSet ( const LogSet & rhs ) ;
2017-05-26 04:48:44 +08:00
std : : string toString ( ) const {
2020-01-04 02:22:41 +08:00
return format ( " anti: %d replication: %d local: %d routers: %d tLogs: %s backupWorkers: %s locality: %d " ,
2019-05-16 07:13:04 +08:00
tLogWriteAntiQuorum , tLogReplicationFactor , isLocal , logRouters . size ( ) , describe ( tLogs ) . c_str ( ) ,
2020-01-04 02:22:41 +08:00
describe ( backupWorkers ) . c_str ( ) , locality ) ;
2017-07-10 05:46:16 +08:00
}
2017-05-26 04:48:44 +08:00
2017-07-10 05:46:16 +08:00
bool operator = = ( const TLogSet & rhs ) const {
2019-05-16 07:13:04 +08:00
if ( tLogWriteAntiQuorum ! = rhs . tLogWriteAntiQuorum | | tLogReplicationFactor ! = rhs . tLogReplicationFactor | |
isLocal ! = rhs . isLocal | | satelliteTagLocations ! = rhs . satelliteTagLocations | |
startVersion ! = rhs . startVersion | | tLogs . size ( ) ! = rhs . tLogs . size ( ) | | locality ! = rhs . locality | |
logRouters . size ( ) ! = rhs . logRouters . size ( ) | | backupWorkers . size ( ) ! = rhs . backupWorkers . size ( ) ) {
2017-07-10 05:46:16 +08:00
return false ;
2017-05-26 04:48:44 +08:00
}
2017-07-10 05:46:16 +08:00
if ( ( tLogPolicy & & ! rhs . tLogPolicy ) | | ( ! tLogPolicy & & rhs . tLogPolicy ) | | ( tLogPolicy & & ( tLogPolicy - > info ( ) ! = rhs . tLogPolicy - > info ( ) ) ) ) {
return false ;
2017-05-26 04:48:44 +08:00
}
2017-07-10 05:46:16 +08:00
for ( int j = 0 ; j < tLogs . size ( ) ; j + + ) {
if ( tLogs [ j ] . id ( ) ! = rhs . tLogs [ j ] . id ( ) | | tLogs [ j ] . present ( ) ! = rhs . tLogs [ j ] . present ( ) | | ( tLogs [ j ] . present ( ) & & tLogs [ j ] . interf ( ) . commit . getEndpoint ( ) . token ! = rhs . tLogs [ j ] . interf ( ) . commit . getEndpoint ( ) . token ) ) {
return false ;
}
2017-05-26 04:48:44 +08:00
}
2018-04-13 06:20:54 +08:00
for ( int j = 0 ; j < logRouters . size ( ) ; j + + ) {
if ( logRouters [ j ] . id ( ) ! = rhs . logRouters [ j ] . id ( ) | | logRouters [ j ] . present ( ) ! = rhs . logRouters [ j ] . present ( ) | | ( logRouters [ j ] . present ( ) & & logRouters [ j ] . interf ( ) . commit . getEndpoint ( ) . token ! = rhs . logRouters [ j ] . interf ( ) . commit . getEndpoint ( ) . token ) ) {
return false ;
}
}
2019-05-16 07:13:04 +08:00
for ( int j = 0 ; j < backupWorkers . size ( ) ; j + + ) {
if ( backupWorkers [ j ] . id ( ) ! = rhs . backupWorkers [ j ] . id ( ) | |
backupWorkers [ j ] . present ( ) ! = rhs . backupWorkers [ j ] . present ( ) | |
( backupWorkers [ j ] . present ( ) & &
backupWorkers [ j ] . interf ( ) . getToken ( ) ! = rhs . backupWorkers [ j ] . interf ( ) . getToken ( ) ) ) {
return false ;
}
}
2017-07-10 05:46:16 +08:00
return true ;
}
bool isEqualIds ( TLogSet const & r ) const {
2018-06-17 08:39:02 +08:00
if ( tLogWriteAntiQuorum ! = r . tLogWriteAntiQuorum | | tLogReplicationFactor ! = r . tLogReplicationFactor | | isLocal ! = r . isLocal | | satelliteTagLocations ! = r . satelliteTagLocations | |
2019-04-19 04:41:37 +08:00
startVersion ! = r . startVersion | | tLogs . size ( ) ! = r . tLogs . size ( ) | | locality ! = r . locality ) {
2017-07-10 05:46:16 +08:00
return false ;
2017-05-26 04:48:44 +08:00
}
2017-07-10 05:46:16 +08:00
if ( ( tLogPolicy & & ! r . tLogPolicy ) | | ( ! tLogPolicy & & r . tLogPolicy ) | | ( tLogPolicy & & ( tLogPolicy - > info ( ) ! = r . tLogPolicy - > info ( ) ) ) ) {
return false ;
2017-06-30 06:50:19 +08:00
}
2017-07-10 05:46:16 +08:00
for ( int i = 0 ; i < tLogs . size ( ) ; i + + ) {
if ( tLogs [ i ] . id ( ) ! = r . tLogs [ i ] . id ( ) ) {
return false ;
2017-05-26 04:48:44 +08:00
}
}
2017-07-10 05:46:16 +08:00
return true ;
2017-05-26 04:48:44 +08:00
}
template < class Ar >
void serialize ( Ar & ar ) {
2020-01-17 13:21:25 +08:00
serializer ( ar , tLogs , logRouters , tLogWriteAntiQuorum , tLogReplicationFactor , tLogPolicy , tLogLocalities ,
isLocal , locality , startVersion , satelliteTagLocations , tLogVersion , backupWorkers ) ;
2017-07-10 05:46:16 +08:00
}
} ;
struct OldTLogConf {
2019-04-10 05:29:21 +08:00
constexpr static FileIdentifier file_identifier = 16233772 ;
2017-07-10 05:46:16 +08:00
std : : vector < TLogSet > tLogs ;
2019-10-02 04:38:52 +08:00
Version epochBegin , epochEnd ;
2018-04-09 12:24:05 +08:00
int32_t logRouterTags ;
2019-06-29 03:33:24 +08:00
int32_t txsTags ;
2019-07-30 10:17:10 +08:00
std : : set < int8_t > pseudoLocalities ; // Tracking pseudo localities, e.g., tagLocalityLogRouterMapped, used in the old epoch.
2019-06-01 07:14:58 +08:00
LogEpoch epoch ;
2017-07-10 05:46:16 +08:00
2019-10-02 04:38:52 +08:00
OldTLogConf ( ) : epochBegin ( 0 ) , epochEnd ( 0 ) , logRouterTags ( 0 ) , txsTags ( 0 ) , epoch ( 0 ) { }
2019-04-19 04:41:37 +08:00
explicit OldTLogConf ( const OldLogData & ) ;
2017-07-10 05:46:16 +08:00
std : : string toString ( ) const {
2019-01-29 11:38:13 +08:00
return format ( " end: %d tags: %d %s " , epochEnd , logRouterTags , describe ( tLogs ) . c_str ( ) ) ;
2017-07-10 05:46:16 +08:00
}
2019-10-02 04:38:52 +08:00
bool operator = = ( const OldTLogConf & rhs ) const {
return tLogs = = rhs . tLogs & & epochBegin = = rhs . epochBegin & & epochEnd = = rhs . epochEnd & &
logRouterTags = = rhs . logRouterTags & & txsTags = = rhs . txsTags & &
pseudoLocalities = = rhs . pseudoLocalities & & epoch = = rhs . epoch ;
2017-07-10 05:46:16 +08:00
}
bool isEqualIds ( OldTLogConf const & r ) const {
if ( tLogs . size ( ) ! = r . tLogs . size ( ) ) {
return false ;
}
for ( int i = 0 ; i < tLogs . size ( ) ; i + + ) {
if ( ! tLogs [ i ] . isEqualIds ( r . tLogs [ i ] ) ) {
return false ;
2017-06-30 06:50:19 +08:00
}
2017-05-26 04:48:44 +08:00
}
2017-07-10 05:46:16 +08:00
return true ;
2017-05-26 04:48:44 +08:00
}
template < class Ar >
void serialize ( Ar & ar ) {
2019-10-02 04:38:52 +08:00
serializer ( ar , tLogs , epochBegin , epochEnd , logRouterTags , pseudoLocalities , txsTags , epoch ) ;
2017-05-26 04:48:44 +08:00
}
} ;
2019-07-30 10:17:10 +08:00
// LogSystemType is always 2 (tagPartitioned). There is no other tag partitioned system.
// This type is supposed to be removed. However, because the serialized value of the type is stored in coordinators,
// removing it is complex in order to support forward and backward compatibility.
2019-04-09 05:45:16 +08:00
enum class LogSystemType {
2019-07-30 10:17:10 +08:00
empty = 0 , // Never used.
2019-04-09 05:45:16 +08:00
tagPartitioned = 2 ,
} ;
2017-05-26 04:48:44 +08:00
struct LogSystemConfig {
2019-04-10 05:29:21 +08:00
constexpr static FileIdentifier file_identifier = 16360847 ;
2019-04-09 05:45:16 +08:00
LogSystemType logSystemType ;
2017-07-10 05:46:16 +08:00
std : : vector < TLogSet > tLogs ;
2018-04-09 12:24:05 +08:00
int32_t logRouterTags ;
2019-06-29 03:33:24 +08:00
int32_t txsTags ;
2017-05-26 04:48:44 +08:00
std : : vector < OldTLogConf > oldTLogs ;
2018-04-09 12:24:05 +08:00
int32_t expectedLogSets ;
2018-04-21 04:25:22 +08:00
UID recruitmentID ;
2018-05-06 08:56:00 +08:00
bool stopped ;
2018-06-27 09:20:28 +08:00
Optional < Version > recoveredAt ;
2019-04-11 01:30:34 +08:00
std : : set < int8_t > pseudoLocalities ;
2019-06-01 07:14:58 +08:00
LogEpoch epoch ;
2019-08-15 08:00:20 +08:00
LogEpoch oldestBackupEpoch ;
2017-05-26 04:48:44 +08:00
2019-06-01 07:14:58 +08:00
LogSystemConfig ( LogEpoch e = 0 )
2019-08-15 08:00:20 +08:00
: logSystemType ( LogSystemType : : empty ) , logRouterTags ( 0 ) , txsTags ( 0 ) , expectedLogSets ( 0 ) , stopped ( false ) , epoch ( e ) ,
oldestBackupEpoch ( e ) { }
2017-05-26 04:48:44 +08:00
2018-06-27 09:20:28 +08:00
std : : string toString ( ) const {
2018-04-09 12:24:05 +08:00
return format ( " type: %d oldGenerations: %d tags: %d %s " , logSystemType , oldTLogs . size ( ) , logRouterTags , describe ( tLogs ) . c_str ( ) ) ;
2017-07-10 05:46:16 +08:00
}
2017-05-26 04:48:44 +08:00
2020-01-11 04:21:08 +08:00
Optional < Key > getRemoteDcId ( ) const {
for ( int i = 0 ; i < tLogs . size ( ) ; i + + ) {
if ( ! tLogs [ i ] . isLocal ) {
for ( int j = 0 ; j < tLogs [ i ] . tLogs . size ( ) ; j + + ) {
if ( tLogs [ i ] . tLogs [ j ] . present ( ) ) {
2020-04-18 08:47:50 +08:00
return tLogs [ i ] . tLogs [ j ] . interf ( ) . filteredLocality . dcId ( ) ;
2020-01-11 04:21:08 +08:00
}
}
}
}
return Optional < Key > ( ) ;
}
2019-07-16 09:25:16 +08:00
std : : vector < TLogInterface > allLocalLogs ( bool includeSatellite = true ) const {
2018-05-30 01:51:23 +08:00
std : : vector < TLogInterface > results ;
for ( int i = 0 ; i < tLogs . size ( ) ; i + + ) {
2019-07-16 09:25:16 +08:00
// skip satellite TLogs, if it was not needed
if ( ! includeSatellite & & tLogs [ i ] . locality = = tagLocalitySatellite ) {
continue ;
}
2018-05-30 01:51:23 +08:00
if ( tLogs [ i ] . isLocal ) {
for ( int j = 0 ; j < tLogs [ i ] . tLogs . size ( ) ; j + + ) {
if ( tLogs [ i ] . tLogs [ j ] . present ( ) ) {
results . push_back ( tLogs [ i ] . tLogs [ j ] . interf ( ) ) ;
}
}
}
}
return results ;
}
2017-05-26 04:48:44 +08:00
std : : vector < TLogInterface > allPresentLogs ( ) const {
std : : vector < TLogInterface > results ;
2017-07-10 05:46:16 +08:00
for ( int i = 0 ; i < tLogs . size ( ) ; i + + ) {
for ( int j = 0 ; j < tLogs [ i ] . tLogs . size ( ) ; j + + ) {
if ( tLogs [ i ] . tLogs [ j ] . present ( ) ) {
results . push_back ( tLogs [ i ] . tLogs [ j ] . interf ( ) ) ;
}
}
}
2017-05-26 04:48:44 +08:00
return results ;
}
2019-02-22 08:52:27 +08:00
std : : pair < int8_t , int8_t > getLocalityForDcId ( Optional < Key > dcId ) const {
2018-09-29 03:21:08 +08:00
std : : map < int8_t , int > matchingLocalities ;
std : : map < int8_t , int > allLocalities ;
for ( auto & tLogSet : tLogs ) {
for ( auto & tLog : tLogSet . tLogs ) {
2019-02-23 06:02:34 +08:00
if ( tLogSet . locality > = 0 ) {
2020-04-18 08:47:50 +08:00
if ( tLog . present ( ) & & tLog . interf ( ) . filteredLocality . dcId ( ) = = dcId ) {
2018-09-29 03:21:08 +08:00
matchingLocalities [ tLogSet . locality ] + + ;
} else {
allLocalities [ tLogSet . locality ] + + ;
}
}
}
}
for ( auto & oldLog : oldTLogs ) {
for ( auto & tLogSet : oldLog . tLogs ) {
for ( auto & tLog : tLogSet . tLogs ) {
2019-02-23 06:02:34 +08:00
if ( tLogSet . locality > = 0 ) {
2020-04-18 08:47:50 +08:00
if ( tLog . present ( ) & & tLog . interf ( ) . filteredLocality . dcId ( ) = = dcId ) {
2018-09-29 03:21:08 +08:00
matchingLocalities [ tLogSet . locality ] + + ;
} else {
allLocalities [ tLogSet . locality ] + + ;
}
}
}
}
}
2019-02-22 08:52:27 +08:00
int8_t bestLoc = tagLocalityInvalid ;
int bestLocalityCount = - 1 ;
for ( auto & it : matchingLocalities ) {
if ( it . second > bestLocalityCount ) {
bestLoc = it . first ;
bestLocalityCount = it . second ;
2018-09-29 03:21:08 +08:00
}
}
2019-02-22 08:52:27 +08:00
int8_t secondLoc = tagLocalityInvalid ;
int8_t thirdLoc = tagLocalityInvalid ;
int secondLocalityCount = - 1 ;
int thirdLocalityCount = - 1 ;
for ( auto & it : allLocalities ) {
if ( bestLoc ! = it . first ) {
if ( it . second > secondLocalityCount ) {
thirdLoc = secondLoc ;
thirdLocalityCount = secondLocalityCount ;
secondLoc = it . first ;
secondLocalityCount = it . second ;
} else if ( it . second > thirdLocalityCount ) {
thirdLoc = it . first ;
thirdLocalityCount = it . second ;
2018-09-29 03:21:08 +08:00
}
}
}
2019-02-22 08:52:27 +08:00
if ( bestLoc ! = tagLocalityInvalid ) {
return std : : make_pair ( bestLoc , secondLoc ) ;
}
2019-02-23 06:02:34 +08:00
return std : : make_pair ( secondLoc , thirdLoc ) ;
2018-09-29 03:21:08 +08:00
}
2018-03-03 08:50:30 +08:00
std : : vector < std : : pair < UID , NetworkAddress > > allSharedLogs ( ) const {
typedef std : : pair < UID , NetworkAddress > IdAddrPair ;
std : : vector < IdAddrPair > results ;
2018-03-06 07:18:14 +08:00
for ( auto & tLogSet : tLogs ) {
for ( auto & tLog : tLogSet . tLogs ) {
if ( tLog . present ( ) )
results . push_back ( IdAddrPair ( tLog . interf ( ) . getSharedTLogID ( ) , tLog . interf ( ) . address ( ) ) ) ;
}
2018-03-03 09:56:49 +08:00
}
2018-03-03 08:50:30 +08:00
for ( auto & oldLog : oldTLogs ) {
2018-03-06 07:18:14 +08:00
for ( auto & tLogSet : oldLog . tLogs ) {
for ( auto & tLog : tLogSet . tLogs ) {
if ( tLog . present ( ) )
results . push_back ( IdAddrPair ( tLog . interf ( ) . getSharedTLogID ( ) , tLog . interf ( ) . address ( ) ) ) ;
}
2018-03-03 08:50:30 +08:00
}
}
uniquify ( results ) ;
// This assert depends on the fact that uniquify will sort the elements based on <UID, NetworkAddr> order
ASSERT_WE_THINK ( std : : unique ( results . begin ( ) , results . end ( ) , [ ] ( IdAddrPair & x , IdAddrPair & y ) { return x . first = = y . first ; } ) = = results . end ( ) ) ;
return results ;
}
2017-05-26 04:48:44 +08:00
bool operator = = ( const LogSystemConfig & rhs ) const { return isEqual ( rhs ) ; }
bool isEqual ( LogSystemConfig const & r ) const {
2019-06-01 07:14:58 +08:00
return logSystemType = = r . logSystemType & & tLogs = = r . tLogs & & oldTLogs = = r . oldTLogs & &
2019-08-15 08:00:20 +08:00
expectedLogSets = = r . expectedLogSets & & logRouterTags = = r . logRouterTags & & txsTags = = r . txsTags & &
recruitmentID = = r . recruitmentID & & stopped = = r . stopped & & recoveredAt = = r . recoveredAt & &
pseudoLocalities = = r . pseudoLocalities & & epoch = = r . epoch & & oldestBackupEpoch = = r . oldestBackupEpoch ;
2017-05-26 04:48:44 +08:00
}
bool isEqualIds ( LogSystemConfig const & r ) const {
2017-10-25 06:09:31 +08:00
for ( auto & i : r . tLogs ) {
for ( auto & j : tLogs ) {
if ( i . isEqualIds ( j ) ) {
return true ;
}
2017-05-26 04:48:44 +08:00
}
}
2017-10-25 06:09:31 +08:00
return false ;
2017-05-26 04:48:44 +08:00
}
bool isNextGenerationOf ( LogSystemConfig const & r ) const {
2017-10-25 06:09:31 +08:00
if ( ! oldTLogs . size ( ) ) {
2017-05-26 04:48:44 +08:00
return false ;
}
2017-10-25 06:09:31 +08:00
for ( auto & i : r . tLogs ) {
2019-04-02 04:56:45 +08:00
for ( auto & j : oldTLogs [ 0 ] . tLogs ) {
2017-10-25 06:09:31 +08:00
if ( i . isEqualIds ( j ) ) {
return true ;
}
2017-07-10 05:46:16 +08:00
}
2017-06-30 06:50:19 +08:00
}
2017-10-25 06:09:31 +08:00
return false ;
2017-05-26 04:48:44 +08:00
}
2019-05-30 05:45:34 +08:00
bool hasTLog ( UID tid ) const {
for ( const auto & log : tLogs ) {
if ( std : : count ( log . tLogs . begin ( ) , log . tLogs . end ( ) , tid ) > 0 ) {
return true ;
}
}
for ( const auto & old : oldTLogs ) {
for ( const auto & log : old . tLogs ) {
if ( std : : count ( log . tLogs . begin ( ) , log . tLogs . end ( ) , tid ) > 0 ) {
return true ;
}
}
}
return false ;
}
bool hasLogRouter ( UID rid ) const {
for ( const auto & log : tLogs ) {
if ( std : : count ( log . logRouters . begin ( ) , log . logRouters . end ( ) , rid ) > 0 ) {
return true ;
}
}
for ( const auto & old : oldTLogs ) {
for ( const auto & log : old . tLogs ) {
if ( std : : count ( log . logRouters . begin ( ) , log . logRouters . end ( ) , rid ) > 0 ) {
return true ;
}
}
}
return false ;
}
bool hasBackupWorker ( UID bid ) const {
for ( const auto & log : tLogs ) {
if ( std : : count ( log . backupWorkers . begin ( ) , log . backupWorkers . end ( ) , bid ) > 0 ) {
return true ;
}
}
for ( const auto & old : oldTLogs ) {
for ( const auto & log : old . tLogs ) {
if ( std : : count ( log . backupWorkers . begin ( ) , log . backupWorkers . end ( ) , bid ) > 0 ) {
return true ;
}
}
}
return false ;
}
2019-06-01 07:14:58 +08:00
Version getEpochEndVersion ( LogEpoch epoch ) const {
for ( const auto & old : oldTLogs ) {
if ( old . epoch = = epoch ) {
return old . epochEnd ;
}
}
return invalidVersion ;
}
2017-05-26 04:48:44 +08:00
template < class Ar >
2019-06-01 07:14:58 +08:00
void serialize ( Ar & ar ) {
serializer ( ar , logSystemType , tLogs , logRouterTags , oldTLogs , expectedLogSets , recruitmentID , stopped ,
2019-08-15 08:00:20 +08:00
recoveredAt , pseudoLocalities , txsTags , epoch , oldestBackupEpoch ) ;
2017-05-26 04:48:44 +08:00
}
} ;
# endif