1 
2 /**
3  *    Copyright (C) 2018-present MongoDB, Inc.
4  *
5  *    This program is free software: you can redistribute it and/or modify
6  *    it under the terms of the Server Side Public License, version 1,
7  *    as published by MongoDB, Inc.
8  *
9  *    This program is distributed in the hope that it will be useful,
10  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
11  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12  *    Server Side Public License for more details.
13  *
14  *    You should have received a copy of the Server Side Public License
15  *    along with this program. If not, see
16  *    <http://www.mongodb.com/licensing/server-side-public-license>.
17  *
18  *    As a special exception, the copyright holders give permission to link the
19  *    code of portions of this program with the OpenSSL library under certain
20  *    conditions as described in each individual source file and distribute
21  *    linked combinations including the program with the OpenSSL library. You
22  *    must comply with the Server Side Public License in all respects for
23  *    all of the code used other than as permitted herein. If you modify file(s)
24  *    with this exception, you may extend this exception to your version of the
25  *    file(s), but you are not obligated to do so. If you do not wish to do so,
26  *    delete this exception statement from your version. If you delete this
27  *    exception statement from all source files in the program, then also delete
28  *    it in the license file.
29  */
30 
31 #pragma once
32 
33 #include "mongo/bson/bsonelement.h"
34 #include "mongo/bson/util/builder.h"
35 #include "mongo/db/namespace_string.h"
36 #include "mongo/db/storage/storage_options.h"
37 #include "mongo/stdx/mutex.h"
38 
39 namespace mongo {
40 
41 /**
42  * A KVPrefix may be prepended to the keys of entries in an underlying KV store. Prefixing keys as
43  * such allows multiple MongoDB collections share an underlying table. This can be a beneficial
44  * tradeoff for workloads that create many collections.
45  */
46 class KVPrefix {
47 public:
48     // Represents a table that is not grouped and should not have its keys prefixed.
49     static const KVPrefix kNotPrefixed;
50 
isPrefixed()51     bool isPrefixed() const {
52         return _value >= 0;
53     }
54 
toBSONValue()55     int64_t toBSONValue() const {
56         return _value;
57     }
58 
repr()59     int64_t repr() const {
60         return _value;
61     }
62 
63     std::string toString() const;
64 
65     inline bool operator<(const KVPrefix& rhs) const {
66         return _value < rhs._value;
67     }
68 
69     inline bool operator==(const KVPrefix& rhs) const {
70         return _value == rhs._value;
71     }
72 
73     inline bool operator!=(const KVPrefix& rhs) const {
74         return _value != rhs._value;
75     }
76 
77     static KVPrefix fromBSONElement(const BSONElement value);
78 
79     static void setLargestPrefix(KVPrefix largestPrefix);
80 
81     /**
82      * Returns 'KVPrefix::kNotPrefixed' if 'storageGlobalParams.groupCollections' is false or the
83      * input 'ns' is a namespace disallowed for grouping. Otherwise returns the next 'KVPrefix'
84      * ensuring it is unique with respect to active collections and indexes.
85      */
86     static KVPrefix getNextPrefix(const NamespaceString& ns);
87 
88     /**
89      * Unconditionally returns a new prefix. Only useful for testing.
90      */
91     static KVPrefix generateNextPrefix();
92 
93 private:
KVPrefix(int64_t value)94     explicit KVPrefix(int64_t value) : _value(value) {}
95     int64_t _value;
96 
97     static stdx::mutex _nextValueMutex;
98     static int64_t _nextValue;
99 };
100 
101 inline std::ostream& operator<<(std::ostream& s, const KVPrefix& prefix) {
102     return (s << prefix.toString());
103 }
104 }
105