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                               const char *kv_store_name,
271                               fdb_doc *doc,
272                               uint64_t last_oldfile_offset,
273                               uint64_t last_newfile_offset,
274                               void *ctx);
275
276/**
277  * Encryption algorithms known to ForestDB.
278  */
279typedef int fdb_encryption_algorithm_t;
280enum {
281    FDB_ENCRYPTION_NONE = 0,    /**< No encryption (default) */
282    FDB_ENCRYPTION_AES256 = 1   /**< AES with 256-bit key */
283};
284
285/**
286  * File encryption key.
287  */
288typedef struct {
289    fdb_encryption_algorithm_t algorithm;
290    uint8_t bytes[32];
291} fdb_encryption_key;
292
293/**
294 * ForestDB config options that are passed to fdb_open API.
295 */
296typedef struct {
297    /**
298     * Chunk size (bytes) that is used to build B+-tree at each level.
299     * It is set to 8 bytes by default and has a min value of 4 bytes
300     * and a max value of 64 bytes.
301     * This is a local config to each ForestDB file.
302     */
303    uint16_t chunksize;
304    /**
305     * Size of block that is a unit of IO operations.
306     * It is set to 4KB by default and has a min value of 1KB and a max value of
307     * 128KB. This is a global config that is used across all ForestDB files.
308     */
309    uint32_t blocksize;
310    /**
311     * Buffer cache size in bytes. If the size is set to zero, then the buffer
312     * cache is disabled. This is a global config that is used across all
313     * ForestDB files.
314     */
315    uint64_t buffercache_size;
316    /**
317     * WAL index size threshold in memory (4096 entries by default).
318     * This is a local config to each ForestDB file.
319     */
320    uint64_t wal_threshold;
321    /**
322     * Flag to enable flushing the WAL whenever it reaches its threshold size.
323     * This reduces memory usage when a lot of data is written before a commit.
324     */
325    bool wal_flush_before_commit;
326    /**
327     * Flag to enable automatic commit.
328     * This is a local config to each ForestDB file.
329     */
330    bool auto_commit;
331    /**
332     * Interval for purging logically deleted documents in the unit of second.
333     * It is set to 0 second (purge during next compaction) by default.
334     * This is a local config to each ForestDB file.
335     */
336    uint32_t purging_interval;
337    /**
338     * Flag to enable or disable a sequence B+-Tree.
339     * This is a local config to each ForestDB file.
340     */
341    fdb_seqtree_opt_t seqtree_opt;
342    /**
343     * Flag to enable synchronous or asynchronous commit options.
344     * This is a local config to each ForestDB file.
345     */
346    fdb_durability_opt_t durability_opt;
347    /**
348     * Flags for fdb_open API. It can be used for specifying read-only mode.
349     * This is a local config to each ForestDB file.
350     */
351    fdb_open_flags flags;
352    /**
353     * Maximum size (bytes) of temporary buffer for compaction (4MB by default).
354     * This is a local config to each ForestDB file.
355     */
356    uint32_t compaction_buf_maxsize;
357    /**
358     * Destroy all the cached blocks in the global buffer cache when a ForestDB
359     * file is closed. It is set to true by default. This is a global config
360     * that is used across all ForestDB files.
361     */
362    bool cleanup_cache_onclose;
363    /**
364     * Compress the body of document when it is written on disk. The compression
365     * is disabled by default. This is a global config that is used across all
366     * ForestDB files.
367     */
368    bool compress_document_body;
369    /**
370     * Flag to enable auto compaction for the file. The auto compaction is disabled
371     * by default.
372     * This is a local config to each ForestDB file.
373     */
374    fdb_compaction_mode_t compaction_mode;
375    /**
376     * Compaction threshold in the unit of percentage (%). It can be calculated
377     * as '(stale data size)/(total file size)'. The compaction daemon triggers
378     * compaction if this threshold is satisfied.
379     * Compaction will not be performed when this value is set to zero or 100.
380     * This is a local config to each ForestDB file.
381     */
382    uint8_t compaction_threshold;
383    /**
384     * The minimum filesize to perform compaction.
385     * This is a local config to each ForestDB file.
386     */
387    uint64_t compaction_minimum_filesize;
388    /**
389     * Duration that the compaction daemon periodically wakes up, in the unit of
390     * second. This is a global config that is used across all ForestDB files.
391     */
392    uint64_t compactor_sleep_duration;
393    /**
394     * Flag to enable supporting multiple KV instances in a DB instance.
395     * This is a global config that is used across all ForestDB files.
396     */
397    bool multi_kv_instances;
398    /**
399     * Duration that prefetching of DB file will be performed when the file
400     * is opened, in the unit of second. If the duration is set to zero,
401     * prefetching is disabled. This is a local config to each ForestDB file.
402     */
403    uint64_t prefetch_duration;
404    /**
405     * Number of in-memory WAL index partitions for a DB file.
406     * This is a local config to each ForestDB file.
407     */
408    uint16_t num_wal_partitions;
409    /**
410     * Number of buffer cache partitions for each DB file.
411     * This is a local config to each ForestDB file.
412     */
413    uint16_t num_bcache_partitions;
414    /**
415     * Callback function for compaction.
416     * This is a local config to each ForestDB file.
417     */
418    fdb_compaction_callback compaction_cb;
419    /**
420     * Mask to select when to invoke callback function during compaction.
421     * Note that mask value is a combination of flags defined in
422     * fdb_compaction_status.
423     * This is a local config to each ForestDB file.
424     */
425    uint32_t compaction_cb_mask;
426    /**
427     * Auxiliary data for compaction callback function.
428     * This is a local config to each ForestDB file.
429     */
430    void *compaction_cb_ctx;
431    /**
432     * Maximum probability (range: 20% ~ 100%) for the compactor to grab
433     * the writer's lock during each batch write in case the writer's throughput
434     * is faster than the compactor, to make sure that the compactor can keep
435     * pace with the writer and eventually complete the compaction.
436     * Note that we plan to reduce the compaction overhead significantly soon
437     * and deprecate this parameter when it is not needed anymore.
438     * This is a local config to each ForestDB file.
439     */
440    size_t max_writer_lock_prob;
441    /**
442     * Number of daemon compactor threads. It is set to 4 threads by default.
443     * If many files are opened and accessed concurrently, then it is
444     * recommended to increase this value if the host machine has enough cores
445     * and disk I/O bandwidth.
446     * This is a global config that is configured across all ForestDB files.
447     */
448    size_t num_compactor_threads;
449    /**
450     * Number of background flusher threads. It is set to 4 threads by default.
451     * For write intensive workloads with large commit intervals and many files
452     * it is recommended to increase this value if the host machine has enough
453     * cores and disk I/O bandwidth.
454     * This is a global config that is configured across all ForestDB files.
455     */
456    size_t num_bgflusher_threads;
457    /**
458     * Encryption key for the database. Default value has algorithm = FDB_ENCRYPTION_NONE,
459     * i.e. no encryption. When a database file is being created, its contents will be
460     * encrypted with the given key. When a database is re-opened, the same key
461     * must be given, otherwise fdb_open will fail with error FDB_RESULT_NO_DB_HEADERS.
462     */
463    fdb_encryption_key encryption_key;
464
465} fdb_config;
466
467typedef struct {
468    /**
469     * Flag to create a new empty KV store instance in a DB instance,
470     * if it doesn't exist.
471     */
472    bool create_if_missing;
473    /**
474     * Customized compare function for an KV store instance.
475     */
476    fdb_custom_cmp_variable custom_cmp;
477} fdb_kvs_config;
478
479/**
480 * Pointer type definition of an error logging callback function.
481 */
482typedef void (*fdb_log_callback)(int err_code, const char *err_msg, void *ctx_data);
483
484/**
485 * Function pointer definition of the fatal error callback function.
486 */
487typedef void (*fdb_fatal_error_callback)(void);
488
489/**
490 * ForestDB iterator options.Combinational options can be passed to the iterator.
491 * For example, FDB_ITR_SKIP_MIN_KEY | FDB_ITR_SKIP_MAX_KEY means
492 * "The smallest and largest keys in the iteration ragne won't be returned by the
493 * iterator".
494 */
495typedef uint16_t fdb_iterator_opt_t;
496enum {
497    /**
498     * Return both key and value through iterator.
499     */
500    FDB_ITR_NONE = 0x00,
501    /**
502     * Return only non-deleted items through iterator.
503     */
504    FDB_ITR_NO_DELETES = 0x02,
505    /**
506     * The lowest key specified will not be returned by the iterator.
507     */
508    FDB_ITR_SKIP_MIN_KEY = 0x04,
509    /**
510     * The highest key specified will not be returned by the iterator.
511     */
512    FDB_ITR_SKIP_MAX_KEY = 0x08
513};
514
515/**
516 * ForestDB iterator seek options.
517 */
518typedef uint8_t fdb_iterator_seek_opt_t;
519enum {
520    /**
521     * If seek_key does not exist return the next sorted key higher than it.
522     */
523    FDB_ITR_SEEK_HIGHER = 0x00,
524    /**
525     * If seek_key does not exist return the previous sorted key lower than it.
526     */
527    FDB_ITR_SEEK_LOWER = 0x01
528};
529
530/**
531 * Opaque reference to ForestDB iterator structure definition, which is exposed
532 * in public APIs.
533 */
534typedef struct _fdb_iterator fdb_iterator;
535
536/**
537 * Using off_t turned out to be a real challenge. On "unix-like" systems
538 * its size is set by a combination of #defines like: _LARGE_FILE,
539 * _FILE_OFFSET_BITS and/or _LARGEFILE_SOURCE etc. The interesting
540 * part is however Windows.
541 *
542 * Windows follows the LLP64 data model:
543 * http://en.wikipedia.org/wiki/LLP64#64-bit_data_models
544 *
545 * This means both the int and long int types have a size of 32 bits
546 * regardless if it's a 32 or 64 bits Windows system.
547 *
548 * And Windows defines the type off_t as being a signed long integer:
549 * http://msdn.microsoft.com/en-us/library/323b6b3k.aspx
550 *
551 * This means we can't use off_t on Windows if we deal with files
552 * that can have a size of 2Gb or more.
553 */
554typedef int64_t cs_off_t;
555
556/**
557 * Information about a ForestDB file
558 */
559typedef struct {
560    /**
561     * A file name.
562     */
563    const char* filename;
564    /**
565     * A new file name that is used after compaction.
566     */
567    const char* new_filename;
568    /**
569     * Total number of non-deleted documents aggregated across all KV stores.
570     */
571    uint64_t doc_count;
572    /**
573     * Total number of deleted documents aggregated across all KV stores.
574     */
575    uint64_t deleted_count;
576    /**
577     * Disk space actively used by the file.
578     */
579    uint64_t space_used;
580    /**
581     * Total disk space used by the file, including stale btree nodes and docs.
582     */
583    uint64_t file_size;
584    /**
585     * Number of KV store instances in a ForestDB file
586     */
587    size_t num_kv_stores;
588} fdb_file_info;
589
590/**
591 * Information about a ForestDB KV store
592 */
593typedef struct {
594    /**
595     * A KV store name.
596     */
597    const char* name;
598    /**
599     * Last sequence number assigned.
600     */
601    fdb_seqnum_t last_seqnum;
602    /**
603     * Total number of non-deleted documents in a KV store.
604     */
605    uint64_t doc_count;
606    /**
607     * Total number of deleted documents in a KV store.
608     */
609    uint64_t deleted_count;
610    /**
611     * Disk space actively used by the KV store.
612     */
613    uint64_t space_used;
614    /**
615     * File handle that owns the KV store.
616     */
617    fdb_file_handle* file;
618} fdb_kvs_info;
619
620/**
621 * Information about a ForestDB KV store's operational counters
622 */
623typedef struct {
624    /**
625     * Number of fdb_set operations.
626     */
627    uint64_t num_sets;
628    /**
629     * Number of fdb_del operations.
630     */
631    uint64_t num_dels;
632    /**
633     * Number of fdb_commit operations.
634     */
635    uint64_t num_commits;
636    /**
637     * Number of fdb_compact operations on underlying file.
638     */
639    uint64_t num_compacts;
640    /**
641     * Number of fdb_get* (includes metaonly, byseq etc) operations.
642     */
643    uint64_t num_gets;
644    /**
645     * Number of fdb_iterator_get* (includes meta_only) operations.
646     */
647    uint64_t num_iterator_gets;
648    /**
649     * Number of fdb_iterator_moves (includes next,prev,seek) operations.
650     */
651    uint64_t num_iterator_moves;
652} fdb_kvs_ops_info;
653
654/**
655 * List of ForestDB KV store names
656 */
657typedef struct {
658    /**
659     * Number of KV store names listed in kvs_names.
660     */
661    size_t num_kvs_names;
662    /**
663     * Pointer to array of KV store names.
664     */
665    char **kvs_names;
666} fdb_kvs_name_list;
667
668/**
669 * Persisted Snapshot Marker in file (Sequence number + KV Store name)
670 */
671typedef struct {
672    /**
673     * NULL-terminated KV Store name.
674     */
675    char *kv_store_name;
676    /**
677     * A Sequence number of the above KV store, which results from an
678     * fdb_commit operation.
679     */
680    fdb_seqnum_t seqnum;
681} fdb_kvs_commit_marker_t;
682
683/**
684 * An opaque file-level snapshot marker that can be used to purge
685 * stale data up to a given file-level snapshot marker.
686*/
687typedef uint64_t fdb_snapshot_marker_t;
688
689/**
690 * Snapshot Information structure for a ForestDB database file.
691 */
692typedef struct {
693    /**
694     * Opaque file-level snapshot marker that can be passed to
695     * fdb_compact_upto() api.
696     */
697    fdb_snapshot_marker_t marker;
698    /**
699     * Number of KV store snapshot markers in the kvs_markers array.
700     */
701    int64_t num_kvs_markers;
702    /**
703     * Pointer to an array of {kv_store_name, committed_seqnum} pairs.
704     */
705    fdb_kvs_commit_marker_t *kvs_markers;
706} fdb_snapshot_info_t;
707
708#ifdef __cplusplus
709}
710#endif
711
712#endif
713