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