Removed old deprecated c++ api.
[qt:qtjsondb.git] / src / 3rdparty / btree / src / btree_p.h
1 /*      $OpenBSD: btree.c,v 1.30 2010/09/01 12:13:21 martinh Exp $ */
2
3 /*
4  * Copyright (c) 2009, 2010 Martin Hedenfalk <martin@bzero.se>
5  *
6  * Permission to use, copy, modify, and distribute this software for any
7  * purpose with or without fee is hereby granted, provided that the above
8  * copyright notice and this permission notice appear in all copies.
9  *
10  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
17  */
18
19 #ifndef BTREE_P_H
20 #define BTREE_P_H
21
22 #include <sys/types.h>
23 #include <sys/tree.h>
24 #include <sys/file.h>
25 #include <sys/stat.h>
26 #include <sys/queue.h>
27 #include <sys/param.h>
28 #include <sys/uio.h>
29
30 #include <assert.h>
31 #include <err.h>
32 #include <errno.h>
33 #include <fcntl.h>
34 #include <stddef.h>
35 #include <stdint.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <string.h>
39 #include <time.h>
40 #include <unistd.h>
41
42 #define __STDC_FORMAT_MACROS
43 #include <inttypes.h>
44
45 #include "btree.h"
46
47 #include <QCryptographicHash>
48 #define SHA_DIGEST_LENGTH 20 /* 160 bits */
49
50 #define ATTR_PACKED __attribute__((packed))
51
52
53 #define PAGESIZE         4096
54 #define BT_MINKEYS       4
55 #define BT_MAGIC         0xB3DBB3DB
56 #define BT_VERSION       4
57 #define BT_COMMIT_PAGES  64     /* max number of pages to write in one commit */
58 #define BT_MAXCACHE_DEF  1024   /* max number of pages to keep in cache  */
59
60 #define P_INVALID        0xFFFFFFFF
61
62 #define F_ISSET(w, f)    (((w) & (f)) == (f))
63
64 typedef uint32_t         pgno_t;
65 typedef uint16_t         indx_t;
66
67 /* There are four page types: meta, index, leaf and overflow.
68  * They all share the same page header.
69  */
70 struct page {                           /* represents an on-disk page */
71         uint32_t         checksum;
72         pgno_t           pgno;          /* page number */
73 #define P_BRANCH         0x01           /* branch page */
74 #define P_LEAF           0x02           /* leaf page */
75 #define P_OVERFLOW       0x04           /* overflow page */
76 #define P_META           0x08           /* meta page */
77 #define P_HEAD           0x10           /* header page */
78         uint32_t         flags;
79 #define lower            b.fb.fb_lower
80 #define upper            b.fb.fb_upper
81 #define p_next_pgno      b.pb_next_pgno
82         union page_bounds {
83                 struct {
84                         indx_t   fb_lower;      /* lower bound of free space */
85                         indx_t   fb_upper;      /* upper bound of free space */
86                 } fb;
87                 pgno_t           pb_next_pgno;  /* overflow page linked list */
88         } b;
89         indx_t           ptrs[1];               /* dynamic size */
90 } ATTR_PACKED;
91
92 #define PAGEHDRSZ        offsetof(struct page, ptrs)
93
94 #define NUMKEYSP(p)      (((p)->lower - PAGEHDRSZ) >> 1)
95 #define NUMKEYS(mp)      (((mp)->page->lower - PAGEHDRSZ) >> 1)
96 #define SIZELEFT(mp)     (indx_t)((mp)->page->upper - (mp)->page->lower)
97 #define PAGEFILL(bt, mp) (1000 * ((bt)->head.psize - PAGEHDRSZ - SIZELEFT(mp)) / \
98                                 ((bt)->head.psize - PAGEHDRSZ))
99 #define IS_LEAF(mp)      F_ISSET((mp)->page->flags, P_LEAF)
100 #define IS_BRANCH(mp)    F_ISSET((mp)->page->flags, P_BRANCH)
101 #define IS_OVERFLOW(mp)  F_ISSET((mp)->page->flags, P_OVERFLOW)
102
103 struct node {
104 #define n_pgno           p.np_pgno
105 #define n_dsize          p.np_dsize
106         union {
107                 pgno_t           np_pgno;       /* child page number */
108                 uint32_t         np_dsize;      /* leaf data size */
109         }                p;
110         uint16_t         ksize;                 /* key size */
111 #define F_BIGDATA        0x01                   /* data put on overflow page */
112         uint8_t          flags;
113         char             data[1];
114 } ATTR_PACKED;
115
116 #define NODESIZE         offsetof(struct node, data)
117
118 #ifdef ENABLE_BIG_KEYS
119 /*  page header (minus the ptrs field)
120     + the size to store an index into the page to the node
121     + the node header (minus data field)
122     + the the min data size required for internal data keeping (ie overflow page)
123     + one index_t and nodesize to make room for at least one other branch node
124     + divide by 2, we need at least two keys for splitting to work */
125 #define MAXKEYSIZE       ((PAGESIZE - (PAGEHDRSZ + (sizeof(indx_t) + NODESIZE + sizeof(pgno_t)) * 2)) / 2)
126 #else
127 #define MAXKEYSIZE       255
128 #endif
129
130 #define MAXPFXSIZE       255
131
132 #define INDXSIZE(k)      (NODESIZE + ((k) == NULL ? 0 : (k)->size))
133 #define LEAFSIZE(k, d)   (NODESIZE + (k)->size + (d)->size)
134 #define NODEPTRP(p, i)   ((struct node *)((char *)(p) + (p)->ptrs[i]))
135 #define NODEPTR(mp, i)   NODEPTRP((mp)->page, i)
136 #define NODEKEY(node)    (char *)((node)->data)
137 #define NODEDATA(node)   (char *)((char *)(node)->data + (node)->ksize)
138 #define NODEPGNO(node)   ((node)->p.np_pgno)
139 #define NODEDSZ(node)    ((node)->p.np_dsize)
140
141 struct bt_head {                                /* header page content */
142         uint32_t         magic;
143         uint32_t         version;
144         uint32_t         flags;
145         uint32_t         psize;                 /* page size */
146         uint16_t         ksize;
147 } ATTR_PACKED;
148
149 struct bt_meta {                                /* meta (footer) page content */
150 #define BT_TOMBSTONE     0x01                   /* file is replaced */
151 #define BT_MARKER        0x02                   /* flushed with fsync */
152         uint32_t         flags;
153         pgno_t           pgno;                  /* this metapage page number */
154         pgno_t           root;                  /* page number of root page */
155         pgno_t           prev_meta;             /* previous meta page number */
156         uint64_t         created_at;            /* time_t type */
157         uint32_t         branch_pages;
158         uint32_t         leaf_pages;
159         uint32_t         overflow_pages;
160         uint32_t         revisions;
161         uint32_t         depth;
162         uint64_t         entries;
163         uint32_t         tag;
164         unsigned char    hash[SHA_DIGEST_LENGTH];
165 } ATTR_PACKED;
166
167 struct btkey {
168         size_t           len;
169         char             str[MAXPFXSIZE];
170 };
171
172 struct mpage {                                  /* an in-memory cached page */
173         RB_ENTRY(mpage)          entry;         /* page cache entry */
174         SIMPLEQ_ENTRY(mpage)     next;          /* queue of dirty pages */
175         TAILQ_ENTRY(mpage)       lru_next;      /* LRU queue */
176         struct mpage            *parent;        /* NULL if root */
177         unsigned int             parent_index;  /* keep track of node index */
178         struct btkey             prefix;
179         struct page             *page;
180         pgno_t                   pgno;          /* copy of page->pgno */
181         short                    ref;           /* increased by cursors */
182         short                    dirty;         /* 1 if on dirty queue */
183 };
184 RB_HEAD(page_cache, mpage);
185 SIMPLEQ_HEAD(dirty_queue, mpage);
186 TAILQ_HEAD(lru_queue, mpage);
187
188 struct ppage {                                  /* ordered list of pages */
189         SLIST_ENTRY(ppage)       entry;
190         struct mpage            *mpage;
191         unsigned int             ki;            /* cursor index on page */
192 };
193 SLIST_HEAD(page_stack, ppage);
194
195 #define CURSOR_EMPTY(c)          SLIST_EMPTY(&(c)->stack)
196 #define CURSOR_TOP(c)            SLIST_FIRST(&(c)->stack)
197 #define CURSOR_POP(c)            SLIST_REMOVE_HEAD(&(c)->stack, entry)
198 #define CURSOR_PUSH(c,p)         SLIST_INSERT_HEAD(&(c)->stack, p, entry)
199
200 struct cursor {
201         struct btree            *bt;
202         struct btree_txn        *txn;
203         struct page_stack        stack;         /* stack of parent pages */
204         short                    initialized;   /* 1 if initialized */
205         short                    eof;           /* 1 if end is reached */
206 };
207
208 #define METAHASHLEN      offsetof(struct bt_meta, hash)
209 #define METADATA(p)      ((bt_meta *)((char *)p + PAGEHDRSZ))
210
211 struct btree_txn {
212         pgno_t                   root;          /* current / new root page */
213         pgno_t                   next_pgno;     /* next unallocated page */
214         struct btree            *bt;            /* btree is ref'd */
215         struct dirty_queue      *dirty_queue;   /* modified pages */
216 #define BT_TXN_RDONLY            0x01           /* read-only transaction */
217 #define BT_TXN_ERROR             0x02           /* an error has occurred */
218         unsigned int             flags;
219         unsigned int             tag;           /* a tag on which the transaction was initiated */
220 };
221
222 struct btree {
223         int                      fd;
224         char                    *path;
225 #define BT_FIXPADDING            0x01           /* internal */
226         unsigned int             flags;
227         bt_cmp_func              cmp;           /* user compare function */
228         struct bt_head           head;
229         struct bt_meta           meta;
230         struct page_cache       *page_cache;
231         struct lru_queue        *lru_queue;
232         struct btree_txn        *txn;           /* current write transaction */
233         int                      ref;           /* increased by cursors & txn */
234         struct btree_stat        stat;
235         off_t                    size;          /* current file size */
236         void                    *context;       /* passed in to the compare function */
237         QCryptographicHash      *hasher;
238 };
239
240 void                     btree_dump_tree(struct btree *bt, pgno_t pgno, int depth);
241 void                     btree_dump_page_from_memory(struct page *p);
242 void                     btree_close_nosync(struct btree *bt);
243
244 #endif // BTREE_P_H