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 _INTERNAL_TYPES_H
19 #define _INTERNAL_TYPES_H
20 
21 #include <stdint.h>
22 
23 #include "libforestdb/fdb_types.h"
24 #include "common.h"
25 #include "atomic.h"
26 #include "avltree.h"
27 #include "atomic.h"
28 
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32 
33 struct hbtrie;
34 struct btree;
35 struct filemgr;
36 struct btreeblk_handle;
37 struct docio_handle;
38 struct btree_blk_ops;
39 struct snap_handle;
40 
41 #define OFFSET_SIZE (sizeof(uint64_t))
42 
43 #define FDB_MAX_KEYLEN_INTERNAL (65520)
44 
45 /**
46  * Error logging callback struct definition.
47  */
48 typedef struct {
49     /**
50      * Error logging callback function.
51      */
52     fdb_log_callback callback;
53     /**
54      * Application-specific context data that is passed to the logging callback
55      * function.
56      */
57     void *ctx_data;
58 } err_log_callback;
59 
60 typedef struct _fdb_transaction fdb_txn;
61 
62 typedef uint64_t fdb_kvs_id_t;
63 
64 typedef uint8_t kvs_type_t;
65 enum {
66     KVS_ROOT = 0,
67     KVS_SUB = 1
68 };
69 
70 struct list;
71 struct kvs_opened_node;
72 
73 /**
74  * KV store info for each handle.
75  */
76 struct kvs_info {
77     /**
78      * KV store type.
79      */
80     kvs_type_t type;
81     /**
82      * KV store ID.
83      */
84     fdb_kvs_id_t id;
85     /**
86      * Pointer to root handle.
87      */
88     fdb_kvs_handle *root;
89 };
90 
91 /**
92  * Attributes in KV store statistics.
93  */
94 typedef enum {
95     KVS_STAT_NLIVENODES,
96     KVS_STAT_NDOCS,
97     KVS_STAT_DATASIZE,
98     KVS_STAT_WAL_NDOCS,
99     KVS_STAT_WAL_NDELETES
100 } kvs_stat_attr_t;
101 
102 /**
103  * KV store statistics.
104  */
105 struct kvs_stat {
106     /**
107      * The number of live index nodes.
108      */
109     uint64_t nlivenodes;
110     /**
111      * The number of documents.
112      */
113     uint64_t ndocs;
114     /**
115      * The amount of space occupied by documents.
116      */
117     uint64_t datasize;
118     /**
119      * The number of documents in WAL.
120      */
121     uint64_t wal_ndocs;
122     /**
123      * The number of deleted documents in WAL.
124      */
125     uint64_t wal_ndeletes;
126 };
127 
128 /**
129  * Atomic counters of operational statistics in ForestDB KV store.
130  */
131 struct kvs_ops_stat {
132     /**
133      * Number of fdb_set operations.
134      */
135     atomic_uint64_t num_sets;
136     /**
137      * Number of fdb_del operations.
138      */
139     atomic_uint64_t num_dels;
140     /**
141      * Number of fdb_commit operations.
142      */
143     atomic_uint64_t num_commits;
144     /**
145      * Number of fdb_compact operations on underlying file.
146      */
147     atomic_uint64_t num_compacts;
148     /**
149      * Number of fdb_get* (includes metaonly, byseq etc) operations.
150      */
151     atomic_uint64_t num_gets;
152     /**
153      * Number of fdb_iterator_get* (includes meta_only) operations.
154      */
155     atomic_uint64_t num_iterator_gets;
156     /**
157      * Number of fdb_iterator_moves (includes next,prev,seek) operations.
158      */
159     atomic_uint64_t num_iterator_moves;
160 };
161 
162 #define FHANDLE_ROOT_OPENED (0x1)
163 #define FHANDLE_ROOT_INITIALIZED (0x2)
164 #define FHANDLE_ROOT_CUSTOM_CMP (0x4)
165 /**
166  * ForestDB file handle definition.
167  */
168 struct _fdb_file_handle {
169     /**
170      * The root KV store handle.
171      */
172     fdb_kvs_handle *root;
173     /**
174      * List of opened default KV store handles
175      * (except for the root handle).
176      */
177     struct list *handles;
178     /**
179      * List of custom compare functions assigned by user
180      */
181     struct list *cmp_func_list;
182     /**
183      * Flags for the file handle.
184      */
185     uint64_t flags;
186     /**
187      * Spin lock for the file handle.
188      */
189     spin_t lock;
190 };
191 
192 /**
193  * ForestDB KV store key comparison callback context
194  */
195 struct _fdb_key_cmp_info {
196     /**
197      * ForestDB KV store level config.
198      */
199     fdb_kvs_config kvs_config;
200     /**
201      * KV store information.
202      */
203     struct kvs_info *kvs;
204 };
205 
206 /**
207  * ForestDB KV store handle definition.
208  */
209 struct _fdb_kvs_handle {
210     /**
211      * ForestDB KV store level config. (Please retain as first struct member)
212      */
213     fdb_kvs_config kvs_config;
214     /**
215      * KV store information. (Please retain as second struct member)
216      */
217     struct kvs_info *kvs;
218     /**
219      * Operational statistics for this kv store.
220      */
221     struct kvs_ops_stat *op_stats;
222     /**
223      * Pointer to the corresponding file handle.
224      */
225     fdb_file_handle *fhandle;
226     /**
227      * HB+-Tree Trie instance.
228      */
229     struct hbtrie *trie;
230     /**
231      * Document key B+-Tree instance.
232      * Used for custom compare function of variable length key
233      */
234     struct btree *idtree;
235     /**
236      * Sequence B+-Tree instance.
237      */
238     union {
239         struct btree *seqtree; // single KV instance mode
240         struct hbtrie *seqtrie; // multi KV instance mode
241     };
242     /**
243      * File manager instance.
244      */
245     struct filemgr *file;
246     /**
247      * Doc IO handle instance.
248      */
249     struct docio_handle *dhandle;
250     /**
251      * B+-Tree handle instance.
252      */
253     struct btreeblk_handle *bhandle;
254     /**
255      * B+-Tree block operation handle.
256      */
257     struct btree_blk_ops *btreeblkops;
258     /**
259      * File manager IO operation handle.
260      */
261     struct filemgr_ops *fileops;
262     /**
263      * ForestDB file level config.
264      */
265     fdb_config config;
266     /**
267      * Error logging callback.
268      */
269     err_log_callback log_callback;
270     /**
271      * File header revision number.
272      */
273     uint64_t cur_header_revnum;
274     /**
275      * Last header's block ID.
276      */
277     uint64_t last_hdr_bid;
278     /**
279      * Block ID of a header created with most recent WAL flush.
280      */
281     uint64_t last_wal_flush_hdr_bid;
282     /**
283      * File offset of a document containing KV instance info.
284      */
285     uint64_t kv_info_offset;
286     /**
287      * Snapshot Information.
288      */
289     struct snap_handle *shandle;
290     /**
291      * KV store's current sequence number.
292      */
293     fdb_seqnum_t seqnum;
294     /**
295      * KV store's max sequence number for snapshot or rollback.
296      */
297     fdb_seqnum_t max_seqnum;
298     /**
299      * Virtual filename (DB instance filename given by users).
300      */
301     char *filename;
302     /**
303      * Transaction handle.
304      */
305     fdb_txn *txn;
306     /**
307      * Atomic flag to detect if handles are being shared among threads.
308      */
309     atomic_uint8_t handle_busy;
310     /**
311      * Flag that indicates whether this handle made dirty updates or not.
312      */
313     uint8_t dirty_updates;
314     /**
315      * List element that will be inserted into 'handles' list in the root handle.
316      */
317     struct kvs_opened_node *node;
318 #ifdef _TRACE_HANDLES
319     struct avl_node avl_trace;
320 #endif
321 };
322 
323 struct hbtrie_iterator;
324 struct avl_tree;
325 struct avl_node;
326 
327 /**
328  * ForestDB iterator cursor movement direction
329  */
330 typedef uint8_t fdb_iterator_dir_t;
331 enum {
332     /**
333      * Iterator cursor default.
334      */
335     FDB_ITR_DIR_NONE = 0x00,
336     /**
337      * Iterator cursor moving forward
338      */
339     FDB_ITR_FORWARD = 0x01,
340     /**
341      * Iterator cursor moving backwards
342      */
343     FDB_ITR_REVERSE = 0x02
344 };
345 
346 /**
347  * ForestDB iterator status
348  */
349 typedef uint8_t fdb_iterator_status_t;
350 enum {
351     /**
352      * The last returned doc was retrieved from the main index.
353      */
354     FDB_ITR_IDX = 0x00,
355     /**
356      * The last returned doc was retrieved from the WAL.
357      */
358     FDB_ITR_WAL = 0x01
359 };
360 
361 /**
362  * ForestDB iterator structure definition.
363  */
364 struct _fdb_iterator {
365     /**
366      * ForestDB KV store handle.
367      */
368     fdb_kvs_handle *handle;
369     /**
370      * HB+Trie iterator instance.
371      */
372     struct hbtrie_iterator *hbtrie_iterator;
373     /**
374      * B+Tree iterator for sequence number iteration
375      */
376     struct btree_iterator *seqtree_iterator;
377     /**
378      * HB+Trie iterator for sequence number iteration
379      * (for multiple KV instance mode)
380      */
381     struct hbtrie_iterator *seqtrie_iterator;
382     /**
383      * Current seqnum pointed by the iterator.
384      */
385     fdb_seqnum_t _seqnum;
386     /**
387      * AVL tree for WAL entries.
388      */
389     struct avl_tree *wal_tree;
390     /**
391      * Cursor instance of AVL tree for WAL entries.
392      */
393     struct avl_node *tree_cursor;
394     /**
395      * Start position of AVL tree cursor.
396      */
397     struct avl_node *tree_cursor_start;
398     /**
399      * Previous position of AVL tree cursor.
400      */
401     struct avl_node *tree_cursor_prev;
402     /**
403      * Iterator start key.
404      */
405     void *start_key;
406     union {
407         /**
408          * Iterator start seqnum.
409          */
410         fdb_seqnum_t start_seqnum;
411         /**
412          * Start key length.
413          */
414         size_t start_keylen;
415     };
416     /**
417      * Iterator end key.
418      */
419     void *end_key;
420     union {
421         /**
422          * Iterator end seqnum.
423          */
424         fdb_seqnum_t end_seqnum;
425         /**
426          * End key length.
427          */
428         size_t end_keylen;
429     };
430     /**
431      * Iterator option.
432      */
433     fdb_iterator_opt_t opt;
434     /**
435      * Iterator cursor direction status.
436      */
437     fdb_iterator_dir_t direction;
438     /**
439      * The last returned document info.
440      */
441     fdb_iterator_status_t status;
442     /**
443      * Current key pointed by the iterator.
444      */
445     void *_key;
446     /**
447      * Length of key pointed by the iterator.
448      */
449     size_t _keylen;
450     /**
451      * Key offset.
452      */
453     uint64_t _offset;
454     /**
455      * Doc IO handle instance to the correct file.
456      */
457     struct docio_handle *_dhandle;
458     /**
459      * Cursor offset to key, meta and value on disk
460      */
461     uint64_t _get_offset;
462 };
463 
464 struct wal_txn_wrapper;
465 
466 /**
467  * ForestDB transaction structure definition.
468  */
469 struct _fdb_transaction {
470     /**
471      * ForestDB KV store handle.
472      */
473     fdb_kvs_handle *handle;
474     /**
475      * Block ID of the last header before the transaction begins.
476      */
477     uint64_t prev_hdr_bid;
478     /**
479      * List of dirty WAL items.
480      */
481     struct list *items;
482     /**
483      * Transaction isolation level.
484      */
485     fdb_isolation_level_t isolation;
486     /**
487      * Pointer to transaction wrapper.
488      */
489     struct wal_txn_wrapper *wrapper;
490 };
491 
492 /* Global KV store header for each file
493  */
494 struct kvs_header {
495     /**
496      * Monotonically increasing counter to generate KV store IDs.
497      */
498     fdb_kvs_id_t id_counter;
499     /**
500      * The custom comparison function if set by user.
501      */
502     fdb_custom_cmp_variable default_kvs_cmp;
503     /**
504      * A tree linking all KV stores in a file by their KV store name.
505      */
506     struct avl_tree *idx_name;
507     /**
508      * A tree linking all KV stores in file by their ID.
509      */
510     struct avl_tree *idx_id;
511     /**
512      * Boolean to determine if custom compare function for a KV store is set.
513      */
514     uint8_t custom_cmp_enabled;
515     /**
516      * lock to protect access to the idx_name and idx_id trees above
517      */
518     spin_t lock;
519 };
520 
521 /** Mapping data for each KV store in DB file.
522  * (global & most fields are persisted in the DB file)
523  */
524 #define KVS_FLAG_CUSTOM_CMP (0x1)
525 struct kvs_node {
526     /**
527      * Name of the KV store as given by user.
528      */
529     char *kvs_name;
530     /**
531      * Unique KV Store ID generated and permanently assigned.
532      */
533     fdb_kvs_id_t id;
534     /**
535      * Highest sequence number seen in this KV store.
536      */
537     fdb_seqnum_t seqnum;
538     /**
539      * Flags indicating various states of the KV store.
540      */
541     uint64_t flags;
542     /**
543      * Custom compare function set by user (in-memory only).
544      */
545     fdb_custom_cmp_variable custom_cmp;
546     /**
547      * Operational CRUD statistics for this KV store (in-memory only).
548      */
549     struct kvs_ops_stat op_stat;
550     /**
551      * Persisted KV store statistics.
552      */
553     struct kvs_stat stat;
554     /**
555      * Link to the global list of KV stores indexed by store name.
556      */
557     struct avl_node avl_name;
558     /**
559      * Link to the global list of KV stores indexed by store ID.
560      */
561     struct avl_node avl_id;
562 };
563 
564 /**
565  * Type of filename in use.
566  */
567 typedef enum {
568     /**
569      * Filename used is a virtual filename (typically in auto compaction).
570      */
571     FDB_VFILENAME = 0,
572     /**
573      * Filename used is the actual filename (typically in manual compaction).
574      */
575     FDB_AFILENAME = 1,
576 } fdb_filename_mode_t;
577 
578 #define FDB_FLAG_SEQTREE_USE (0x1)
579 #define FDB_FLAG_ROOT_INITIALIZED (0x2)
580 #define FDB_FLAG_ROOT_CUSTOM_CMP (0x4)
581 
582 #ifdef __cplusplus
583 }
584 #endif
585 
586 #endif
587