1 /* -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /*
3  *     Copyright 2010 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 <stdio.h>
19 #include <stdlib.h>
20 #include <string.h>
21 #include <fcntl.h>
22 
23 #include "libforestdb/forestdb.h"
24 #include "common.h"
25 #include "internal_types.h"
26 #include "btree_var_kv_ops.h"
27 #include "hbtrie.h"
28 #include "fdb_internal.h"
29 
30 #include "memleak.h"
31 
32 #ifdef __DEBUG
33 #ifndef __DEBUG_FDB
34     #undef DBG
35     #undef DBGCMD
36     #undef DBGSW
37     #define DBG(...)
38     #define DBGCMD(...)
39     #define DBGSW(n, ...)
40 #endif
41 #endif
42 
43 LIBFDB_API
fdb_get_kv(fdb_kvs_handle *handle, const void *key, size_t keylen, void **value_out, size_t *valuelen_out)44 fdb_status fdb_get_kv(fdb_kvs_handle *handle,
45                       const void *key, size_t keylen,
46                       void **value_out, size_t *valuelen_out)
47 {
48     fdb_doc *doc = NULL;
49     fdb_status fs;
50 
51     if (key == NULL || keylen == 0 || keylen > FDB_MAX_KEYLEN ||
52         value_out == NULL || valuelen_out == NULL ||
53         (handle->kvs_config.custom_cmp &&
54             keylen > handle->config.blocksize - HBTRIE_HEADROOM)) {
55         return FDB_RESULT_INVALID_ARGS;
56     }
57 
58     fs = fdb_doc_create(&doc, key, keylen, NULL, 0, NULL, 0);
59     if (fs != FDB_RESULT_SUCCESS) { // LCOV_EXCL_START
60         if (doc) {
61             fdb_doc_free(doc);
62         }
63         fdb_log(&handle->log_callback, fs,
64                 "Warning: Failed to allocate fdb_doc instance for key '%s' in "
65                 "fdb_get_kv API.", (const char *)key);
66         return fs;
67     } // LCOV_EXCL_STOP
68 
69     fs = fdb_get(handle, doc);
70     if (fs != FDB_RESULT_SUCCESS) {
71         if (doc) {
72             fdb_doc_free(doc);
73         }
74         return fs;
75     }
76 
77     *value_out = doc->body;
78     *valuelen_out = doc->bodylen;
79     if (doc->key) free(doc->key);
80     if (doc->meta) free(doc->meta);
81     free(doc);
82 
83     return fs;
84 }
85 
86 LIBFDB_API
fdb_set_kv(fdb_kvs_handle *handle, const void *key, size_t keylen, const void *value, size_t valuelen)87 fdb_status fdb_set_kv(fdb_kvs_handle *handle,
88                       const void *key, size_t keylen,
89                       const void *value, size_t valuelen)
90 {
91     fdb_doc *doc;
92     fdb_status fs;
93 
94     if (key == NULL || keylen == 0 || keylen > FDB_MAX_KEYLEN ||
95         (handle->kvs_config.custom_cmp &&
96             keylen > handle->config.blocksize - HBTRIE_HEADROOM)) {
97         return FDB_RESULT_INVALID_ARGS;
98     }
99 
100     fs = fdb_doc_create(&doc, key, keylen, NULL, 0, value, valuelen);
101     if (fs != FDB_RESULT_SUCCESS) { // LCOV_EXCL_START
102         if (doc) {
103             fdb_doc_free(doc);
104         }
105         fdb_log(&handle->log_callback, fs,
106                 "Warning: Failed to allocate fdb_doc instance for key '%s' in "
107                 "fdb_set_kv API.", (const char *)key);
108         return fs;
109     } // LCOV_EXCL_STOP
110 
111     fs = fdb_set(handle, doc);
112     if (fs != FDB_RESULT_SUCCESS) {
113         if (doc) {
114             fdb_doc_free(doc);
115         }
116         return fs;
117     }
118     fdb_doc_free(doc);
119 
120     return fs;
121 }
122 
123 LIBFDB_API
fdb_del_kv(fdb_kvs_handle *handle, const void *key, size_t keylen)124 fdb_status fdb_del_kv(fdb_kvs_handle *handle,
125                       const void *key, size_t keylen)
126 {
127     fdb_doc *doc;
128     fdb_status fs;
129 
130     if (key == NULL || keylen == 0 || keylen > FDB_MAX_KEYLEN ||
131         (handle->kvs_config.custom_cmp &&
132             keylen > handle->config.blocksize - HBTRIE_HEADROOM)) {
133         return FDB_RESULT_INVALID_ARGS;
134     }
135 
136     fs = fdb_doc_create(&doc, key, keylen, NULL, 0, NULL, 0);
137     if (fs != FDB_RESULT_SUCCESS) { // LCOV_EXCL_START
138         if (doc) {
139             fdb_doc_free(doc);
140         }
141         fdb_log(&handle->log_callback, fs,
142                 "Warning: Failed to allocate fdb_doc instance for key '%s' in "
143                 "fdb_del_kv API.", (const char *)key);
144         return fs;
145     } // LCOV_EXCL_STOP
146 
147     fs = fdb_del(handle, doc);
148     if (fs != FDB_RESULT_SUCCESS) {
149         fdb_doc_free(doc);
150         return fs;
151     }
152     fdb_doc_free(doc);
153 
154     return fs;
155 }
156 
157 LIBFDB_API
fdb_free_block(void *ptr)158 fdb_status fdb_free_block(void *ptr)
159 {
160     free(ptr);
161     return FDB_RESULT_SUCCESS;
162 }
163 
164