2017-05-26 04:48:44 +08:00
|
|
|
/*
|
|
|
|
* DatabaseConfiguration.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.
|
|
|
|
*/
|
|
|
|
|
2018-04-09 12:24:05 +08:00
|
|
|
#ifndef FDBCLIENT_DATABASECONFIGURATION_H
|
|
|
|
#define FDBCLIENT_DATABASECONFIGURATION_H
|
2017-05-26 04:48:44 +08:00
|
|
|
#pragma once
|
|
|
|
|
|
|
|
#include "fdbclient/FDBTypes.h"
|
|
|
|
#include "fdbclient/CommitTransaction.h"
|
|
|
|
#include "fdbrpc/ReplicationPolicy.h"
|
2018-03-06 11:27:46 +08:00
|
|
|
#include "fdbclient/Status.h"
|
2017-05-26 04:48:44 +08:00
|
|
|
|
|
|
|
// SOMEDAY: Buggify DatabaseConfiguration
|
|
|
|
|
2018-03-06 11:27:46 +08:00
|
|
|
struct SatelliteInfo {
|
|
|
|
Key dcId;
|
|
|
|
int32_t priority;
|
2019-10-17 05:55:02 +08:00
|
|
|
int32_t satelliteDesiredTLogCount = -1;
|
2018-03-06 11:27:46 +08:00
|
|
|
|
2019-10-17 06:11:24 +08:00
|
|
|
SatelliteInfo() : priority(0) {}
|
2018-03-06 11:27:46 +08:00
|
|
|
|
|
|
|
struct sort_by_priority {
|
2021-03-11 02:06:03 +08:00
|
|
|
bool operator()(SatelliteInfo const& a, SatelliteInfo const& b) const { return a.priority > b.priority; }
|
2018-03-06 11:27:46 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class Ar>
|
|
|
|
void serialize(Ar& ar) {
|
2019-10-15 09:30:15 +08:00
|
|
|
serializer(ar, dcId, priority, satelliteDesiredTLogCount);
|
2018-03-06 11:27:46 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
|
|
|
struct RegionInfo {
|
|
|
|
Key dcId;
|
|
|
|
int32_t priority;
|
|
|
|
|
2019-03-14 04:14:39 +08:00
|
|
|
Reference<IReplicationPolicy> satelliteTLogPolicy;
|
2020-12-16 06:42:07 +08:00
|
|
|
|
|
|
|
// Number of tLogs that should be recruited in satellite datacenters.
|
2018-03-06 11:27:46 +08:00
|
|
|
int32_t satelliteDesiredTLogCount;
|
2020-12-16 06:42:07 +08:00
|
|
|
|
|
|
|
// Total number of copies made for each mutation across all satellite tLogs in all DCs.
|
2018-03-06 11:27:46 +08:00
|
|
|
int32_t satelliteTLogReplicationFactor;
|
2020-12-16 06:42:07 +08:00
|
|
|
|
|
|
|
// Number of tLog replies we can ignore when waiting for quorum. Hence, effective quorum is
|
|
|
|
// satelliteDesiredTLogCount - satelliteTLogWriteAntiQuorum. Locality of individual tLogs is not taken
|
|
|
|
// into account.
|
2018-03-06 11:27:46 +08:00
|
|
|
int32_t satelliteTLogWriteAntiQuorum;
|
2020-12-16 06:42:07 +08:00
|
|
|
|
|
|
|
// Number of satellite datacenters for current region, as set by `satellite_redundancy_mode`.
|
2018-03-06 11:27:46 +08:00
|
|
|
int32_t satelliteTLogUsableDcs;
|
|
|
|
|
2019-03-14 04:14:39 +08:00
|
|
|
Reference<IReplicationPolicy> satelliteTLogPolicyFallback;
|
2018-06-29 14:15:32 +08:00
|
|
|
int32_t satelliteTLogReplicationFactorFallback;
|
|
|
|
int32_t satelliteTLogWriteAntiQuorumFallback;
|
|
|
|
int32_t satelliteTLogUsableDcsFallback;
|
|
|
|
|
2018-03-06 11:27:46 +08:00
|
|
|
std::vector<SatelliteInfo> satellites;
|
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
RegionInfo()
|
|
|
|
: priority(0), satelliteDesiredTLogCount(-1), satelliteTLogReplicationFactor(0), satelliteTLogWriteAntiQuorum(0),
|
|
|
|
satelliteTLogUsableDcs(1), satelliteTLogReplicationFactorFallback(0), satelliteTLogWriteAntiQuorumFallback(0),
|
|
|
|
satelliteTLogUsableDcsFallback(0) {}
|
2018-03-06 11:27:46 +08:00
|
|
|
|
|
|
|
struct sort_by_priority {
|
2020-12-16 06:42:07 +08:00
|
|
|
bool operator()(RegionInfo const& a, RegionInfo const& b) const { return a.priority > b.priority; }
|
2018-03-06 11:27:46 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
template <class Ar>
|
|
|
|
void serialize(Ar& ar) {
|
2021-03-11 02:06:03 +08:00
|
|
|
serializer(ar,
|
|
|
|
dcId,
|
|
|
|
priority,
|
|
|
|
satelliteTLogPolicy,
|
|
|
|
satelliteDesiredTLogCount,
|
|
|
|
satelliteTLogReplicationFactor,
|
|
|
|
satelliteTLogWriteAntiQuorum,
|
|
|
|
satelliteTLogUsableDcs,
|
|
|
|
satelliteTLogPolicyFallback,
|
|
|
|
satelliteTLogReplicationFactorFallback,
|
|
|
|
satelliteTLogWriteAntiQuorumFallback,
|
|
|
|
satelliteTLogUsableDcsFallback,
|
|
|
|
satellites);
|
2018-03-06 11:27:46 +08:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2017-05-26 04:48:44 +08:00
|
|
|
struct DatabaseConfiguration {
|
|
|
|
DatabaseConfiguration();
|
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
void applyMutation(MutationRef mutation);
|
|
|
|
bool set(KeyRef key,
|
|
|
|
ValueRef value); // Returns true if a configuration option that requires recovery to take effect is changed
|
|
|
|
bool clear(KeyRangeRef keys);
|
|
|
|
Optional<ValueRef> get(KeyRef key) const;
|
2017-05-26 04:48:44 +08:00
|
|
|
|
|
|
|
bool isValid() const;
|
|
|
|
|
|
|
|
bool initialized;
|
|
|
|
|
|
|
|
std::string toString() const;
|
2018-03-06 11:27:46 +08:00
|
|
|
StatusObject toJSON(bool noPolicies = false) const;
|
2019-02-19 06:54:28 +08:00
|
|
|
StatusArray getRegionJSON() const;
|
2020-12-16 06:42:07 +08:00
|
|
|
|
|
|
|
RegionInfo getRegion(Optional<Key> dcId) const {
|
|
|
|
if (!dcId.present()) {
|
2018-03-06 11:27:46 +08:00
|
|
|
return RegionInfo();
|
|
|
|
}
|
2020-12-16 06:42:07 +08:00
|
|
|
for (auto& r : regions) {
|
|
|
|
if (r.dcId == dcId.get()) {
|
2018-03-06 11:27:46 +08:00
|
|
|
return r;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return RegionInfo();
|
|
|
|
}
|
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
int expectedLogSets(Optional<Key> dcId) const {
|
2017-09-08 06:32:08 +08:00
|
|
|
int result = 1;
|
2020-12-16 06:42:07 +08:00
|
|
|
if (dcId.present() && getRegion(dcId.get()).satelliteTLogReplicationFactor > 0 && usableRegions > 1) {
|
2017-09-08 06:32:08 +08:00
|
|
|
result++;
|
|
|
|
}
|
2020-12-16 06:42:07 +08:00
|
|
|
|
|
|
|
if (usableRegions > 1) {
|
2017-09-08 06:32:08 +08:00
|
|
|
result++;
|
|
|
|
}
|
|
|
|
return result;
|
|
|
|
}
|
2017-05-26 04:48:44 +08:00
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
// Counts the number of DCs required including remote and satellites for current database configuraiton.
|
2018-02-16 10:32:39 +08:00
|
|
|
int32_t minDatacentersRequired() const {
|
2018-03-06 11:27:46 +08:00
|
|
|
int minRequired = 0;
|
2020-12-16 06:42:07 +08:00
|
|
|
for (auto& r : regions) {
|
2018-03-06 11:27:46 +08:00
|
|
|
minRequired += 1 + r.satellites.size();
|
|
|
|
}
|
|
|
|
return minRequired;
|
|
|
|
}
|
2020-12-16 06:42:07 +08:00
|
|
|
|
2019-07-31 05:02:31 +08:00
|
|
|
int32_t minZonesRequiredPerDatacenter() const {
|
2020-12-16 06:42:07 +08:00
|
|
|
int minRequired = std::max(remoteTLogReplicationFactor, std::max(tLogReplicationFactor, storageTeamSize));
|
|
|
|
for (auto& r : regions) {
|
|
|
|
minRequired =
|
|
|
|
std::max(minRequired, r.satelliteTLogReplicationFactor / std::max(1, r.satelliteTLogUsableDcs));
|
2018-03-06 11:27:46 +08:00
|
|
|
}
|
2018-06-29 14:15:32 +08:00
|
|
|
return minRequired;
|
2018-02-16 10:32:39 +08:00
|
|
|
}
|
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
// Retuns the maximum number of discrete failures a cluster can tolerate.
|
2021-03-30 06:10:57 +08:00
|
|
|
// In HA mode, `fullyReplicatedRegions` is set to "1" initially when data is being
|
2021-03-18 06:45:12 +08:00
|
|
|
// replicated to remote, and will be incremented later. `forAvailablity` is set to true
|
2020-12-16 06:42:07 +08:00
|
|
|
// if we want to account the number for machines that can recruit new tLogs/SS after failures.
|
2021-03-18 06:45:12 +08:00
|
|
|
// Killing an entire datacenter counts as killing one zone in modes that support it.
|
2020-10-01 09:04:23 +08:00
|
|
|
int32_t maxZoneFailuresTolerated(int fullyReplicatedRegions, bool forAvailability) const {
|
2021-03-18 06:45:12 +08:00
|
|
|
int worstSatelliteTLogReplicationFactor = regions.size() ? std::numeric_limits<int>::max() : 0;
|
2020-10-01 09:04:23 +08:00
|
|
|
int regionsWithNonNegativePriority = 0;
|
2020-12-16 06:42:07 +08:00
|
|
|
for (auto& r : regions) {
|
|
|
|
if (r.priority >= 0) {
|
2020-10-01 09:04:23 +08:00
|
|
|
regionsWithNonNegativePriority++;
|
|
|
|
}
|
2021-03-18 06:45:12 +08:00
|
|
|
worstSatelliteTLogReplicationFactor = std::min(
|
|
|
|
worstSatelliteTLogReplicationFactor, r.satelliteTLogReplicationFactor - r.satelliteTLogWriteAntiQuorum);
|
2020-12-16 06:42:07 +08:00
|
|
|
if (r.satelliteTLogUsableDcsFallback > 0) {
|
2021-03-18 06:45:12 +08:00
|
|
|
worstSatelliteTLogReplicationFactor =
|
|
|
|
std::min(worstSatelliteTLogReplicationFactor,
|
|
|
|
r.satelliteTLogReplicationFactorFallback - r.satelliteTLogWriteAntiQuorumFallback);
|
2018-06-29 14:15:32 +08:00
|
|
|
}
|
2018-03-06 11:27:46 +08:00
|
|
|
}
|
2021-03-18 06:45:12 +08:00
|
|
|
|
|
|
|
if (worstSatelliteTLogReplicationFactor <= 0) {
|
|
|
|
// HA is not enabled in this database. Return single cluster zone failures to tolerate.
|
|
|
|
return std::min(tLogReplicationFactor - 1 - tLogWriteAntiQuorum, storageTeamSize - 1);
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compute HA enabled database zone failure tolerance.
|
|
|
|
auto isGeoReplicatedData = [this, &fullyReplicatedRegions]() {
|
|
|
|
return usableRegions > 1 && fullyReplicatedRegions > 1;
|
|
|
|
};
|
|
|
|
|
|
|
|
if (isGeoReplicatedData() && (!forAvailability || regionsWithNonNegativePriority > 1)) {
|
|
|
|
return 1 + std::min(std::max(tLogReplicationFactor - 1 - tLogWriteAntiQuorum,
|
|
|
|
worstSatelliteTLogReplicationFactor - 1),
|
2020-12-16 06:42:07 +08:00
|
|
|
storageTeamSize - 1);
|
2018-02-16 10:32:39 +08:00
|
|
|
}
|
2021-03-18 06:45:12 +08:00
|
|
|
// Primary and Satellite tLogs are synchronously replicated, hence we can lose all but 1.
|
|
|
|
return std::min(tLogReplicationFactor + worstSatelliteTLogReplicationFactor - 1 - tLogWriteAntiQuorum,
|
|
|
|
storageTeamSize - 1);
|
2018-02-16 10:32:39 +08:00
|
|
|
}
|
2017-05-26 04:48:44 +08:00
|
|
|
|
2020-09-11 08:44:15 +08:00
|
|
|
// CommitProxy Servers
|
|
|
|
int32_t commitProxyCount;
|
|
|
|
int32_t autoCommitProxyCount;
|
2020-08-06 15:01:57 +08:00
|
|
|
int32_t grvProxyCount;
|
|
|
|
int32_t autoGrvProxyCount;
|
2020-07-15 15:37:41 +08:00
|
|
|
|
2017-05-26 04:48:44 +08:00
|
|
|
// Resolvers
|
|
|
|
int32_t resolverCount;
|
|
|
|
int32_t autoResolverCount;
|
|
|
|
|
|
|
|
// TLogs
|
2019-03-14 04:14:39 +08:00
|
|
|
Reference<IReplicationPolicy> tLogPolicy;
|
2017-05-26 04:48:44 +08:00
|
|
|
int32_t desiredTLogCount;
|
|
|
|
int32_t autoDesiredTLogCount;
|
|
|
|
int32_t tLogWriteAntiQuorum;
|
|
|
|
int32_t tLogReplicationFactor;
|
2019-02-23 04:15:23 +08:00
|
|
|
TLogVersion tLogVersion;
|
2017-05-26 04:48:44 +08:00
|
|
|
KeyValueStoreType tLogDataStoreType;
|
2019-02-08 09:02:46 +08:00
|
|
|
TLogSpillType tLogSpillType;
|
2017-05-26 04:48:44 +08:00
|
|
|
|
2017-09-08 06:32:08 +08:00
|
|
|
// Storage Servers
|
2019-03-14 04:14:39 +08:00
|
|
|
Reference<IReplicationPolicy> storagePolicy;
|
2017-05-26 04:48:44 +08:00
|
|
|
int32_t storageTeamSize;
|
|
|
|
KeyValueStoreType storageServerStoreType;
|
|
|
|
|
2021-03-06 03:28:15 +08:00
|
|
|
// Testing StorageServers
|
|
|
|
int32_t desiredTSSCount;
|
|
|
|
KeyValueStoreType testingStorageServerStoreType;
|
|
|
|
|
2017-09-08 06:32:08 +08:00
|
|
|
// Remote TLogs
|
2018-06-22 15:04:00 +08:00
|
|
|
int32_t desiredLogRouterCount;
|
2018-06-19 01:22:34 +08:00
|
|
|
int32_t remoteDesiredTLogCount;
|
2017-09-08 06:32:08 +08:00
|
|
|
int32_t remoteTLogReplicationFactor;
|
2019-03-14 04:14:39 +08:00
|
|
|
Reference<IReplicationPolicy> remoteTLogPolicy;
|
2017-09-08 06:32:08 +08:00
|
|
|
|
2020-01-28 05:14:52 +08:00
|
|
|
// Backup Workers
|
2020-02-05 02:09:16 +08:00
|
|
|
bool backupWorkerEnabled;
|
2020-01-28 05:14:52 +08:00
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
// Data centers
|
2021-03-11 02:06:03 +08:00
|
|
|
int32_t usableRegions; // Number of regions which have a replica of the database.
|
2018-07-04 13:59:04 +08:00
|
|
|
int32_t repopulateRegionAntiQuorum;
|
2018-03-06 11:27:46 +08:00
|
|
|
std::vector<RegionInfo> regions;
|
2017-09-08 06:32:08 +08:00
|
|
|
|
2021-05-11 08:05:08 +08:00
|
|
|
// Perpetual Storage Setting
|
|
|
|
int32_t perpetualStorageWiggleSpeed;
|
2021-09-11 06:33:17 +08:00
|
|
|
std::string perpetualStorageWiggleLocality;
|
2021-05-11 08:05:08 +08:00
|
|
|
|
2021-09-08 07:26:43 +08:00
|
|
|
// Storage Migration Type
|
|
|
|
StorageMigrationType storageMigrationType;
|
|
|
|
|
2017-05-26 04:48:44 +08:00
|
|
|
// Excluded servers (no state should be here)
|
2020-12-16 06:42:07 +08:00
|
|
|
bool isExcludedServer(NetworkAddressList) const;
|
2021-05-19 14:48:04 +08:00
|
|
|
bool isExcludedLocality(const LocalityData& locality) const;
|
|
|
|
bool isMachineExcluded(const LocalityData& locality) const;
|
2017-05-26 04:48:44 +08:00
|
|
|
std::set<AddressExclusion> getExcludedServers() const;
|
2021-05-19 14:48:04 +08:00
|
|
|
std::set<std::string> getExcludedLocalities() const;
|
2017-05-26 04:48:44 +08:00
|
|
|
|
2020-09-11 08:44:15 +08:00
|
|
|
int32_t getDesiredCommitProxies() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (commitProxyCount == -1)
|
|
|
|
return autoCommitProxyCount;
|
2020-09-11 08:44:15 +08:00
|
|
|
return commitProxyCount;
|
|
|
|
}
|
2020-08-06 15:01:57 +08:00
|
|
|
int32_t getDesiredGrvProxies() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (grvProxyCount == -1)
|
|
|
|
return autoGrvProxyCount;
|
2020-08-06 15:01:57 +08:00
|
|
|
return grvProxyCount;
|
|
|
|
}
|
2020-12-16 06:42:07 +08:00
|
|
|
int32_t getDesiredResolvers() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (resolverCount == -1)
|
|
|
|
return autoResolverCount;
|
2020-12-16 06:42:07 +08:00
|
|
|
return resolverCount;
|
|
|
|
}
|
|
|
|
int32_t getDesiredLogs() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (desiredTLogCount == -1)
|
|
|
|
return autoDesiredTLogCount;
|
2020-12-16 06:42:07 +08:00
|
|
|
return desiredTLogCount;
|
|
|
|
}
|
|
|
|
int32_t getDesiredRemoteLogs() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (remoteDesiredTLogCount == -1)
|
|
|
|
return getDesiredLogs();
|
2020-12-16 06:42:07 +08:00
|
|
|
return remoteDesiredTLogCount;
|
|
|
|
}
|
|
|
|
int32_t getDesiredSatelliteLogs(Optional<Key> dcId) const {
|
2018-03-06 11:27:46 +08:00
|
|
|
auto desired = getRegion(dcId).satelliteDesiredTLogCount;
|
2021-03-11 02:06:03 +08:00
|
|
|
if (desired == -1)
|
|
|
|
return autoDesiredTLogCount;
|
2020-12-16 06:42:07 +08:00
|
|
|
return desired;
|
|
|
|
}
|
|
|
|
int32_t getRemoteTLogReplicationFactor() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (remoteTLogReplicationFactor == 0)
|
|
|
|
return tLogReplicationFactor;
|
2020-12-16 06:42:07 +08:00
|
|
|
return remoteTLogReplicationFactor;
|
|
|
|
}
|
|
|
|
Reference<IReplicationPolicy> getRemoteTLogPolicy() const {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (remoteTLogReplicationFactor == 0)
|
|
|
|
return tLogPolicy;
|
2020-12-16 06:42:07 +08:00
|
|
|
return remoteTLogPolicy;
|
2018-03-06 11:27:46 +08:00
|
|
|
}
|
2017-05-26 04:48:44 +08:00
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
bool operator==(DatabaseConfiguration const& rhs) const {
|
2017-05-26 04:48:44 +08:00
|
|
|
const_cast<DatabaseConfiguration*>(this)->makeConfigurationImmutable();
|
|
|
|
const_cast<DatabaseConfiguration*>(&rhs)->makeConfigurationImmutable();
|
|
|
|
return rawConfiguration == rhs.rawConfiguration;
|
|
|
|
}
|
2020-07-11 05:37:47 +08:00
|
|
|
bool operator!=(DatabaseConfiguration const& rhs) const { return !(*this == rhs); }
|
2017-05-26 04:48:44 +08:00
|
|
|
|
|
|
|
template <class Ar>
|
|
|
|
void serialize(Ar& ar) {
|
2021-03-11 02:06:03 +08:00
|
|
|
if (!ar.isDeserializing)
|
|
|
|
makeConfigurationImmutable();
|
2018-12-29 02:49:26 +08:00
|
|
|
serializer(ar, rawConfiguration);
|
2017-05-26 04:48:44 +08:00
|
|
|
if (ar.isDeserializing) {
|
2021-03-11 02:06:03 +08:00
|
|
|
for (auto c = rawConfiguration.begin(); c != rawConfiguration.end(); ++c)
|
|
|
|
setInternal(c->key, c->value);
|
2018-02-16 10:32:39 +08:00
|
|
|
setDefaultReplicationPolicy();
|
2017-05-26 04:48:44 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-08-07 13:30:30 +08:00
|
|
|
void fromKeyValues(Standalone<VectorRef<KeyValueRef>> rawConfig);
|
2017-05-26 04:48:44 +08:00
|
|
|
|
|
|
|
private:
|
2020-12-16 06:42:07 +08:00
|
|
|
Optional<std::map<std::string, std::string>> mutableConfiguration; // If present, rawConfiguration is not valid
|
|
|
|
Standalone<VectorRef<KeyValueRef>> rawConfiguration; // sorted by key
|
2017-05-26 04:48:44 +08:00
|
|
|
|
|
|
|
void makeConfigurationMutable();
|
|
|
|
void makeConfigurationImmutable();
|
|
|
|
|
2020-12-16 06:42:07 +08:00
|
|
|
bool setInternal(KeyRef key, ValueRef value);
|
2017-05-26 04:48:44 +08:00
|
|
|
void resetInternal();
|
|
|
|
void setDefaultReplicationPolicy();
|
2020-08-07 13:30:30 +08:00
|
|
|
|
2020-08-09 14:17:14 +08:00
|
|
|
/// Check if the key is overridden by either mutableConfiguration or rawConfiguration
|
|
|
|
bool isOverridden(std::string key) const;
|
2017-05-26 04:48:44 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif
|