1 /* -*- Mode: C; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3 * Copyright 2016 Couchbase, Inc
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 #include "config.h"
19 #include "nobucket.h"
20
21 #include <cstdlib>
22 #include <stdexcept>
23 #include <string>
24
25 /**
26 * The NoBucket is a bucket that just returns "ENGINE_NO_BUCKET" for "all"
27 * operations. The main purpose for having this bucket is to reduce the
28 * code complexity so we don't have to had checks all over the place to
29 * see if a client is connected to a bucket or not (we may just associate
30 * the connection to this bucket and it'll handle the appropriate
31 * command.
32 */
33 class NoBucket : public ENGINE_HANDLE_V1 {
34 public:
NoBucket()35 NoBucket() {
36 memset(this, 0, sizeof(*this));
37 ENGINE_HANDLE_V1::interface.interface = 1;
38 ENGINE_HANDLE_V1::initialize = initialize;
39 ENGINE_HANDLE_V1::destroy = destroy;
40 ENGINE_HANDLE_V1::allocate = item_allocate;
41 ENGINE_HANDLE_V1::allocate_ex = item_allocate_ex;
42 ENGINE_HANDLE_V1::remove = item_delete;
43 ENGINE_HANDLE_V1::release = item_release;
44 ENGINE_HANDLE_V1::get = get;
45 ENGINE_HANDLE_V1::get_meta = get_meta;
46 ENGINE_HANDLE_V1::get_if = get_if;
47 ENGINE_HANDLE_V1::get_and_touch = get_and_touch;
48 ENGINE_HANDLE_V1::get_locked = get_locked;
49 ENGINE_HANDLE_V1::unlock = unlock;
50 ENGINE_HANDLE_V1::get_stats = get_stats;
51 ENGINE_HANDLE_V1::reset_stats = reset_stats;
52 ENGINE_HANDLE_V1::store = store;
53 ENGINE_HANDLE_V1::store_if = store_if;
54 ENGINE_HANDLE_V1::flush = flush;
55 ENGINE_HANDLE_V1::unknown_command = unknown_command;
56 ENGINE_HANDLE_V1::item_set_cas = item_set_cas;
57 ENGINE_HANDLE_V1::item_set_datatype = item_set_datatype;
58 ENGINE_HANDLE_V1::get_item_info = get_item_info;
59 ENGINE_HANDLE_V1::set_item_info = set_item_info;
60 ENGINE_HANDLE_V1::dcp.step = dcp_step;
61 ENGINE_HANDLE_V1::dcp.open = dcp_open;
62 ENGINE_HANDLE_V1::dcp.add_stream = dcp_add_stream;
63 ENGINE_HANDLE_V1::dcp.close_stream = dcp_close_stream;
64 ENGINE_HANDLE_V1::dcp.get_failover_log = dcp_get_failover_log;
65 ENGINE_HANDLE_V1::dcp.stream_req = dcp_stream_req;
66 ENGINE_HANDLE_V1::dcp.stream_end = dcp_stream_end;
67 ENGINE_HANDLE_V1::dcp.snapshot_marker = dcp_snapshot_marker;
68 ENGINE_HANDLE_V1::dcp.mutation = dcp_mutation;
69 ENGINE_HANDLE_V1::dcp.deletion = dcp_deletion;
70 ENGINE_HANDLE_V1::dcp.deletion_v2 = dcp_deletion_v2;
71 ENGINE_HANDLE_V1::dcp.expiration = dcp_expiration;
72 ENGINE_HANDLE_V1::dcp.flush = dcp_flush;
73 ENGINE_HANDLE_V1::dcp.set_vbucket_state = dcp_set_vbucket_state;
74 ENGINE_HANDLE_V1::dcp.system_event = dcp_system_event;
75 ENGINE_HANDLE_V1::collections.set_manifest = collections_set_manifest;
76 ENGINE_HANDLE_V1::collections.get_manifest = collections_get_manifest;
77 ENGINE_HANDLE_V1::isXattrEnabled = isXattrEnabled;
78 ENGINE_HANDLE_V1::getMaxItemSize = getMaxItemSize;
79 };
80
81 private:
82 /**
83 * Convert the ENGINE_HANDLE to the underlying class type
84 *
85 * @param handle the handle as provided by the frontend
86 * @return the actual no bucket object
87 */
get_handle(ENGINE_HANDLE* handle)88 static NoBucket* get_handle(ENGINE_HANDLE* handle) {
89 return reinterpret_cast<NoBucket*>(handle);
90 }
91
initialize(gsl::not_null<ENGINE_HANDLE*>, const char*)92 static ENGINE_ERROR_CODE initialize(gsl::not_null<ENGINE_HANDLE*>,
93 const char*) {
94 return ENGINE_SUCCESS;
95 }
96
destroy(gsl::not_null<ENGINE_HANDLE*> handle, const bool)97 static void destroy(gsl::not_null<ENGINE_HANDLE*> handle, const bool) {
98 delete get_handle(handle);
99 }
100
item_allocate(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, const DocKey&, const size_t, const int, const rel_time_t, uint8_t, uint16_t)101 static cb::EngineErrorItemPair item_allocate(gsl::not_null<ENGINE_HANDLE*>,
102 gsl::not_null<const void*>,
103 const DocKey&,
104 const size_t,
105 const int,
106 const rel_time_t,
107 uint8_t,
108 uint16_t) {
109 return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
110 }
111
item_allocate_ex( gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*> cookie, const DocKey&, size_t, size_t, int, rel_time_t, uint8_t, uint16_t)112 static std::pair<cb::unique_item_ptr, item_info> item_allocate_ex(
113 gsl::not_null<ENGINE_HANDLE*>,
114 gsl::not_null<const void*> cookie,
115 const DocKey&,
116 size_t,
117 size_t,
118 int,
119 rel_time_t,
120 uint8_t,
121 uint16_t) {
122 throw cb::engine_error(cb::engine_errc::no_bucket, "no bucket");
123 }
124
item_delete(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, const DocKey&, uint64_t&, uint16_t, mutation_descr_t&)125 static ENGINE_ERROR_CODE item_delete(gsl::not_null<ENGINE_HANDLE*>,
126 gsl::not_null<const void*>,
127 const DocKey&,
128 uint64_t&,
129 uint16_t,
130 mutation_descr_t&) {
131 return ENGINE_NO_BUCKET;
132 }
133
item_release(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<item*>)134 static void item_release(gsl::not_null<ENGINE_HANDLE*>,
135 gsl::not_null<item*>) {
136 throw std::logic_error("NoBucket::item_release: no items should have"
137 " been allocated from this engine");
138 }
139
get(gsl::not_null<ENGINE_HANDLE*> h, gsl::not_null<const void*>, const DocKey&, uint16_t, DocStateFilter)140 static cb::EngineErrorItemPair get(gsl::not_null<ENGINE_HANDLE*> h,
141 gsl::not_null<const void*>,
142 const DocKey&,
143 uint16_t,
144 DocStateFilter) {
145 return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
146 }
147
get_meta( gsl::not_null<ENGINE_HANDLE*> handle, gsl::not_null<const void*> cookie, const DocKey& key, uint16_t vbucket)148 static cb::EngineErrorMetadataPair get_meta(
149 gsl::not_null<ENGINE_HANDLE*> handle,
150 gsl::not_null<const void*> cookie,
151 const DocKey& key,
152 uint16_t vbucket) {
153 return cb::EngineErrorMetadataPair(cb::engine_errc::no_bucket, {});
154 }
155
get_if( gsl::not_null<ENGINE_HANDLE*> handle, gsl::not_null<const void*>, const DocKey&, uint16_t, std::function<bool(const item_info&)>)156 static cb::EngineErrorItemPair get_if(
157 gsl::not_null<ENGINE_HANDLE*> handle,
158 gsl::not_null<const void*>,
159 const DocKey&,
160 uint16_t,
161 std::function<bool(const item_info&)>) {
162 return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
163 }
164
get_and_touch( gsl::not_null<ENGINE_HANDLE*> handle, gsl::not_null<const void*> cookie, const DocKey&, uint16_t, uint32_t)165 static cb::EngineErrorItemPair get_and_touch(
166 gsl::not_null<ENGINE_HANDLE*> handle,
167 gsl::not_null<const void*> cookie,
168 const DocKey&,
169 uint16_t,
170 uint32_t) {
171 return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
172 }
173
get_locked(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, const DocKey&, uint16_t, uint32_t)174 static cb::EngineErrorItemPair get_locked(gsl::not_null<ENGINE_HANDLE*>,
175 gsl::not_null<const void*>,
176 const DocKey&,
177 uint16_t,
178 uint32_t) {
179 return cb::makeEngineErrorItemPair(cb::engine_errc::no_bucket);
180 }
181
unlock(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, const DocKey&, uint16_t, uint64_t)182 static ENGINE_ERROR_CODE unlock(gsl::not_null<ENGINE_HANDLE*>,
183 gsl::not_null<const void*>,
184 const DocKey&,
185 uint16_t,
186 uint64_t) {
187 return ENGINE_NO_BUCKET;
188 }
189
get_stats(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, cb::const_char_buffer key, ADD_STAT)190 static ENGINE_ERROR_CODE get_stats(gsl::not_null<ENGINE_HANDLE*>,
191 gsl::not_null<const void*>,
192 cb::const_char_buffer key,
193 ADD_STAT) {
194 return ENGINE_NO_BUCKET;
195 }
196
store(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, gsl::not_null<item*>, uint64_t&, ENGINE_STORE_OPERATION, DocumentState)197 static ENGINE_ERROR_CODE store(gsl::not_null<ENGINE_HANDLE*>,
198 gsl::not_null<const void*>,
199 gsl::not_null<item*>,
200 uint64_t&,
201 ENGINE_STORE_OPERATION,
202 DocumentState) {
203 return ENGINE_NO_BUCKET;
204 }
205
store_if(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, gsl::not_null<item*>, uint64_t, ENGINE_STORE_OPERATION, cb::StoreIfPredicate, DocumentState)206 static cb::EngineErrorCasPair store_if(gsl::not_null<ENGINE_HANDLE*>,
207 gsl::not_null<const void*>,
208 gsl::not_null<item*>,
209 uint64_t,
210 ENGINE_STORE_OPERATION,
211 cb::StoreIfPredicate,
212 DocumentState) {
213 return {cb::engine_errc::no_bucket, 0};
214 }
215
flush(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>)216 static ENGINE_ERROR_CODE flush(gsl::not_null<ENGINE_HANDLE*>,
217 gsl::not_null<const void*>) {
218 return ENGINE_NO_BUCKET;
219 }
220
reset_stats(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*> cookie)221 static void reset_stats(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*> cookie) {
222 }
223
unknown_command( gsl::not_null<ENGINE_HANDLE*>, const void*, gsl::not_null<protocol_binary_request_header*>, ADD_RESPONSE, DocNamespace)224 static ENGINE_ERROR_CODE unknown_command(
225 gsl::not_null<ENGINE_HANDLE*>,
226 const void*,
227 gsl::not_null<protocol_binary_request_header*>,
228 ADD_RESPONSE,
229 DocNamespace) {
230 return ENGINE_NO_BUCKET;
231 }
232
item_set_cas(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<item*>, uint64_t)233 static void item_set_cas(gsl::not_null<ENGINE_HANDLE*>,
234 gsl::not_null<item*>,
235 uint64_t) {
236 throw std::logic_error("NoBucket::item_set_cas: no items should have"
237 " been allocated from this engine");
238 }
239
item_set_datatype(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<item*>, protocol_binary_datatype_t)240 static void item_set_datatype(gsl::not_null<ENGINE_HANDLE*>,
241 gsl::not_null<item*>,
242 protocol_binary_datatype_t) {
243 throw std::logic_error(
244 "NoBucket::item_set_datatype: no items should have"
245 " been allocated from this engine");
246 }
247
get_item_info(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const item*>, gsl::not_null<item_info*>)248 static bool get_item_info(gsl::not_null<ENGINE_HANDLE*>,
249 gsl::not_null<const item*>,
250 gsl::not_null<item_info*>) {
251 throw std::logic_error("NoBucket::get_item_info: no items should have"
252 " been allocated from this engine");
253 }
254
set_item_info(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<item*>, gsl::not_null<const item_info*>)255 static bool set_item_info(gsl::not_null<ENGINE_HANDLE*>,
256 gsl::not_null<item*>,
257 gsl::not_null<const item_info*>) {
258 throw std::logic_error("NoBucket::set_item_info: no items should have"
259 " been allocated from this engine");
260 }
261
dcp_step( gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, gsl::not_null<struct dcp_message_producers*>)262 static ENGINE_ERROR_CODE dcp_step(
263 gsl::not_null<ENGINE_HANDLE*>,
264 gsl::not_null<const void*>,
265 gsl::not_null<struct dcp_message_producers*>) {
266 return ENGINE_NO_BUCKET;
267 }
268
dcp_open(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint32_t, uint32_t, cb::const_char_buffer, cb::const_byte_buffer)269 static ENGINE_ERROR_CODE dcp_open(gsl::not_null<ENGINE_HANDLE*>,
270 gsl::not_null<const void*>,
271 uint32_t,
272 uint32_t,
273 uint32_t,
274 cb::const_char_buffer,
275 cb::const_byte_buffer) {
276 return ENGINE_NO_BUCKET;
277 }
278
dcp_add_stream(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t, uint32_t)279 static ENGINE_ERROR_CODE dcp_add_stream(gsl::not_null<ENGINE_HANDLE*>,
280 gsl::not_null<const void*>,
281 uint32_t,
282 uint16_t,
283 uint32_t) {
284 return ENGINE_NO_BUCKET;
285 }
286
dcp_close_stream(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t)287 static ENGINE_ERROR_CODE dcp_close_stream(gsl::not_null<ENGINE_HANDLE*>,
288 gsl::not_null<const void*>,
289 uint32_t,
290 uint16_t) {
291 return ENGINE_NO_BUCKET;
292 }
293
dcp_stream_req(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint32_t, uint16_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t, uint64_t*, dcp_add_failover_log)294 static ENGINE_ERROR_CODE dcp_stream_req(gsl::not_null<ENGINE_HANDLE*>,
295 gsl::not_null<const void*>,
296 uint32_t,
297 uint32_t,
298 uint16_t,
299 uint64_t,
300 uint64_t,
301 uint64_t,
302 uint64_t,
303 uint64_t,
304 uint64_t*,
305 dcp_add_failover_log) {
306 return ENGINE_NO_BUCKET;
307 }
308
dcp_get_failover_log( gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t, ENGINE_ERROR_CODE (*)(vbucket_failover_t*, size_t, gsl::not_null<const void*>))309 static ENGINE_ERROR_CODE dcp_get_failover_log(
310 gsl::not_null<ENGINE_HANDLE*>,
311 gsl::not_null<const void*>,
312 uint32_t,
313 uint16_t,
314 ENGINE_ERROR_CODE (*)(vbucket_failover_t*,
315 size_t,
316 gsl::not_null<const void*>)) {
317 return ENGINE_NO_BUCKET;
318 }
319
dcp_stream_end(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t, uint32_t)320 static ENGINE_ERROR_CODE dcp_stream_end(gsl::not_null<ENGINE_HANDLE*>,
321 gsl::not_null<const void*>,
322 uint32_t,
323 uint16_t,
324 uint32_t) {
325 return ENGINE_NO_BUCKET;
326 }
327
dcp_snapshot_marker(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t, uint64_t, uint64_t, uint32_t)328 static ENGINE_ERROR_CODE dcp_snapshot_marker(gsl::not_null<ENGINE_HANDLE*>,
329 gsl::not_null<const void*>,
330 uint32_t,
331 uint16_t,
332 uint64_t,
333 uint64_t,
334 uint32_t) {
335 return ENGINE_NO_BUCKET;
336 }
337
dcp_mutation(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, const DocKey&, cb::const_byte_buffer, size_t, uint8_t, uint64_t, uint16_t, uint32_t, uint64_t, uint64_t, uint32_t, uint32_t, cb::const_byte_buffer, uint8_t)338 static ENGINE_ERROR_CODE dcp_mutation(gsl::not_null<ENGINE_HANDLE*>,
339 gsl::not_null<const void*>,
340 uint32_t,
341 const DocKey&,
342 cb::const_byte_buffer,
343 size_t,
344 uint8_t,
345 uint64_t,
346 uint16_t,
347 uint32_t,
348 uint64_t,
349 uint64_t,
350 uint32_t,
351 uint32_t,
352 cb::const_byte_buffer,
353 uint8_t) {
354 return ENGINE_NO_BUCKET;
355 }
356
dcp_deletion(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, const DocKey&, cb::const_byte_buffer, size_t, uint8_t, uint64_t, uint16_t, uint64_t, uint64_t, cb::const_byte_buffer)357 static ENGINE_ERROR_CODE dcp_deletion(gsl::not_null<ENGINE_HANDLE*>,
358 gsl::not_null<const void*>,
359 uint32_t,
360 const DocKey&,
361 cb::const_byte_buffer,
362 size_t,
363 uint8_t,
364 uint64_t,
365 uint16_t,
366 uint64_t,
367 uint64_t,
368 cb::const_byte_buffer) {
369 return ENGINE_NO_BUCKET;
370 }
371
dcp_deletion_v2(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, const DocKey&, cb::const_byte_buffer, size_t, uint8_t, uint64_t, uint16_t, uint64_t, uint64_t, uint32_t)372 static ENGINE_ERROR_CODE dcp_deletion_v2(gsl::not_null<ENGINE_HANDLE*>,
373 gsl::not_null<const void*>,
374 uint32_t,
375 const DocKey&,
376 cb::const_byte_buffer,
377 size_t,
378 uint8_t,
379 uint64_t,
380 uint16_t,
381 uint64_t,
382 uint64_t,
383 uint32_t) {
384 return ENGINE_NO_BUCKET;
385 }
386
dcp_expiration(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, const DocKey&, cb::const_byte_buffer, size_t, uint8_t, uint64_t, uint16_t, uint64_t, uint64_t, cb::const_byte_buffer)387 static ENGINE_ERROR_CODE dcp_expiration(gsl::not_null<ENGINE_HANDLE*>,
388 gsl::not_null<const void*>,
389 uint32_t,
390 const DocKey&,
391 cb::const_byte_buffer,
392 size_t,
393 uint8_t,
394 uint64_t,
395 uint16_t,
396 uint64_t,
397 uint64_t,
398 cb::const_byte_buffer) {
399 return ENGINE_NO_BUCKET;
400 }
401
dcp_flush(gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t)402 static ENGINE_ERROR_CODE dcp_flush(gsl::not_null<ENGINE_HANDLE*>,
403 gsl::not_null<const void*>,
404 uint32_t,
405 uint16_t) {
406 return ENGINE_NO_BUCKET;
407 }
408
dcp_set_vbucket_state( gsl::not_null<ENGINE_HANDLE*>, gsl::not_null<const void*>, uint32_t, uint16_t, vbucket_state_t)409 static ENGINE_ERROR_CODE dcp_set_vbucket_state(
410 gsl::not_null<ENGINE_HANDLE*>,
411 gsl::not_null<const void*>,
412 uint32_t,
413 uint16_t,
414 vbucket_state_t) {
415 return ENGINE_NO_BUCKET;
416 }
417
dcp_system_event( gsl::not_null<ENGINE_HANDLE*> handle, gsl::not_null<const void*> cookie, uint32_t opaque, uint16_t vbucket, mcbp::systemevent::id event, uint64_t bySeqno, cb::const_byte_buffer key, cb::const_byte_buffer eventData)418 static ENGINE_ERROR_CODE dcp_system_event(
419 gsl::not_null<ENGINE_HANDLE*> handle,
420 gsl::not_null<const void*> cookie,
421 uint32_t opaque,
422 uint16_t vbucket,
423 mcbp::systemevent::id event,
424 uint64_t bySeqno,
425 cb::const_byte_buffer key,
426 cb::const_byte_buffer eventData) {
427 return ENGINE_NO_BUCKET;
428 }
429
collections_set_manifest( gsl::not_null<ENGINE_HANDLE*> handle, cb::const_char_buffer json)430 static cb::engine_error collections_set_manifest(
431 gsl::not_null<ENGINE_HANDLE*> handle, cb::const_char_buffer json) {
432 return {cb::engine_errc::no_bucket,
433 "nobucket::collections_set_manifest"};
434 }
435
collections_get_manifest( gsl::not_null<ENGINE_HANDLE*> handle)436 static cb::EngineErrorStringPair collections_get_manifest(
437 gsl::not_null<ENGINE_HANDLE*> handle) {
438 return {cb::engine_errc::no_bucket,
439 "nobucket::collections_get_manifest"};
440 }
441
isXattrEnabled(gsl::not_null<ENGINE_HANDLE*> handle)442 static bool isXattrEnabled(gsl::not_null<ENGINE_HANDLE*> handle) {
443 return false;
444 }
445
getCompressionMode(gsl::not_null<ENGINE_HANDLE*> handle)446 static BucketCompressionMode getCompressionMode(gsl::not_null<ENGINE_HANDLE*> handle) {
447 return BucketCompressionMode::Off;
448 }
449
getMaxItemSize(gsl::not_null<ENGINE_HANDLE*> handle)450 static size_t getMaxItemSize(gsl::not_null<ENGINE_HANDLE*> handle) {
451 return default_max_item_size;
452 }
453
getMinCompressionRatio(gsl::not_null<ENGINE_HANDLE*> handle)454 static float getMinCompressionRatio(gsl::not_null<ENGINE_HANDLE*> handle) {
455 return default_min_compression_ratio;
456 }
457 };
458
459 MEMCACHED_PUBLIC_API
create_no_bucket_instance(uint64_t interface, GET_SERVER_API get_server_api, ENGINE_HANDLE **handle)460 ENGINE_ERROR_CODE create_no_bucket_instance(uint64_t interface,
461 GET_SERVER_API get_server_api,
462 ENGINE_HANDLE **handle)
463 {
464 if (interface != 1) {
465 return ENGINE_ENOTSUP;
466 }
467
468 try {
469 NoBucket* engine = new NoBucket();
470 *handle = reinterpret_cast<ENGINE_HANDLE*>(engine);
471 } catch (std::bad_alloc& e) {
472 auto logger = get_server_api()->log->get_logger();
473 logger->log(EXTENSION_LOG_WARNING, NULL,
474 "NoBucket: failed to create engine: %s", e.what());
475 return ENGINE_FAILED;
476 }
477
478 return ENGINE_SUCCESS;
479 }
480
481 MEMCACHED_PUBLIC_API
destroy_engine(void)482 void destroy_engine(void) {
483 // Empty
484 }
485