Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
tag: r1.9.0
Fetching contributors…

Octocat-spinner-32-eaf2f5

Cannot retrieve contributors at this time

file 151 lines (125 sloc) 6.586 kb
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150
// @file d_chunk_manager.h

/**
* Copyright (C) 2008 10gen 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 <http://www.gnu.org/licenses/>.
*/

#pragma once

#include "../pch.h"

#include "../db/jsobj.h"
#include "util.h"

namespace mongo {

    /**
* Controls the boundaries of all the chunks for a given collection that live in this shard.
*
* ShardChunkManager instances never change after construction. There are methods provided that would generate a
* new manager if new chunks are added, subtracted, or split.
*
* TODO
* The responsibility of maintaining the version for a shard is still shared between this class and its caller. The
* manager does check corner cases (e.g. cloning out the last chunk generates a manager with version 0) but ultimately
* still cannot be responsible to set all versions. Currently, they are a function of the global state as opposed to
* the per-shard one.
*/
    class ShardChunkManager : public boost::noncopyable {
    public:

        /**
* Loads the ShardChunkManager with all boundaries for chunks of a given collection that live in an given
* shard.
*
* @param configServer name of the server where the configDB currently is. Can be empty to indicate
* that the configDB is running locally
* @param ns namespace for the collections whose chunks we're interested
* @param shardName name of the shard that this chunk matcher should track
*
* This constructor throws if collection is dropped/malformed and on connectivity errors
*/
        ShardChunkManager( const string& configServer , const string& ns , const string& shardName );

        /**
* Same as the regular constructor but used in unittest (no access to configDB required).
*
* @param collectionDoc simulates config.collection's entry for one colleciton
* @param chunksDocs simulates config.chunks' entries for one collection's shard
*/
        ShardChunkManager( const BSONObj& collectionDoc , const BSONArray& chunksDoc );

        ~ShardChunkManager() {}

        /**
* Generates a new manager based on 'this's state minus a given chunk.
*
* @param min max chunk boundaries for the chunk to subtract
* @param version that the resulting manager should be at. The version has to be higher than the current one.
* When cloning away the last chunk, verstion must be 0.
* @return a new ShardChunkManager, to be owned by the caller
*/
        ShardChunkManager* cloneMinus( const BSONObj& min , const BSONObj& max , const ShardChunkVersion& version );

        /**
* Generates a new manager based on 'this's state plus a given chunk.
*
* @param min max chunk boundaries for the chunk to add
* @param version that the resulting manager should be at. It can never be 0, though (see CloneMinus).
* @return a new ShardChunkManager, to be owned by the caller
*/
        ShardChunkManager* clonePlus( const BSONObj& min , const BSONObj& max , const ShardChunkVersion& version );

        /**
* Generates a new manager by splitting an existing chunk at one or more points.
*
* @param min max boundaries of chunk to be split
* @param splitKeys points to split original chunk at
* @param version to be used in first chunk. The subsequent chunks would increment the minor version.
* @return a new ShardChunkManager with the chunk split, to be owned by the caller
*/
        ShardChunkManager* cloneSplit( const BSONObj& min , const BSONObj& max , const vector<BSONObj>& splitKeys ,
                                       const ShardChunkVersion& version );

        /**
* Checks whether a document belongs to this shard.
*
* @param obj document containing sharding keys (and, optionally, other attributes)
* @return true if shards hold the object
*/
        bool belongsToMe( const BSONObj& obj ) const;

        /**
* Given a chunk's min key (or empty doc), gets the boundary of the chunk following that one (the first).
*
* @param lookupKey is the min key for a previously obtained chunk or the empty document
* @param foundMin IN/OUT min for chunk following the one starting at lookupKey
* @param foundMax IN/OUT max for the above chunk
* @return true if the chunk returned is the last one
*/
        bool getNextChunk( const BSONObj& lookupKey, BSONObj* foundMin , BSONObj* foundMax ) const;

        // accessors

        ShardChunkVersion getVersion() const { return _version; }
        BSONObj getKey() const { return _key.getOwned(); }
        unsigned getNumChunks() const { return _chunksMap.size(); }

        string toString() const;
    private:
        // highest ShardChunkVersion for which this ShardChunkManager's information is accurate
        ShardChunkVersion _version;

        // key pattern for chunks under this range
        BSONObj _key;

        // a map from a min key into the chunk's (or range's) max boundary
        typedef map< BSONObj, BSONObj , BSONObjCmp > RangeMap;
        RangeMap _chunksMap;

        // a map from a min key into a range or continguous chunks
        // redundant but we expect high chunk continguity, expecially in small installations
        RangeMap _rangesMap;

        /** constructors helpers */
        void _fillCollectionKey( const BSONObj& collectionDoc );
        void _fillChunks( DBClientCursorInterface* cursor );
        void _fillRanges();

        /** throws if the exact chunk is not in the chunks' map */
        void _assertChunkExists( const BSONObj& min , const BSONObj& max ) const;

        /** can only be used in the cloning calls */
        ShardChunkManager() {}
    };

    typedef shared_ptr<ShardChunkManager> ShardChunkManagerPtr;

} // namespace mongo
Something went wrong with that request. Please try again.