xref: /5.5.2/kv_engine/include/memcached/dockey.h (revision f3cb0722)
1 /*
2  *     Copyright 2016 Couchbase, Inc
3  *
4  *   Licensed under the Apache License, Version 2.0 (the "License");
5  *   you may not use this file except in compliance with the License.
6  *   You may obtain a copy of the License at
7  *
8  *       http://www.apache.org/licenses/LICENSE-2.0
9  *
10  *   Unless required by applicable law or agreed to in writing, software
11  *   distributed under the License is distributed on an "AS IS" BASIS,
12  *   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  *   See the License for the specific language governing permissions and
14  *   limitations under the License.
15  */
16 
17 #pragma once
18 
19 #include <cstdint>
20 #include <cstring>
21 
22 #include <platform/sized_buffer.h>
23 
24 /**
25  * DocNamespace "Document Namespace"
26  * Meta-data that applies to every document stored in an engine.
27  *
28  * A document "key" with the flag DefaultCollection is not the same document
29  * as "key" with the Collections flag and so on...
30  *
31  * DefaultCollection: describes "legacy" documents stored in a bucket by
32  * clients that do not understand collections.
33  *
34  * Collections: describes documents that have a collection name as part of
35  * the key. E.g. "planet::earth" and "planet::mars" are documents belonging
36  * to a "planet" collection.
37  *
38  * System: describes documents that are created by the system for our own
39  * uses. This is only planned for use with the collection feature where
40  * special keys are interleaved in the users data stream to represent create
41  * and delete events. In future more generic "system documents" maybe
42  * created by the core but until such plans are more clear, ep-engine will
43  * deny the core from performing operations in the System DocNamespace.
44  * DocNamespace values are persisted ot the database and thus are fully
45  * described now ready for future use.
46  */
47 enum class DocNamespace : uint8_t {
48     DefaultCollection = 0,
49     Collections = 1,
50     System = 2
51 };
52 
53 template <class T>
54 struct DocKeyInterface {
sizeDocKeyInterface55     size_t size() const {
56         return static_cast<const T*>(this)->size();
57     }
58 
dataDocKeyInterface59     const uint8_t* data() const {
60         return static_cast<const T*>(this)->data();
61     }
62 
getDocNamespaceDocKeyInterface63     DocNamespace getDocNamespace() const {
64         return static_cast<const T*>(this)->getDocNamespace();
65     }
66 
hashDocKeyInterface67     uint32_t hash() const {
68         return hash(size());
69     }
70 
71 protected:
hashDocKeyInterface72     uint32_t hash(size_t bytes) const {
73         uint32_t h = 5381;
74 
75         h = ((h << 5) + h) ^ uint32_t(getDocNamespace());
76 
77         for (size_t i = 0; i < bytes; i++) {
78             h = ((h << 5) + h) ^ uint32_t(data()[i]);
79         }
80 
81         return h;
82     }
83 };
84 
85 /**
86  * DocKey is a non-owning structure used to describe a document keys over
87  * the engine-API. All API commands working with "keys" must specify the
88  * data, length and the namespace with which the document applies to.
89  */
90 struct DocKey : DocKeyInterface<DocKey> {
91     /**
92      * Standard constructor - creates a view onto key/nkey
93      */
DocKeyDocKey94     DocKey(const uint8_t* key, size_t nkey, DocNamespace ins)
95         : buffer(key, nkey), doc_namespace(ins) {
96     }
97 
98     /**
99      * C-string constructor - only for use with null terminated strings and
100      * creates a view onto key/strlen(key).
101      */
DocKeyDocKey102     DocKey(const char* key, DocNamespace ins)
103         : DocKey(reinterpret_cast<const uint8_t*>(key), std::strlen(key), ins) {
104     }
105 
106     /**
107      * const_char_buffer constructor, views the data()/size() of the key
108      */
DocKeyDocKey109     DocKey(const cb::const_char_buffer& key, DocNamespace ins)
110         : DocKey(reinterpret_cast<const uint8_t*>(key.data()),
111                  key.size(),
112                  ins) {
113     }
114 
115     /**
116      * Disallow rvalue strings as we would view something which would soon be
117      * out of scope.
118      */
119     DocKey(const std::string&& key, DocNamespace ins) = delete;
120 
121     template <class T>
DocKeyDocKey122     DocKey(const DocKeyInterface<T>& key) {
123         buffer.len = key.size();
124         buffer.buf = key.data();
125         doc_namespace = key.getDocNamespace();
126     }
127 
dataDocKey128     const uint8_t* data() const {
129         return buffer.data();
130     }
131 
sizeDocKey132     size_t size() const {
133         return buffer.size();
134     }
135 
getDocNamespaceDocKey136     DocNamespace getDocNamespace() const {
137         return doc_namespace;
138     }
139 
140 private:
141     cb::const_byte_buffer buffer;
142     DocNamespace doc_namespace;
143 };
144