/**
* Copyright (C) 2008-2015 MongoDB Inc.
*
* This program is free software: you can redistribute it and/or modify
* it under the terms of the GNU Affero General Public License, version 3,
* as published by the Free Software Foundation.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Affero General Public License for more details.
*
* You should have received a copy of the GNU Affero General Public License
* along with this program. If not, see .
*
* As a special exception, the copyright holders give permission to link the
* code of portions of this program with the OpenSSL library under certain
* conditions as described in each individual source file and distribute
* linked combinations including the program with the OpenSSL library. You
* must comply with the GNU Affero General Public License in all respects
* for all of the code used other than as permitted herein. If you modify
* file(s) with this exception, you may extend this exception to your
* version of the file(s), but you are not obligated to do so. If you do not
* wish to do so, delete this exception statement from your version. If you
* delete this exception statement from all source files in the program,
* then also delete it in the license file.
*/
#pragma once
#include
#include "mongo/bson/bsonmisc.h"
#include "mongo/bson/bsonobj.h"
namespace mongo {
class ChunkType;
struct ChunkVersion;
class CatalogManager;
class Query;
/**
* This class manages and applies diffs from partial config server data reloads. Because the
* config data can be large, we want to update it in small parts, not all-at-once. Once a
* ConfigDiffTracker is created, the current config data is *attached* to it, and it is then
* able to modify the data.
*
* The current form is templated b/c the overall algorithm is identical between mongos and
* mongod, but the actual chunk maps used differ in implementation. We don't want to copy the
* implementation, because the logic is identical, or the chunk data, because that would be
* slow for big clusters, so this is the alternative for now.
*
* TODO: Standardize between mongos and mongod and convert template parameters to types.
*/
template
class ConfigDiffTracker {
public:
// Stores ranges indexed by max or min key
typedef typename std::map RangeMap;
// Pair of iterators defining a subset of ranges
typedef
typename std::pair RangeOverlap;
// Map of shard identifiers to the maximum chunk version on that shard
typedef typename std::map MaxChunkVersionMap;
ConfigDiffTracker();
virtual ~ConfigDiffTracker();
/**
* The tracker attaches to a set of ranges with versions, and uses a config server
* connection to update these. Because the set of ranges and versions may be large, they
* aren't owned by the tracker, they're just passed in and updated. Therefore they must all
* stay in scope while the tracker is working.
*
* TODO: Make a standard VersionedRange to encapsulate this info in both mongod and mongos?
*/
void attach(const std::string& ns,
RangeMap& currMap,
ChunkVersion& maxVersion,
MaxChunkVersionMap& maxShardVersions);
// Call after load for more information
int numValidDiffs() const {
return _validDiffs;
}
// Whether or not a range exists in the min/max region
bool isOverlapping(const BSONObj& min, const BSONObj& max);
// Removes all ranges in the region from min/max
void removeOverlapping(const BSONObj& min, const BSONObj& max);
// Returns a subset of ranges overlapping the region min/max
RangeOverlap overlappingRange(const BSONObj& min, const BSONObj& max);
// Finds and applies the changes to a collection from the config servers via
// the catalog manager.
// Also includes minor version changes for particular major-version chunks if explicitly
// specified.
// Returns the number of diffs processed, or -1 if the diffs were inconsistent
// Throws a DBException on connection errors
int calculateConfigDiff(CatalogManager* catalogManager);
// Applies changes to the config data from a vector of chunks passed in
// Returns the number of diffs processed, or -1 if the diffs were inconsistent
// Throws a DBException on connection errors
int calculateConfigDiff(const std::vector& chunks);
// Returns the query needed to find new changes to a collection from the config server
// Needed only if a custom connection is required to the config server
Query configDiffQuery() const;
protected:
// Determines which chunks are actually being remembered by our RangeMap
virtual bool isTracked(const ChunkType& chunk) const = 0;
// Whether or not our RangeMap uses min or max keys
virtual bool isMinKeyIndexed() const {
return true;
}
virtual std::pair rangeFor(const ChunkType& chunk) const = 0;
virtual ShardType shardFor(const std::string& name) const = 0;
private:
void _assertAttached() const;
std::string _ns;
RangeMap* _currMap;
ChunkVersion* _maxVersion;
MaxChunkVersionMap* _maxShardVersions;
// Store for later use
int _validDiffs;
};
} // namespace mongo