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 _FDB_TYPES_H
19#define _FDB_TYPES_H
20
21#include <stdint.h>
22#include <stddef.h>
23#ifndef _MSC_VER
24#include <stdbool.h>
25#else
26#ifndef __cplusplus
27#pragma once
28#define false (0)
29#define true (1)
30#define bool int
31#endif
32#endif
33
34/**
35 * Maximum key length supported.
36 */
37#define FDB_MAX_KEYLEN (65408) // 2^16 - 64*2 (64: max chunk size)
38/**
39 * Maximum metadata length supported.
40 */
41#define FDB_MAX_METALEN (65535UL) // 2^16 - 1
42/**
43 * Maximum value length supported.
44 */
45#define FDB_MAX_BODYLEN (4294967295UL) // 2^32 - 1
46
47#ifdef __cplusplus
48extern "C" {
49#endif
50
51/**
52 * Flags to be passed to fdb_open() API
53 */
54typedef uint32_t fdb_open_flags;
55enum {
56    /**
57     * Open a ForestDB file with read-write mode and
58     * create a new empty ForestDB file if it doesn't exist.
59     */
60    FDB_OPEN_FLAG_CREATE = 1,
61    /**
62     * Open a ForestDB file in read only mode, but
63     * return an error if a file doesn't exist.
64     */
65    FDB_OPEN_FLAG_RDONLY = 2,
66
67    /**
68     * Open a ForestDB file with legacy CRC.
69     *
70     * This flag is intended to be used by upgrade tests.
71     *
72     * This flag is only valid if the file to be opened is a new file or an
73     * existing file with legacy CRC.
74     *
75     * Opening existing files which use CRC32C with this flag results
76     * in FDB_RESULT_INVALID_ARGS.
77     */
78    FDB_OPEN_WITH_LEGACY_CRC = 4
79};
80
81/**
82 * Options to be passed to fdb_commit() API.
83 * Combinational options can be possible.
84 */
85typedef uint8_t fdb_commit_opt_t;
86enum {
87    /**
88     * Perform commit without any options.
89     */
90    FDB_COMMIT_NORMAL = 0x00,
91    /**
92     * Manually flush WAL entries even though it doesn't
93     * reach the configured threshold
94     */
95    FDB_COMMIT_MANUAL_WAL_FLUSH = 0x01
96};
97
98/**
99 * Flag to enable / disable a sequence btree.
100 */
101typedef uint8_t fdb_seqtree_opt_t;
102enum {
103    FDB_SEQTREE_NOT_USE = 0,
104    FDB_SEQTREE_USE = 1
105};
106
107/**
108 * Durability options for ForestDB.
109 */
110typedef uint8_t fdb_durability_opt_t;
111enum {
112    /**
113     * Synchronous commit through OS page cache.
114     */
115    FDB_DRB_NONE = 0x0,
116    /**
117     * Synchronous commit through the direct IO option to bypass
118     * the OS page cache.
119     */
120    FDB_DRB_ODIRECT = 0x1,
121    /**
122     * Asynchronous commit through OS page cache.
123     */
124    FDB_DRB_ASYNC = 0x2,
125    /**
126     * Asynchronous commit through the direct IO option to bypass
127     * the OS page cache.
128     */
129    FDB_DRB_ODIRECT_ASYNC = 0x3
130};
131
132/**
133 * Options for compaction mode.
134 */
135typedef uint8_t fdb_compaction_mode_t;
136enum {
137    FDB_COMPACTION_MANUAL = 0,
138    FDB_COMPACTION_AUTO = 1
139};
140
141/**
142 * Transaction isolation level.
143 * Note that both serializable and repeatable-read isolation levels are not
144 * supported at this moment. We plan to support them in the future releases.
145 */
146typedef uint8_t fdb_isolation_level_t;
147enum {
148    // FDB_ISOLATION_SERIALIZABLE = 0,
149    // FDB_ISOLATION_REPEATABLE_READ = 1,
150    /**
151     * Prevent a transaction from reading uncommitted data from other
152     * transactions.
153     */
154    FDB_ISOLATION_READ_COMMITTED = 2,
155    /**
156     * Allow a transaction to see uncommitted data from other transaction.
157     */
158    FDB_ISOLATION_READ_UNCOMMITTED = 3
159};
160
161/**
162 * Pointer type definition of a customized compare function for fixed size key.
163 */
164typedef int (*fdb_custom_cmp_fixed)(void *a, void *b);
165
166/**
167 * Pointer type definition of a customized compare function for variable length key.
168 */
169typedef int (*fdb_custom_cmp_variable)(void *a, size_t len_a,
170                                       void *b, size_t len_b);
171
172typedef uint64_t fdb_seqnum_t;
173#define FDB_SNAPSHOT_INMEM ((fdb_seqnum_t)(-1))
174
175/**
176 * ForestDB doc structure definition
177 */
178typedef struct fdb_doc_struct {
179    /**
180     * key length.
181     */
182    size_t keylen;
183    /**
184     * metadata length.
185     */
186    size_t metalen;
187    /**
188     * doc body length.
189     */
190    size_t bodylen;
191    /**
192     * actual doc size written on disk.
193     */
194    size_t size_ondisk;
195    /**
196     * Pointer to doc's key.
197     */
198    void *key;
199    /**
200     * Sequence number assigned to a doc.
201     */
202    fdb_seqnum_t seqnum;
203    /**
204     * Offset to the doc (header + key + metadata + body) on disk.
205     */
206    uint64_t offset;
207    /**
208     * Pointer to doc's metadata.
209     */
210    void *meta;
211    /**
212     * Pointer to doc's body.
213     */
214    void *body;
215    /**
216     * Is a doc deleted?
217     */
218    bool deleted;
219    /**
220     * Flags for miscellaneous doc properties.
221     */
222     uint32_t flags;
223    /**
224     * Use the seqnum set by user instead of auto-generating.
225     */
226#define FDB_CUSTOM_SEQNUM 0x01
227} fdb_doc;
228
229/**
230 * Opaque reference to a ForestDB file handle, which is exposed in public APIs.
231 */
232typedef struct _fdb_file_handle fdb_file_handle;
233
234/**
235 * Opaque reference to a ForestDB KV store handle, which is exposed in public APIs.
236 */
237typedef struct _fdb_kvs_handle fdb_kvs_handle;
238
239/**
240 * Compaction status for callback function.
241 */
242typedef uint32_t fdb_compaction_status;
243enum {
244    FDB_CS_BEGIN = 0x1,
245    FDB_CS_MOVE_DOC = 0x2,
246    FDB_CS_BATCH_MOVE = 0x4,
247    FDB_CS_FLUSH_WAL = 0x8,
248    FDB_CS_END = 0x10, // invoked at the end of every phase of compaction
249    FDB_CS_COMPLETE = 0x20 // invoked on completion of compaction
250};
251
252/**
253 * Compaction decision returned if FDB_CS_MOVE_DOC callback option is used.
254 * If this compaction callback option is used then it is upto its corresponding
255 * callback function to specify, using the given return values below, if a
256 * given document should be retained in the newly compacted file or dropped.
257 */
258typedef int fdb_compact_decision;
259enum {
260    FDB_CS_KEEP_DOC = 0x0,
261    FDB_CS_DROP_DOC = 0x1
262};
263
264/**
265 * Pointer type definition of a callback function for compaction.
266 */
267typedef fdb_compact_decision (*fdb_compaction_callback)(
268                               fdb_file_handle *fhandle,
269                               fdb_compaction_status status,
270                               fdb_doc *doc,
271                               uint64_t last_oldfile_offset,
272                               uint64_t last_newfile_offset,
273                               void *ctx);
274
275/**
276  * Encryption algorithms known to ForestDB.
277  */
278typedef int fdb_encryption_algorithm_t;
279enum {
280    FDB_ENCRYPTION_NONE = 0,    /**< No encryption (default) */
281    FDB_ENCRYPTION_AES256 = 1   /**< AES with 256-bit key */
282};
283
284/**
285  * File encryption key.
286  */
287typedef struct {
288    fdb_encryption_algorithm_t algorithm;
289    uint8_t bytes[32];
290} fdb_encryption_key;
291
292/**
293 * ForestDB config options that are passed to fdb_open API.
294 */
295typedef struct {
296    /**
297     * Chunk size (bytes) that is used to build B+-tree at each level.
298     * It is set to 8 bytes by default and has a min value of 4 bytes
299     * and a max value of 64 bytes.
300     * This is a local config to each ForestDB file.
301     */
302    uint16_t chunksize;
303    /**
304     * Size of block that is a unit of IO operations.
305     * It is set to 4KB by default and has a min value of 1KB and a max value of
306     * 128KB. This is a global config that is used across all ForestDB files.
307     */
308    uint32_t blocksize;
309    /**
310     * Buffer cache size in bytes. If the size is set to zero, then the buffer
311     * cache is disabled. This is a global config that is used across all
312     * ForestDB files.
313     */
314    uint64_t buffercache_size;
315    /**
316     * WAL index size threshold in memory (4096 entries by default).
317     * This is a local config to each ForestDB file.
318     */
319    uint64_t wal_threshold;
320    /**
321     * Flag to enable flushing the WAL whenever it reaches its threshold size.
322     * This reduces memory usage when a lot of data is written before a commit.
323     */
324    bool wal_flush_before_commit;
325    /**
326     * Flag to enable automatic commit.
327     * This is a local config to each ForestDB file.
328     */
329    bool auto_commit;
330    /**
331     * Interval for purging logically deleted documents in the unit of second.
332     * It is set to 0 second (purge during next compaction) by default.
333     * This is a local config to each ForestDB file.
334     */
335    uint32_t purging_interval;
336    /**
337     * Flag to enable or disable a sequence B+-Tree.
338     * This is a local config to each ForestDB file.
339     */
340    fdb_seqtree_opt_t seqtree_opt;
341    /**
342     * Flag to enable synchronous or asynchronous commit options.
343     * This is a local config to each ForestDB file.
344     */
345    fdb_durability_opt_t durability_opt;
346    /**
347     * Flags for fdb_open API. It can be used for specifying read-only mode.
348     * This is a local config to each ForestDB file.
349     */
350    fdb_open_flags flags;
351    /**
352     * Maximum size (bytes) of temporary buffer for compaction (4MB by default).
353     * This is a local config to each ForestDB file.
354     */
355    uint32_t compaction_buf_maxsize;
356    /**
357     * Destroy all the cached blocks in the global buffer cache when a ForestDB
358     * file is closed. It is set to true by default. This is a global config
359     * that is used across all ForestDB files.
360     */
361    bool cleanup_cache_onclose;
362    /**
363     * Compress the body of document when it is written on disk. The compression
364     * is disabled by default. This is a global config that is used across all
365     * ForestDB files.
366     */
367    bool compress_document_body;
368    /**
369     * Flag to enable auto compaction for the file. The auto compaction is disabled
370     * by default.
371     * This is a local config to each ForestDB file.
372     */
373    fdb_compaction_mode_t compaction_mode;
374    /**
375     * Compaction threshold in the unit of percentage (%). It can be calculated
376     * as '(stale data size)/(total file size)'. The compaction daemon triggers
377     * compaction if this threshold is satisfied.
378     * Compaction will not be performed when this value is set to zero or 100.
379     * This is a local config to each ForestDB file.
380     */
381    uint8_t compaction_threshold;
382    /**
383     * The minimum filesize to perform compaction.
384     * This is a local config to each ForestDB file.
385     */
386    uint64_t compaction_minimum_filesize;
387    /**
388     * Duration that the compaction daemon periodically wakes up, in the unit of
389     * second. This is a global config that is used across all ForestDB files.
390     */
391    uint64_t compactor_sleep_duration;
392    /**
393     * Flag to enable supporting multiple KV instances in a DB instance.
394     * This is a global config that is used across all ForestDB files.
395     */
396    bool multi_kv_instances;
397    /**
398     * Duration that prefetching of DB file will be performed when the file
399     * is opened, in the unit of second. If the duration is set to zero,
400     * prefetching is disabled. This is a local config to each ForestDB file.
401     */
402    uint64_t prefetch_duration;
403    /**
404     * Number of in-memory WAL index partitions for a DB file.
405     * This is a local config to each ForestDB file.
406     */
407    uint16_t num_wal_partitions;
408    /**
409     * Number of buffer cache partitions for each DB file.
410     * This is a local config to each ForestDB file.
411     */
412    uint16_t num_bcache_partitions;
413    /**
414     * Callback function for compaction.
415     * This is a local config to each ForestDB file.
416     */
417    fdb_compaction_callback compaction_cb;
418    /**
419     * Mask to select when to invoke callback function during compaction.
420     * Note that mask value is a combination of flags defined in
421     * fdb_compaction_status.
422     * This is a local config to each ForestDB file.
423     */
424    uint32_t compaction_cb_mask;
425    /**
426     * Auxiliary data for compaction callback function.
427     * This is a local config to each ForestDB file.
428     */
429    void *compaction_cb_ctx;
430    /**
431     * Maximum probability (range: 20% ~ 100%) for the compactor to grab
432     * the writer's lock during each batch write in case the writer's throughput
433     * is faster than the compactor, to make sure that the compactor can keep
434     * pace with the writer and eventually complete the compaction.
435     * Note that we plan to reduce the compaction overhead significantly soon
436     * and deprecate this parameter when it is not needed anymore.
437     * This is a local config to each ForestDB file.
438     */
439    size_t max_writer_lock_prob;
440    /**
441     * Number of daemon compactor threads. It is set to 4 threads by default.
442     * If many files are opened and accessed concurrently, then it is
443     * recommended to increase this value if the host machine has enough cores
444     * and disk I/O bandwidth.
445     * This is a global config that is configured across all ForestDB files.
446     */
447    size_t num_compactor_threads;
448    /**
449     * Number of background flusher threads. It is set to 4 threads by default.
450     * For write intensive workloads with large commit intervals and many files
451     * it is recommended to increase this value if the host machine has enough
452     * cores and disk I/O bandwidth.
453     * This is a global config that is configured across all ForestDB files.
454     */
455    size_t num_bgflusher_threads;
456    /**
457     * Encryption key for the database. Default value has algorithm = FDB_ENCRYPTION_NONE,
458     * i.e. no encryption. When a database file is being created, its contents will be
459     * encrypted with the given key. When a database is re-opened, the same key
460     * must be given, otherwise fdb_open will fail with error FDB_RESULT_NO_DB_HEADERS.
461     */
462    fdb_encryption_key encryption_key;
463
464} fdb_config;
465
466typedef struct {
467    /**
468     * Flag to create a new empty KV store instance in a DB instance,
469     * if it doesn't exist.
470     */
471    bool create_if_missing;
472    /**
473     * Customized compare function for an KV store instance.
474     */
475    fdb_custom_cmp_variable custom_cmp;
476} fdb_kvs_config;
477
478/**
479 * Pointer type definition of an error logging callback function.
480 */
481typedef void (*fdb_log_callback)(int err_code, const char *err_msg, void *ctx_data);
482
483/**
484 * Function pointer definition of the fatal error callback function.
485 */
486typedef void (*fdb_fatal_error_callback)(void);
487
488/**
489 * ForestDB iterator options.Combinational options can be passed to the iterator.
490 * For example, FDB_ITR_SKIP_MIN_KEY | FDB_ITR_SKIP_MAX_KEY means
491 * "The smallest and largest keys in the iteration ragne won't be returned by the
492 * iterator".
493 */
494typedef uint16_t fdb_iterator_opt_t;
495enum {
496    /**
497     * Return both key and value through iterator.
498     */
499    FDB_ITR_NONE = 0x00,
500    /**
501     * Return only non-deleted items through iterator.
502     */
503    FDB_ITR_NO_DELETES = 0x02,
504    /**
505     * The lowest key specified will not be returned by the iterator.
506     */
507    FDB_ITR_SKIP_MIN_KEY = 0x04,
508    /**
509     * The highest key specified will not be returned by the iterator.
510     */
511    FDB_ITR_SKIP_MAX_KEY = 0x08
512};
513
514/**
515 * ForestDB iterator seek options.
516 */
517typedef uint8_t fdb_iterator_seek_opt_t;
518enum {
519    /**
520     * If seek_key does not exist return the next sorted key higher than it.
521     */
522    FDB_ITR_SEEK_HIGHER = 0x00,
523    /**
524     * If seek_key does not exist return the previous sorted key lower than it.
525     */
526    FDB_ITR_SEEK_LOWER = 0x01
527};
528
529/**
530 * Opaque reference to ForestDB iterator structure definition, which is exposed
531 * in public APIs.
532 */
533typedef struct _fdb_iterator fdb_iterator;
534
535/**
536 * Using off_t turned out to be a real challenge. On "unix-like" systems
537 * its size is set by a combination of #defines like: _LARGE_FILE,
538 * _FILE_OFFSET_BITS and/or _LARGEFILE_SOURCE etc. The interesting
539 * part is however Windows.
540 *
541 * Windows follows the LLP64 data model:
542 * http://en.wikipedia.org/wiki/LLP64#64-bit_data_models
543 *
544 * This means both the int and long int types have a size of 32 bits
545 * regardless if it's a 32 or 64 bits Windows system.
546 *
547 * And Windows defines the type off_t as being a signed long integer:
548 * http://msdn.microsoft.com/en-us/library/323b6b3k.aspx
549 *
550 * This means we can't use off_t on Windows if we deal with files
551 * that can have a size of 2Gb or more.
552 */
553typedef int64_t cs_off_t;
554
555/**
556 * Information about a ForestDB file
557 */
558typedef struct {
559    /**
560     * A file name.
561     */
562    const char* filename;
563    /**
564     * A new file name that is used after compaction.
565     */
566    const char* new_filename;
567    /**
568     * Total number of non-deleted documents aggregated across all KV stores.
569     */
570    uint64_t doc_count;
571    /**
572     * Disk space actively used by the file.
573     */
574    uint64_t space_used;
575    /**
576     * Total disk space used by the file, including stale btree nodes and docs.
577     */
578    uint64_t file_size;
579    /**
580     * Number of KV store instances in a ForestDB file
581     */
582    size_t num_kv_stores;
583} fdb_file_info;
584
585/**
586 * Information about a ForestDB KV store
587 */
588typedef struct {
589    /**
590     * A KV store name.
591     */
592    const char* name;
593    /**
594     * Last sequence number assigned.
595     */
596    fdb_seqnum_t last_seqnum;
597    /**
598     * Total number of non-deleted documents in a KV store.
599     */
600    uint64_t doc_count;
601    /**
602     * Disk space actively used by the KV store.
603     */
604    uint64_t space_used;
605    /**
606     * File handle that owns the KV store.
607     */
608    fdb_file_handle* file;
609} fdb_kvs_info;
610
611/**
612 * Information about a ForestDB KV store's operational counters
613 */
614typedef struct {
615    /**
616     * Number of fdb_set operations.
617     */
618    uint64_t num_sets;
619    /**
620     * Number of fdb_del operations.
621     */
622    uint64_t num_dels;
623    /**
624     * Number of fdb_commit operations.
625     */
626    uint64_t num_commits;
627    /**
628     * Number of fdb_compact operations on underlying file.
629     */
630    uint64_t num_compacts;
631    /**
632     * Number of fdb_get* (includes metaonly, byseq etc) operations.
633     */
634    uint64_t num_gets;
635    /**
636     * Number of fdb_iterator_get* (includes meta_only) operations.
637     */
638    uint64_t num_iterator_gets;
639    /**
640     * Number of fdb_iterator_moves (includes next,prev,seek) operations.
641     */
642    uint64_t num_iterator_moves;
643} fdb_kvs_ops_info;
644
645/**
646 * List of ForestDB KV store names
647 */
648typedef struct {
649    /**
650     * Number of KV store names listed in kvs_names.
651     */
652    size_t num_kvs_names;
653    /**
654     * Pointer to array of KV store names.
655     */
656    char **kvs_names;
657} fdb_kvs_name_list;
658
659/**
660 * Persisted Snapshot Marker in file (Sequence number + KV Store name)
661 */
662typedef struct {
663    /**
664     * NULL-terminated KV Store name.
665     */
666    char *kv_store_name;
667    /**
668     * A Sequence number of the above KV store, which results from an
669     * fdb_commit operation.
670     */
671    fdb_seqnum_t seqnum;
672} fdb_kvs_commit_marker_t;
673
674/**
675 * An opaque file-level snapshot marker that can be used to purge
676 * stale data up to a given file-level snapshot marker.
677*/
678typedef uint64_t fdb_snapshot_marker_t;
679
680/**
681 * Snapshot Information structure for a ForestDB database file.
682 */
683typedef struct {
684    /**
685     * Opaque file-level snapshot marker that can be passed to
686     * fdb_compact_upto() api.
687     */
688    fdb_snapshot_marker_t marker;
689    /**
690     * Number of KV store snapshot markers in the kvs_markers array.
691     */
692    int64_t num_kvs_markers;
693    /**
694     * Pointer to an array of {kv_store_name, committed_seqnum} pairs.
695     */
696    fdb_kvs_commit_marker_t *kvs_markers;
697} fdb_snapshot_info_t;
698
699#ifdef __cplusplus
700}
701#endif
702
703#endif
704