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