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#ifndef _JSAHN_FDB_H
19#define _JSAHN_FDB_H
20
21#include "fdb_errors.h"
22#include "fdb_types.h"
23
24#if defined(_MSC_VER) && !defined(_FDB_TOOLS)
25    #ifdef forestdb_EXPORTS
26        #define LIBFDB_API extern __declspec(dllexport)
27    #else
28        #define LIBFDB_API extern __declspec(dllimport)
29    #endif
30#elif defined __GNUC__
31    #define LIBFDB_API __attribute ((visibility("default")))
32#else
33    #define LIBFDB_API
34#endif
35
36#ifdef __cplusplus
37extern "C" {
38#endif
39
40/**
41 * Initialize all global resources (e.g., buffer cache, daemon compaction thread, etc.)
42 * for ForestDB engine, using the given configurations. Note that all open API
43 * calls automatically invoke this API if ForestDB engine is not initialized.
44 *
45 * @param config Pointer to the config instance that contains ForestDB configs.
46 *               If NULL is passed, then we use default settings of ForestDB configs.
47 * @return FDB_RESULT_SUCCESS on success.
48 */
49LIBFDB_API
50fdb_status fdb_init(fdb_config *config);
51
52/**
53 * Get the default ForestDB configs.
54 * The general recommendation is to invoke this API to get the default configs
55 * and change some configs if necessary and then pass them to fdb_open APIs.
56 *
57 * @return fdb_config instance that contains the default configs.
58 */
59LIBFDB_API
60fdb_config fdb_get_default_config(void);
61
62/**
63 * Get the default ForestDB KV(Key-Value) store configs. Note that multiple KV
64 * store instances can be created in a single ForestDB file.
65 * The general recommendation is to invoke this API to get the default configs
66 * and change some configs if necessary and then pass them to fdb_kvs_open APIs.
67 *
68 * @return fdb_kvs_config instance that contains the default configs.
69 */
70LIBFDB_API
71fdb_kvs_config fdb_get_default_kvs_config(void);
72
73/**
74 * Open a ForestDB file.
75 * The file should be closed with fdb_close API call.
76 *
77 * @param ptr_fhandle Pointer to the place where ForestDB file handle is
78 *        instantiated as result of this API call.
79 * @param filename Name of the ForestDB file to be opened.
80 * @param fconfig Pointer to the config instance that contains ForestDB configs.
81 *        If NULL is passed, then we use default settings of ForestDB configs.
82 * @return FDB_RESULT_SUCCESS on success.
83 */
84LIBFDB_API
85fdb_status fdb_open(fdb_file_handle **ptr_fhandle,
86                    const char *filename,
87                    fdb_config *fconfig);
88
89/**
90 * Open a ForestDB file.
91 * Note that if any KV store in the file uses a customized compare function,
92 * then the file should be opened with this API by passing the list of all KV
93 * instance names that use customized compare functions, and their corresponding
94 * customized compare functions.
95 *
96 * Documents in the file will be indexed using their corresponding
97 * customized compare functions. The file should be closed with fdb_close
98 * API call.
99 *
100 * @param ptr_fhandle Pointer to the place where ForestDB file handle is
101 *        instantiated as result of this API call.
102 * @param filename Name of the ForestDB file to be opened.
103 * @param fconfig Pointer to the config instance that contains ForestDB configs.
104 *        If NULL is passed, then we use default settings of ForestDB configs.
105 * @param num_functions The number of customized compare functions.
106 * @param kvs_names List of KV store names to be indexed using the customized
107 *        compare functions.
108 * @param functions List of customized compare functions corresponding to each
109 *        KV store listed in kvs_names.
110 * @return FDB_RESULT_SUCCESS on success.
111 */
112LIBFDB_API
113fdb_status fdb_open_custom_cmp(fdb_file_handle **ptr_fhandle,
114                               const char *filename,
115                               fdb_config *fconfig,
116                               size_t num_functions,
117                               char **kvs_names,
118                               fdb_custom_cmp_variable *functions);
119
120/**
121 * Set up the error logging callback that allows an application to process
122 * error code and message from ForestDB.
123 *
124 * @param handle Pointer to ForestDB KV store handle.
125 * @param log_callback Logging callback function that receives and processes
126 *        error codes and messages from ForestDB.
127 * @param ctx_data Pointer to application-specific context data that is going
128 *        to be passed to the logging callback function.
129 * @return FDB_RESULT_SUCCESS on success.
130 */
131LIBFDB_API
132fdb_status fdb_set_log_callback(fdb_kvs_handle *handle,
133                                fdb_log_callback log_callback,
134                                void *ctx_data);
135
136/**
137 * Set the fatal error callback that allows an application to specify a
138 * function to be called if forestdb encounters a fatal error, before
139 * forestdb raises a SIGABRT.
140 *
141 * @param err_callback Error callback that will be called upon detecting a
142 *        fatal error (but before forestdb raises SIGABRT). Any previously
143 *        registered fatal error callback will be replaced.
144 */
145LIBFDB_API
146void fdb_set_fatal_error_callback(fdb_fatal_error_callback err_callback);
147
148/**
149 * Create a new FDB_DOC instance on heap with a given key, its metadata, and
150 * its doc body.
151 *
152 * @param doc Pointer to a FDB_DOC instance created.
153 * @param key Pointer to a key.
154 * @param keylen Key length.
155 * @param meta Pointer to key's metadata.
156 * @param metalen Metadata length.
157 * @param body Pointer to key's doc body.
158 * @param bodylen Doc body length.
159 * @return FDB_RESULT_SUCCESS on success.
160 */
161LIBFDB_API
162fdb_status fdb_doc_create(fdb_doc **doc,
163                          const void *key,
164                          size_t keylen,
165                          const void *meta,
166                          size_t metalen,
167                          const void *body,
168                          size_t bodylen);
169
170/**
171 * Update a FDB_DOC instance with a given metadata and body.
172 * Note that this API does not update an item in the ForestDB KV store, but
173 * instead simply updates a given FDB_DOC instance only.
174 *
175 * @param doc Pointer to a FDB_DOC instance to be updated.
176 * @param meta Pointer to key's metadata.
177 * @param metalen Metadata length.
178 * @param body Pointer to key's doc body.
179 * @param bodylen Doc body length.
180 * @return FDB_RESULT_SUCCESS on success.
181 */
182LIBFDB_API
183fdb_status fdb_doc_update(fdb_doc **doc,
184                          const void *meta,
185                          size_t metalen,
186                          const void *body,
187                          size_t bodylen);
188
189/**
190 * Explicitly set the sequence number of a FDB_DOC instance instead of having
191 * ForestDB internally generate it upon fdb_set().
192 * Note that this API does not update an item in the ForestDB KV store, but
193 * instead simply updates a given FDB_DOC instance only.
194 *
195 * WARNING: It is upto the caller to ensure that sequence numbers are unique
196 *          and monotonically increasing based on the order of mutations.
197 *
198 * @param doc Pointer to a FDB_DOC instance to be updated.
199 * @param seqnum The value of the custom sequence number for this mutation.
200 *
201 */
202LIBFDB_API
203void fdb_doc_set_seqnum(fdb_doc *doc,
204                        const fdb_seqnum_t seqnum);
205
206/**
207 * Free a given FDB_DOC instance from heap.
208 *
209 * @param doc Pointer to a FDB_DOC instance to be freed from heap.
210 * @return FDB_RESULT_SUCCESS on success.
211 */
212LIBFDB_API
213fdb_status fdb_doc_free(fdb_doc *doc);
214
215/**
216 * Retrieve the metadata and doc body for a given key.
217 * Note that FDB_DOC instance should be created by calling
218 * fdb_doc_create(doc, key, keylen, NULL, 0, NULL, 0) before using this API.
219 *
220 * @param handle Pointer to ForestDB KV store handle.
221 * @param doc Pointer to ForestDB doc instance whose metadata and doc body
222 *        are populated as a result of this API call.
223 * @return FDB_RESULT_SUCCESS on success.
224 */
225LIBFDB_API
226fdb_status fdb_get(fdb_kvs_handle *handle,
227                   fdb_doc *doc);
228
229/**
230 * Retrieve the metadata for a given key.
231 * Note that FDB_DOC instance should be created by calling
232 * fdb_doc_create(doc, key, keylen, NULL, 0, NULL, 0) before using this API.
233 *
234 * WARNING: If the document was deleted but not yet purged, then the metadata
235 *          will still be populated in the fdb_doc passed into the function.
236 *
237 * @param handle Pointer to ForestDB KV store handle.
238 * @param doc Pointer to ForestDB doc instance whose metadata including the offset
239 *        on disk is populated as a result of this API call.
240 *        Note that the offset returned can be used by fdb_get_byoffset API to
241 *        retrieve a doc body.
242 * @return FDB_RESULT_SUCCESS on success.
243 */
244LIBFDB_API
245fdb_status fdb_get_metaonly(fdb_kvs_handle *handle,
246                            fdb_doc *doc);
247
248/**
249 * Retrieve the metadata and doc body for a given sequence number.
250 * Note that FDB_DOC instance should be created by calling
251 * fdb_doc_create(doc, NULL, 0, NULL, 0, NULL, 0) before using this API.
252 *
253 * @param handle Pointer to ForestDB KV store handle.
254 * @param doc Pointer to ForestDB doc instance whose key, metadata and doc body
255 *        are populated as a result of this API call.
256 * @return FDB_RESULT_SUCCESS on success.
257 */
258LIBFDB_API
259fdb_status fdb_get_byseq(fdb_kvs_handle *handle,
260                         fdb_doc *doc);
261
262/**
263 * Retrieve the metadata for a given sequence number.
264 * Note that FDB_DOC instance should be created by calling
265 * fdb_doc_create(doc, NULL, 0, NULL, 0, NULL, 0) before using this API.
266 *
267 * WARNING: If the document was deleted but not yet purged, then the metadata
268 *          will still be populated in the fdb_doc passed into the function.
269 *
270 * @param handle Pointer to ForestDB KV store handle.
271 * @param doc Pointer to ForestDB doc instance whose key and metadata including
272 *        the offset on disk are populated as a result of this API call.
273 *        Note that the offset returned can be used by fdb_get_byoffset API to
274 *        retrieve a doc body.
275 * @return FDB_RESULT_SUCCESS on success.
276 */
277LIBFDB_API
278fdb_status fdb_get_metaonly_byseq(fdb_kvs_handle *handle,
279                                  fdb_doc *doc);
280
281/**
282 * Retrieve a doc's metadata and body with a given doc offset in the file.
283 * Note that FDB_DOC instance should be first instantiated and populated
284 * by calling fdb_get_metaonly, fdb_get_metaonly_byseq, or
285 * fdb_iterator_next_offset, which returns an offset to a doc. Then,
286 * the FDB_DOC instance and the offset should be passed together to this API.
287 *
288 * WARNING: If the document was deleted but not yet purged, then the metadata
289 *          will still be populated in the fdb_doc passed into the function,
290 *          even though the return code is FDB_RESULT_KEY_NOT_FOUND.
291 *
292 * @param handle Pointer to ForestDB KV store handle.
293 * @param doc Pointer to ForestDB doc instance that contains the offset to a doc
294 *        and whose doc body is populated as a result of this API call.
295 * @return FDB_RESULT_SUCCESS on success.
296 */
297LIBFDB_API
298fdb_status fdb_get_byoffset(fdb_kvs_handle *handle,
299                            fdb_doc *doc);
300
301/**
302 * Update the metadata and doc body for a given key.
303 * Note that FDB_DOC instance should be created by calling
304 * fdb_doc_create(doc, key, keylen, meta, metalen, body, bodylen) before using
305 * this API. Setting "deleted" flag in FDB_DOC instance to true is equivalent to
306 * calling fdb_del api described below.
307 *
308 * @param handle Pointer to ForestDB KV store handle.
309 * @param doc Pointer to ForestDB doc instance that is used to update a key.
310 * @return FDB_RESULT_SUCCESS on success.
311 */
312LIBFDB_API
313fdb_status fdb_set(fdb_kvs_handle *handle,
314                   fdb_doc *doc);
315
316/**
317 * Delete a key, its metadata and value
318 * Note that FDB_DOC instance should be created by calling
319 * fdb_doc_create(doc, key, keylen, meta, metalen, body, bodylen) before using
320 * this API.
321 *
322 * @param handle Pointer to ForestDB KV store handle.
323 * @param doc Pointer to ForestDB doc instance that is used to delete a key.
324 * @return FDB_RESULT_SUCCESS on success.
325 */
326LIBFDB_API
327fdb_status fdb_del(fdb_kvs_handle *handle,
328                   fdb_doc *doc);
329
330/**
331 * Simplified API for fdb_get:
332 * Retrieve the value (doc body in fdb_get) for a given key.
333 *
334 * @param handle Pointer to ForestDB KV store handle.
335 * @param key Pointer to the key to be retrieved.
336 * @param keylen Length of the key.
337 * @param value_out Pointer to the value as a result of this API call. Note that this
338 *        pointer should be released using free().
339 * @param valuelen_out Length of the value as a result of this API call.
340 * @return FDB_RESULT_SUCCESS on success.
341 */
342LIBFDB_API
343fdb_status fdb_get_kv(fdb_kvs_handle *handle,
344                      const void *key, size_t keylen,
345                      void **value_out, size_t *valuelen_out);
346
347/**
348 * Simplified API for fdb_set:
349 * Update the value (doc body in fdb_set) for a given key.
350 *
351 * @param handle Pointer to ForestDB KV store handle.
352 * @param key Pointer to the key to be updated.
353 * @param keylen Length of the key.
354 * @param value Pointer to the value corresponding to the key.
355 * @param valuelen Length of the value.
356 * @return FDB_RESULT_SUCCESS on success.
357 */
358LIBFDB_API
359fdb_status fdb_set_kv(fdb_kvs_handle *handle,
360                      const void *key, size_t keylen,
361                      const void *value, size_t valuelen);
362
363/**
364 * Simplified API for fdb_del:
365 * Delete a key, and its value (doc body in fdb_del).
366 *
367 * @param handle Pointer to ForestDB KV store handle.
368 * @param key Pointer to the key to be deleted.
369 * @param keylen Length of the key.
370 * @return FDB_RESULT_SUCCESS on success.
371 */
372LIBFDB_API
373fdb_status fdb_del_kv(fdb_kvs_handle *handle,
374                      const void *key, size_t keylen);
375
376/**
377 * Free memory allocated by fdb_get_kv:
378 * Release the memory allocated by ForestDB when fdb_get_kv called.
379 *
380 * @param ptr Pointer to the value memory that must be freed.
381 * @return FDB_RESULT_SUCCESS on success.
382 */
383LIBFDB_API
384fdb_status fdb_free_block(void *ptr);
385
386/**
387 * Commit all pending changes on a ForestDB file into disk.
388 * Note that this API should be invoked with a ForestDB file handle.
389 *
390 * @param fhandle Pointer to ForestDB file handle.
391 * @param opt Commit option.
392 * @return FDB_RESULT_SUCCESS on success.
393 */
394LIBFDB_API
395fdb_status fdb_commit(fdb_file_handle *fhandle, fdb_commit_opt_t opt);
396
397/**
398 * Create a snapshot of a KV store.
399 *
400 * @param handle_in ForestDB KV store handle pointer from which snapshot is to be made
401 * @param handle_out Pointer to KV store snapshot handle, close with fdb_kvs_close()
402 * @param snapshot_seqnum The sequence number or snapshot marker of snapshot.
403 *        Note that this seq number should correspond to one of the commits
404 *        that have been persisted for a given KV store instance.
405 *        To create an in-memory snapshot for a given KV store, pass
406 *        FDB_SNAPSHOT_INMEM as the sequence number.
407 *        In-memory snapshot is a non-durable consistent copy of the KV store
408 *        instance and carries the latest version of all the keys at the point
409 *        of the snapshot and can even be taken out of uncommitted transaction.
410 * @return FDB_RESULT_SUCCESS on success.
411 *         FDB_RESULT_INVALID_ARGS if any input param is NULL, or,
412 *                                 if sequence number tree is not enabled
413 *         Any other error from fdb_open may be returned
414 */
415LIBFDB_API
416fdb_status fdb_snapshot_open(fdb_kvs_handle *handle_in, fdb_kvs_handle **handle_out,
417                             fdb_seqnum_t snapshot_seqnum);
418
419/**
420 * Rollback a KV store to a specified point represented by a given sequence
421 * number.
422 *
423 * @param handle_ptr ForestDB KV store handle that needs to be rolled back.
424 * @param rollback_seqnum sequence number or rollback point marker of snapshot
425 * @return FDB_RESULT_SUCCESS on success.
426 *         FDB_RESULT_INVALID_ARGS if any input param is NULL, or,
427 *                                 if sequence number tree is not enabled
428 *         Any other error from fdb_open may be returned
429 */
430LIBFDB_API
431fdb_status fdb_rollback(fdb_kvs_handle **handle_ptr, fdb_seqnum_t rollback_seqnum);
432
433/**
434 * Rollback all the KV stores in a file to a specified point represented by
435 * a file-level snapshot marker returned by fdb_get_all_snap_markers api.
436 *
437 * @param fhandle ForestDB file handle.
438 * @param marker file level marker or the rollback point of all KV stores
439 * @return FDB_RESULT_SUCCESS on success.
440 *         FDB_RESULT_HANDLE_BUSY if there are multiple kv stores used whose
441 *                                handles have not yet been closed
442 */
443LIBFDB_API
444fdb_status fdb_rollback_all(fdb_file_handle *fhandle,
445                            fdb_snapshot_marker_t marker);
446
447/**
448 * Create an iterator to traverse a ForestDB KV store snapshot by key range
449 *
450 * @param handle Pointer to ForestDB KV store handle.
451 * @param iterator Pointer to the place where the iterator is created
452 *        as a result of this API call.
453 * @param min_key Pointer to the smallest key. Passing NULL means that
454 *        it wants to start with the smallest key in the KV store.
455 * @param min_keylen Length of the smallest key.
456 * @param max_key Pointer to the largest key. Passing NULL means that it wants
457 *        to end iteration with the largest key in the KV store.
458 * @param max_keylen Length of the largest key.
459 * @param opt Iterator option.
460 * @return FDB_RESULT_SUCCESS on success.
461 */
462LIBFDB_API
463fdb_status fdb_iterator_init(fdb_kvs_handle *handle,
464                             fdb_iterator **iterator,
465                             const void *min_key,
466                             size_t min_keylen,
467                             const void *max_key,
468                             size_t max_keylen,
469                             fdb_iterator_opt_t opt);
470
471/**
472 * Create an iterator to traverse a ForestDB KV store snapshot by sequence
473 * number range
474 *
475 * @param handle Pointer to ForestDB KV store handle.
476 * @param iterator Pointer to the iterator to be created as a result of
477 *        this API call.
478 * @param min_seq Smallest document sequence number of the iteration.
479 * @param max_seq Largest document sequence number of the iteration.
480 *        Passing 0 means that it wants iteration to end with the latest
481 *        mutation
482 *
483 * @param opt Iterator option.
484 * @return FDB_RESULT_SUCCESS on success.
485 */
486LIBFDB_API
487fdb_status fdb_iterator_sequence_init(fdb_kvs_handle *handle,
488                             fdb_iterator **iterator,
489                             const fdb_seqnum_t min_seq,
490                             const fdb_seqnum_t max_seq,
491                             fdb_iterator_opt_t opt);
492
493/**
494 * Move the iterator backward by one.
495 *
496 * @param iterator Pointer to the iterator.
497 * @return FDB_RESULT_SUCCESS on success.
498 */
499LIBFDB_API
500fdb_status fdb_iterator_prev(fdb_iterator *iterator);
501
502/**
503 * Move the iterator forward by one.
504 *
505 * @param iterator Pointer to the iterator.
506 * @return FDB_RESULT_SUCCESS on success.
507 */
508LIBFDB_API
509fdb_status fdb_iterator_next(fdb_iterator *iterator);
510
511/**
512 * Get the item (key, metadata, doc body) from the iterator.
513 * Note that the parameter 'doc' should be set to NULL before passing it
514 * to this API if the API caller wants a fdb_doc instance to be created and
515 * returned by this API.
516 *
517 * Example usage:
518 *   ...
519 *   fdb_doc *doc = NULL;
520 *   // fdb_doc instance is created and returned by fdb_iterator_get API.
521 *   fdb_status status = fdb_iterator_get(iterator, &doc);
522 *   ...
523 *   fdb_doc_free(doc);
524 *
525 * Otherwise, if the client knows the max lengths of key, metadata, and
526 * value in the iterator range, then it can pre-allocate fdb_doc instance with
527 * these max lengths, and pass it to this API, so that the memory allocation
528 * overhead can be avoided for each iteration.
529 *
530 * Example usage:
531 *   ...
532 *   fdb_doc *doc;
533 *   fdb_doc_create(&doc, NULL, 0, NULL, 0, NULL, 0);
534 *   doc->key = malloc(MAX_KEY_LENGTH);
535 *   doc->meta = malloc(MAX_META_LENGTH);
536 *   doc->body = malloc(MAX_VALUE_LENGTH);
537 *   while (...) {
538 *       status = fdb_iterator_get(iterator, &doc);
539 *       ...
540 *   }
541 *   fdb_doc_free(doc);
542 *
543 * @param iterator Pointer to the iterator.
544 * @param doc Pointer to FDB_DOC instance to be populated by the iterator.
545 * @return FDB_RESULT_SUCCESS on success.
546 */
547LIBFDB_API
548fdb_status fdb_iterator_get(fdb_iterator *iterator, fdb_doc **doc);
549
550/**
551 * Get item metadata only (key, metadata, offset to doc body) from the iterator.
552 * Note that the parameter 'doc' should be set to NULL before passing it
553 * to this API if the API caller wants a fdb_doc instance to be created and
554 * returned by this API.
555 *
556 * @param iterator Pointer to the iterator.
557 * @param doc Pointer to FDB_DOC instance to be populated by the iterator.
558 *        Note that the API call won't return the doc body, but instead the
559 *        offset to the doc on disk.
560 * @return FDB_RESULT_SUCCESS on success.
561 */
562LIBFDB_API
563fdb_status fdb_iterator_get_metaonly(fdb_iterator *iterator, fdb_doc **doc);
564
565/**
566 * Fast forward / backward an iterator to return documents starting from
567 * the given seek_key. If the seek key does not exist, the iterator is
568 * positioned to start from the next sorted key.
569 *
570 * @param iterator Pointer to the iterator.
571 * @param seek_key Pointer to the key to seek to.
572 * @param seek_keylen Length of the seek_key
573 * @param direction Specifies which key to return if seek_key does not exist.
574 *        Default value of 0 indicates FDB_ITR_SEEK_HIGHER
575 * @return FDB_RESULT_SUCCESS on success.
576 */
577LIBFDB_API
578fdb_status fdb_iterator_seek(fdb_iterator *iterator, const void *seek_key,
579                             const size_t seek_keylen,
580                             const fdb_iterator_seek_opt_t direction);
581
582/**
583 * Rewind an iterator to position at the smallest key of the iteration.
584 *
585 * @param iterator Pointer to the iterator.
586 * @return FDB_RESULT_SUCCESS on success.
587 */
588LIBFDB_API
589fdb_status fdb_iterator_seek_to_min(fdb_iterator *iterator);
590
591/**
592 * Fast forward an iterator to position at the largest key of the iteration.
593 *
594 * @param iterator Pointer to the iterator.
595 * @return FDB_RESULT_SUCCESS on success.
596 */
597LIBFDB_API
598fdb_status fdb_iterator_seek_to_max(fdb_iterator *iterator);
599
600/**
601 * Close the iterator and free its associated resources.
602 *
603 * @param iterator Pointer to the iterator.
604 * @return FDB_RESULT_SUCCESS on success.
605 */
606LIBFDB_API
607fdb_status fdb_iterator_close(fdb_iterator *iterator);
608
609/**
610 * Compact the current file and create a new compacted file.
611 * Note that a new file name passed to this API will be ignored if the compaction
612 * mode of the handle is auto-compaction (i.e., FDB_COMPACTION_AUTO). In the auto
613 * compaction mode, the name of a new compacted file will be automatically generated
614 * by increasing its current file revision number.
615 *
616 * If a new file name is not given (i.e., NULL is passed) in a manual compaction
617 * mode, then a new file name will be automatically created by appending
618 * a file revision number to the original file name.
619 *
620 *  Example usage:
621 *
622 *   fdb_open(db1, "test.fdb");
623 *   ...
624 *   fdb_compact(db1, NULL); // "test.fdb.1" is created after compaction.
625 *                           // Note that "test.fdb" will be removed automatically
626 *                           // when its reference counter becomes zero.
627 *   ...
628 *   fdb_compact(db1, NULL); // "test.fdb.2" is created after compaction.
629 *                           // Note that "test.fdb.1" will be removed automatically
630 *                           // when its reference counter becomes zero.
631 *   fdb_open(db2, "test.fdb"); // "test.fdb.2" is opened because that is the last
632 *                              // compacted file.
633 *   ...
634 *   fdb_close(db1);
635 *   fdb_close(db2); // "test.fdb.2" is automatically renamed to the original
636 *                   // file name "test.fdb" because there are no file handles
637 *                   // on "test.fdb.2".
638 *
639 * Also note that if a given ForestDB file is currently being compacted by the
640 * compaction daemon, then FDB_RESULT_FILE_IS_BUSY is returned to the caller.
641 *
642 * @param fhandle Pointer to ForestDB file handle.
643 * @param new_filename Name of a new compacted file.
644 * @return FDB_RESULT_SUCCESS on success.
645 */
646LIBFDB_API
647fdb_status fdb_compact(fdb_file_handle *fhandle,
648                       const char *new_filename);
649/**
650 * Compact the database file by sharing valid document blocks from
651 * the old file.
652 *
653 * Currently this API works only on Btrfs (B-tree file system) having the
654 * copy-file-range support that allows physical pages to be shared across files
655 * through the copy-on-write (CoW) nature of Btrfs.
656 *
657 *  WARNING: Currently this API performs best only in the offline compaction mode.
658 *  NOTE: Only one compaction will be allowed per file, and any other calls made
659 *        while the first call is in-progress will fail.
660 *
661 * @param fhandle Pointer to ForestDB file handle.
662 * @param new_filename Name of a new compacted file. The semantics are the same
663 *                     as that of fdb_compact() call described above.
664 * @return FDB_RESULT_SUCCESS on success or an error indicating either
665 *         temporary failure like FDB_RESULT_FAIL_BY_COMPACTION, or permanent
666 *         failure such as FDB_RESULT_COMPACTION_FAIL if not supported.
667 */
668LIBFDB_API
669fdb_status fdb_compact_with_cow(fdb_file_handle *fhandle,
670                                const char *new_filename);
671
672/**
673 * Compact the database file by retaining the stale data up to a given file-level
674 * snapshot marker.
675 *
676 *  NOTE: Only one compaction will be allowed per file, and any other calls made
677 *        while the first call is in-progress will fail.
678 *
679 * @param fhandle Pointer to ForestDB file handle.
680 * @param new_filename Name of a new compacted file. The semantics are the same
681 *                     as that of fdb_compact() call described above.
682 * @param marker Snapshot marker retrieved from fdb_get_all_snap_markers() API,
683 *               indicating the stale data up to a given snapshot marker will be
684 *               retained.
685 * @return FDB_RESULT_SUCCESS on success or an error indicating either
686 *         temporary failure like FDB_RESULT_FAIL_BY_COMPACTION, or permanent
687 *         failure such as FDB_RESULT_NO_DB_INSTANCE.
688 */
689LIBFDB_API
690fdb_status fdb_compact_upto(fdb_file_handle *fhandle,
691                            const char *new_filename,
692                            fdb_snapshot_marker_t marker);
693/**
694 * Compact the database file by retaining the stale data upto a given file-level
695 * snapshot marker and sharing valid document blocks from the old file.
696 *
697 * Currently this API works only on Btrfs (B-tree file system) having the
698 * copy-file-range support that allows physical pages to be shared across files
699 * through the copy-on-write (CoW) nature of Btrfs.
700 *
701 *  WARNING: Currently this API performs best only in the offline compaction mode.
702 *  NOTE: Only one compaction will be allowed per file, and any other calls made
703 *        while the first call is in-progress will fail.
704 *
705 * @param fhandle Pointer to ForestDB file handle.
706 * @param new_filename Name of a new compacted file. The semantics are the same
707 *                     as that of fdb_compact() call described above.
708 * @param marker Snapshot marker retrieved from fdb_get_all_snap_markers() API,
709 *               indicating the stale data up to a given snapshot marker will be
710 *               retained.
711 * @return FDB_RESULT_SUCCESS on success or an error indicating either
712 *         temporary failure like FDB_RESULT_FAIL_BY_COMPACTION, or permanent
713 *         failure such as FDB_RESULT_COMPACTION_FAIL if not supported.
714 */
715LIBFDB_API
716fdb_status fdb_compact_upto_with_cow(fdb_file_handle *fhandle,
717                                     const char *new_filename,
718                                     fdb_snapshot_marker_t marker);
719/**
720 * Change the database file's encryption, by compacting it while writing with a new key.
721 * @param fhandle Pointer to ForestDB file handle.
722 * @param new_key Key with which to encrypt the new file. To remove encryption, set the key's
723 *                algorithm to FDB_ENCRYPTION_NONE.
724 * @return FDB_RESULT_SUCCESS on success.
725 */
726LIBFDB_API
727fdb_status fdb_rekey(fdb_file_handle *fhandle,
728                     fdb_encryption_key new_key);
729
730/**
731 * Return the overall buffer cache space actively used by all ForestDB files.
732 * Note that this does not include space in WAL, hash tables and other
733 * in-memory data structures allocated by ForestDB api
734 *
735 * @return Size of buffer cache currently used.
736 */
737LIBFDB_API
738size_t fdb_get_buffer_cache_used();
739
740/**
741 * Return the overall disk space actively used by a ForestDB file.
742 * Note that this doesn't include the disk space used by stale btree nodes
743 * and docs.
744 *
745 * @param fhandle Pointer to ForestDB file handle.
746 * @return Disk space actively used by a ForestDB file.
747 */
748LIBFDB_API
749size_t fdb_estimate_space_used(fdb_file_handle *fhandle);
750
751/**
752 * Return the overall disk space actively used by all snapshots starting from
753 * a given snapshot marker.
754 * Note that this doesn't include the disk space used by stale btree nodes
755 * and docs.
756 *
757 * @param fhandle Pointer to ForestDB file handle.
758 * @param marker Snapshot marker returned by fdb_get_all_snap_markers()
759 * @return Disk space actively used by all snapshots starting from a given
760 *         snapshot marker. fdb_log used internally to log errors.
761 *
762 */
763LIBFDB_API
764size_t fdb_estimate_space_used_from(fdb_file_handle *fhandle,
765                                    fdb_snapshot_marker_t marker);
766
767/**
768 * Return the information about a ForestDB file.
769 *
770 * @param fhandle Pointer to ForestDB file handle.
771 * @param info Pointer to ForestDB File Info instance.
772 * @return FDB_RESULT_SUCCESS on success.
773 */
774LIBFDB_API
775fdb_status fdb_get_file_info(fdb_file_handle *fhandle, fdb_file_info *info);
776
777/**
778 * Return the information about a ForestDB KV store instance.
779 *
780 * @param handle Pointer to ForestDB KV store handle.
781 * @param info Pointer to KV Store Info instance.
782 * @return FDB_RESULT_SUCCESS on success.
783 */
784LIBFDB_API
785fdb_status fdb_get_kvs_info(fdb_kvs_handle *handle, fdb_kvs_info *info);
786
787/**
788 * Return the information about operational counters in a ForestDB KV store.
789 *
790 * @param handle Pointer to ForestDB KV store handle.
791 * @param info Pointer to KV Store Ops Info instance.
792 * @return FDB_RESULT_SUCCESS on success.
793 */
794LIBFDB_API
795fdb_status fdb_get_kvs_ops_info(fdb_kvs_handle *handle, fdb_kvs_ops_info *info);
796
797/**
798 * Get the current sequence number of a ForestDB KV store instance.
799 *
800 * @param handle Pointer to ForestDB KV store handle.
801 * @param seqnum Pointer to the variable that sequence number will be returned.
802 * @return FDB_RESULT_SUCCESS on success.
803 */
804LIBFDB_API
805fdb_status fdb_get_kvs_seqnum(fdb_kvs_handle *handle, fdb_seqnum_t *seqnum);
806
807/**
808 * Get all KV store names in a ForestDB file.
809 *
810 * @param fhandle Pointer to ForestDB file handle.
811 * @param kvs_name_list Pointer to a KV store name list. Note that this list
812 *        should be released using fdb_free_kvs_name_list API call().
813 * @return FDB_RESULT_SUCCESS on success.
814 */
815LIBFDB_API
816fdb_status fdb_get_kvs_name_list(fdb_file_handle *fhandle,
817                                 fdb_kvs_name_list *kvs_name_list);
818
819/**
820 * Return all the snapshot markers in a given database file.
821 *
822 * @param fhandle Pointer to ForestDB file handle.
823 * @param markers Pointer to the allocated array of snapshot_info instances
824 *                that correspond to each of the commit markers in a file.
825 * @param size Number of elements of the markers that are allocated.
826 * @return file i/o or other on failure, FDB_RESULT_SUCCESS if successful.
827 *
828 */
829LIBFDB_API
830fdb_status fdb_get_all_snap_markers(fdb_file_handle *fhandle,
831                                    fdb_snapshot_info_t **markers,
832                                    uint64_t *size);
833/**
834 * Free a kv snapshot_info array allocated by fdb_get_all_snap_markers API.
835 *
836 * @param markers Pointer to a KV snapshot_info array that is allocated by
837 *        fdb_get_all_snap_markers API.
838 * @param size Number of elements in above array.
839 * @return FDB_RESULT_SUCCESS on success.
840 */
841LIBFDB_API
842fdb_status fdb_free_snap_markers(fdb_snapshot_info_t *markers, uint64_t size);
843
844/**
845 * Free a KV store name list.
846 *
847 * @param kvs_name_list Pointer to a KV store name list to be freed.
848 * @return FDB_RESULT_SUCCESS on success.
849 */
850LIBFDB_API
851fdb_status fdb_free_kvs_name_list(fdb_kvs_name_list *kvs_name_list);
852
853/**
854 * Change the compaction mode of a ForestDB file referred by the handle passed.
855 * If the mode is changed to auto-compaction (i.e., FDB_COMPACTION_AUTO), the compaction
856 * threshold is set to the threshold passed to this API.
857 * This API can be also used to change the compaction threshould for a ForestDB file
858 * whose compaction mode is currently auto-compaction.
859 *
860 * Note that all the other handles referring the same ForestDB file should be closed
861 * before this API call, and no concurrent operation should be performed on the same
862 * file until the mode switching is done.
863 *
864 * @param fhandle Pointer to ForestDB file handle.
865 * @param mode New compaction mode to be set.
866 * @param new_threshold New compaction threshold to be set.
867 * @return FDB_RESULT_SUCCESS on success.
868 */
869LIBFDB_API
870fdb_status fdb_switch_compaction_mode(fdb_file_handle *fhandle,
871                                      fdb_compaction_mode_t mode,
872                                      size_t new_threshold);
873
874/**
875 * Close a ForestDB file.
876 *
877 * @param fhandle Pointer to ForestDB file handle.
878 * @return FDB_RESULT_SUCCESS on success.
879 */
880LIBFDB_API
881fdb_status fdb_close(fdb_file_handle *fhandle);
882
883/**
884 * Destroy all resources associated with a ForestDB file permanently
885 * (e.g., buffer cache, in-memory WAL, indexes, daemon compaction thread)
886 * including current and past versions of the file.
887 * Note that all handles on the file should be closed through fdb_close
888 * calls before calling this API.
889 *
890 * NOTE: If manual compaction is being used, fdb_destroy() is best-effort only
891 *       and must be called with the correct filename
892 * Reason for best-effort in manual compaction case:
893 * FileA --> FileB --> FileC --> FileA --> FileD --> FileC -->DESTROY
894 * (In above case, FileB cannot be destroyed as its info is not
895 *  reachable from file path "FileC", api will wipe out FileA, FileC and FileD)
896 *
897 * @param filename The file path that needs to be destroyed
898 * @param fconfig  The forestdb configuration to determine
899 *        error log callbacks, manual/auto compaction etc
900 * @return FDB_RESULT_SUCCESS on success.
901 */
902LIBFDB_API
903fdb_status fdb_destroy(const char *filename,
904                       fdb_config *fconfig);
905
906/**
907 * Destroy all the resources (e.g., buffer cache, in-memory WAL indexes,
908 * daemon compaction thread, etc.) and then shutdown the ForestDB engine.
909 * Note that all the ForestDB files should be closed through fdb_close calls
910 * before calling this API.
911 *
912 * @return FDB_RESULT_SUCCESS on success.
913 */
914LIBFDB_API
915fdb_status fdb_shutdown();
916
917/**
918 * Begin a transaction with a given ForestDB file handle and isolation level.
919 * The transaction should be closed with fdb_end_transaction API call.
920 * The isolation levels supported are "read committed" or "read uncommitted".
921 * We plan to support both serializable and repeatable read isolation levels
922 * in the upcoming releases. For more information about database isolation levels,
923 * please refer to the following link:
924 * http://en.wikipedia.org/wiki/Isolation_level
925 *
926 * @param fhandle Pointer to ForestDB file handle.
927 * @param isolation_level Isolation level (i.e., read_committed or read_uncommitted)
928 *        of the transaction.
929 * @return FDB_RESULT_SUCCESS on success.
930 */
931LIBFDB_API
932fdb_status fdb_begin_transaction(fdb_file_handle *fhandle,
933                                 fdb_isolation_level_t isolation_level);
934
935/**
936 * End a transaction for a given ForestDB file handle by commiting all the dirty
937 * updates and releasing all the resouces allocated for that transaction.
938 *
939 * @param fhandle Pointer to ForestDB file handle.
940 * @param opt Commit option.
941 * @return FDB_RESULT_SUCCESS on success.
942 */
943LIBFDB_API
944fdb_status fdb_end_transaction(fdb_file_handle *fhandle,
945                               fdb_commit_opt_t opt);
946
947/**
948 * Abort the transaction for a given ForestDB file handle.
949 * All uncommitted dirty updates in the handle will be discarded.
950 *
951 * @param fhandle Pointer to ForestDB file handle.
952 * @return FDB_RESULT_SUCCESS on success.
953 */
954LIBFDB_API
955fdb_status fdb_abort_transaction(fdb_file_handle *fhandle);
956
957/**
958 * Open the KV store with a given instance name.
959 * The KV store should be closed with fdb_kvs_close API call.
960 *
961 * @param fhandle Pointer to ForestDB file handle.
962 * @param ptr_handle Pointer to the place where the KV store handle is
963 *        instantiated as a result of this API call.
964 * @param kvs_name The name of KV store to be opened. If the name is not given
965 *        (i.e., NULL is passed), the KV store instance named "default" will be
966 *        returned.
967 * @param config Pointer to the config instance that contains KV store configs.
968 *        If NULL is passed, then we use default settings of KV store configs.
969 * @return FDB_RESULT_SUCCESS on success.
970 */
971LIBFDB_API
972fdb_status fdb_kvs_open(fdb_file_handle *fhandle,
973                        fdb_kvs_handle **ptr_handle,
974                        const char *kvs_name,
975                        fdb_kvs_config *config);
976
977
978/**
979 * Open the default KV store.
980 * The KV store should be closed with fdb_kvs_close API call.
981 *
982 * @param fhandle Pointer to ForestDB file handle.
983 * @param ptr_handle Pointer to the place where the KV store handle is
984 *        instantiated as a result of this API call.
985 * @param config Pointer to the config instance that contains KV store configs.
986 *        If NULL is passed, then we use default settings of KV store configs.
987 * @return FDB_RESULT_SUCCESS on success.
988 */
989LIBFDB_API
990fdb_status fdb_kvs_open_default(fdb_file_handle *fhandle,
991                                fdb_kvs_handle **ptr_handle,
992                                fdb_kvs_config *config);
993
994/**
995 * Close the KV store handle.
996 *
997 * @param handle Pointer to KV store handle.
998 * @return FDB_RESULT_SUCCESS on success.
999 */
1000LIBFDB_API
1001fdb_status fdb_kvs_close(fdb_kvs_handle *handle);
1002
1003/**
1004 * Permanently drop a given KV store instance from a ForestDB file.
1005 *
1006 * @param fhandle Pointer to ForestDB file handle.
1007 * @param kvs_name The name of KV store instance to be removed. If the name is not given
1008 *        (i.e., NULL is passed), the KV store instance named "default" will be
1009 *        dropped.
1010 * @return FDB_RESULT_SUCCESS on success.
1011 */
1012LIBFDB_API
1013fdb_status fdb_kvs_remove(fdb_file_handle *fhandle,
1014                          const char *kvs_name);
1015
1016/**
1017 * Retrieve ForestDB error code as a string
1018 *
1019 * @param  err_code Error code
1020 * @return A text string that describes an error code. Note that the string
1021 *         returned is a constant. The application must not try to modify
1022 *         it or try to free the pointer to this string.
1023 */
1024LIBFDB_API
1025const char* fdb_error_msg(fdb_status err_code);
1026
1027#ifdef __cplusplus
1028}
1029#endif
1030
1031#endif
1032