1 // kv_catalog.h 2 3 4 /** 5 * Copyright (C) 2018-present MongoDB, Inc. 6 * 7 * This program is free software: you can redistribute it and/or modify 8 * it under the terms of the Server Side Public License, version 1, 9 * as published by MongoDB, Inc. 10 * 11 * This program is distributed in the hope that it will be useful, 12 * but WITHOUT ANY WARRANTY; without even the implied warranty of 13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 14 * Server Side Public License for more details. 15 * 16 * You should have received a copy of the Server Side Public License 17 * along with this program. If not, see 18 * <http://www.mongodb.com/licensing/server-side-public-license>. 19 * 20 * As a special exception, the copyright holders give permission to link the 21 * code of portions of this program with the OpenSSL library under certain 22 * conditions as described in each individual source file and distribute 23 * linked combinations including the program with the OpenSSL library. You 24 * must comply with the Server Side Public License in all respects for 25 * all of the code used other than as permitted herein. If you modify file(s) 26 * with this exception, you may extend this exception to your version of the 27 * file(s), but you are not obligated to do so. If you do not wish to do so, 28 * delete this exception statement from your version. If you delete this 29 * exception statement from all source files in the program, then also delete 30 * it in the license file. 31 */ 32 33 #pragma once 34 35 #include <map> 36 #include <memory> 37 #include <string> 38 39 #include "mongo/base/string_data.h" 40 #include "mongo/db/catalog/collection_options.h" 41 #include "mongo/db/record_id.h" 42 #include "mongo/db/storage/bson_collection_catalog_entry.h" 43 #include "mongo/db/storage/kv/kv_prefix.h" 44 #include "mongo/stdx/mutex.h" 45 46 namespace mongo { 47 48 class OperationContext; 49 class RecordStore; 50 51 class KVCatalog { 52 public: 53 class FeatureTracker; 54 55 /** 56 * @param rs - does NOT take ownership. The RecordStore must be thread-safe, in particular 57 * with concurrent calls to RecordStore::find, updateRecord, insertRecord, deleteRecord and 58 * dataFor. The KVCatalog does not utilize Cursors and those methods may omit further 59 * protection. 60 */ 61 KVCatalog(RecordStore* rs, bool directoryPerDb, bool directoryForIndexes); 62 ~KVCatalog(); 63 64 void init(OperationContext* opCtx); 65 66 void getAllCollections(std::vector<std::string>* out) const; 67 68 /** 69 * @return error or ident for instance 70 */ 71 Status newCollection(OperationContext* opCtx, 72 StringData ns, 73 const CollectionOptions& options, 74 KVPrefix prefix); 75 76 std::string getCollectionIdent(StringData ns) const; 77 78 std::string getIndexIdent(OperationContext* opCtx, StringData ns, StringData idName) const; 79 80 const BSONCollectionCatalogEntry::MetaData getMetaData(OperationContext* opCtx, StringData ns); 81 void putMetaData(OperationContext* opCtx, 82 StringData ns, 83 BSONCollectionCatalogEntry::MetaData& md); 84 85 Status renameCollection(OperationContext* opCtx, 86 StringData fromNS, 87 StringData toNS, 88 bool stayTemp); 89 90 Status dropCollection(OperationContext* opCtx, StringData ns); 91 92 std::vector<std::string> getAllIdentsForDB(StringData db) const; 93 std::vector<std::string> getAllIdents(OperationContext* opCtx) const; 94 95 bool isUserDataIdent(StringData ident) const; 96 getFeatureTracker()97 FeatureTracker* getFeatureTracker() const { 98 invariant(_featureTracker); 99 return _featureTracker.get(); 100 } 101 102 std::string getFilesystemPathForDb(const std::string& dbName) const; 103 104 private: 105 class AddIdentChange; 106 class RemoveIdentChange; 107 108 BSONObj _findEntry(OperationContext* opCtx, StringData ns, RecordId* out = NULL) const; 109 110 /** 111 * Generates a new unique identifier for a new "thing". 112 * @param ns - the containing ns 113 * @param kind - what this "thing" is, likely collection or index 114 */ 115 std::string _newUniqueIdent(StringData ns, const char* kind); 116 117 // Helpers only used by constructor and init(). Don't call from elsewhere. 118 static std::string _newRand(); 119 bool _hasEntryCollidingWithRand() const; 120 121 RecordStore* _rs; // not owned 122 const bool _directoryPerDb; 123 const bool _directoryForIndexes; 124 125 // These two are only used for ident generation inside _newUniqueIdent. 126 std::string _rand; // effectively const after init() returns 127 AtomicUInt64 _next; 128 129 struct Entry { EntryEntry130 Entry() {} EntryEntry131 Entry(std::string i, RecordId l) : ident(i), storedLoc(l) {} 132 std::string ident; 133 RecordId storedLoc; 134 }; 135 typedef std::map<std::string, Entry> NSToIdentMap; 136 NSToIdentMap _idents; 137 mutable stdx::mutex _identsLock; 138 139 // Manages the feature document that may be present in the KVCatalog. '_featureTracker' is 140 // guaranteed to be non-null after KVCatalog::init() is called. 141 std::unique_ptr<FeatureTracker> _featureTracker; 142 }; 143 } 144