Asterisk - The Open Source Telephony Project
18.5.0
utils
db1-ast
btree
btree.h
Go to the documentation of this file.
1
/*-
2
* Copyright (c) 1991, 1993, 1994
3
* The Regents of the University of California. All rights reserved.
4
*
5
* This code is derived from software contributed to Berkeley by
6
* Mike Olson.
7
*
8
* Redistribution and use in source and binary forms, with or without
9
* modification, are permitted provided that the following conditions
10
* are met:
11
* 1. Redistributions of source code must retain the above copyright
12
* notice, this list of conditions and the following disclaimer.
13
* 2. Redistributions in binary form must reproduce the above copyright
14
* notice, this list of conditions and the following disclaimer in the
15
* documentation and/or other materials provided with the distribution.
16
* 3. All advertising materials mentioning features or use of this software
17
* must display the following acknowledgement:
18
* This product includes software developed by the University of
19
* California, Berkeley and its contributors.
20
* 4. Neither the name of the University nor the names of its contributors
21
* may be used to endorse or promote products derived from this software
22
* without specific prior written permission.
23
*
24
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
25
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
28
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
29
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
30
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
31
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
32
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34
* SUCH DAMAGE.
35
*
36
* @(#)btree.h 8.11 (Berkeley) 8/17/94
37
*/
38
39
/* Macros to set/clear/test flags. */
40
#define F_SET(p, f) (p)->flags |= (f)
41
#define F_CLR(p, f) (p)->flags &= ~(f)
42
#define F_ISSET(p, f) ((p)->flags & (f))
43
44
#include <
mpool.h
>
45
46
#define mpool_open __mpool_open
47
#define mpool_filter __mpool_filter
48
#define mpool_new __mpool_new
49
#define mpool_get __mpool_get
50
#define mpool_put __mpool_put
51
#define mpool_sync __mpool_sync
52
#define mpool_close __mpool_close
53
54
#define DEFMINKEYPAGE (2)
/* Minimum keys per page */
55
#define MINCACHE (5)
/* Minimum cached pages */
56
#define MINPSIZE (512)
/* Minimum page size */
57
58
/*
59
* Page 0 of a btree file contains a copy of the meta-data. This page is also
60
* used as an out-of-band page, i.e. page pointers that point to nowhere point
61
* to page 0. Page 1 is the root of the btree.
62
*/
63
#define P_INVALID 0
/* Invalid tree page number. */
64
#define P_META 0
/* Tree metadata page number. */
65
#define P_ROOT 1
/* Tree root page number. */
66
67
/*
68
* There are five page layouts in the btree: btree internal pages (BINTERNAL),
69
* btree leaf pages (BLEAF), recno internal pages (RINTERNAL), recno leaf pages
70
* (RLEAF) and overflow pages. All five page types have a page header (PAGE).
71
* This implementation requires that values within structures NOT be padded.
72
* (ANSI C permits random padding.) If your compiler pads randomly you'll have
73
* to do some work to get this package to run.
74
*/
75
typedef
struct
_page
{
76
pgno_t
pgno
;
/* this page's page number */
77
pgno_t
prevpg
;
/* left sibling */
78
pgno_t
nextpg
;
/* right sibling */
79
80
#define P_BINTERNAL 0x01
/* btree internal page */
81
#define P_BLEAF 0x02
/* leaf page */
82
#define P_OVERFLOW 0x04
/* overflow page */
83
#define P_RINTERNAL 0x08
/* recno internal page */
84
#define P_RLEAF 0x10
/* leaf page */
85
#define P_TYPE 0x1f
/* type mask */
86
#define P_PRESERVE 0x20
/* never delete this chain of pages */
87
u_int32_t
flags
;
88
89
indx_t
lower
;
/* lower bound of free space on page */
90
indx_t
upper
;
/* upper bound of free space on page */
91
indx_t
linp
[1];
/* indx_t-aligned VAR. LENGTH DATA */
92
}
PAGE
;
93
94
/* First and next index. */
95
#define BTDATAOFF \
96
(sizeof(pgno_t) + sizeof(pgno_t) + sizeof(pgno_t) + \
97
sizeof(u_int32_t) + sizeof(indx_t) + sizeof(indx_t))
98
#define NEXTINDEX(p) (((p)->lower - BTDATAOFF) / sizeof(indx_t))
99
100
/*
101
* For pages other than overflow pages, there is an array of offsets into the
102
* rest of the page immediately following the page header. Each offset is to
103
* an item which is unique to the type of page. The h_lower offset is just
104
* past the last filled-in index. The h_upper offset is the first item on the
105
* page. Offsets are from the beginning of the page.
106
*
107
* If an item is too big to store on a single page, a flag is set and the item
108
* is a { page, size } pair such that the page is the first page of an overflow
109
* chain with size bytes of item. Overflow pages are simply bytes without any
110
* external structure.
111
*
112
* The page number and size fields in the items are pgno_t-aligned so they can
113
* be manipulated without copying. (This presumes that 32 bit items can be
114
* manipulated on this system.)
115
*/
116
#define LALIGN(n) (((n) + sizeof(pgno_t) - 1) & ~(sizeof(pgno_t) - 1))
117
#define NOVFLSIZE (sizeof(pgno_t) + sizeof(u_int32_t))
118
119
/*
120
* For the btree internal pages, the item is a key. BINTERNALs are {key, pgno}
121
* pairs, such that the key compares less than or equal to all of the records
122
* on that page. For a tree without duplicate keys, an internal page with two
123
* consecutive keys, a and b, will have all records greater than or equal to a
124
* and less than b stored on the page associated with a. Duplicate keys are
125
* somewhat special and can cause duplicate internal and leaf page records and
126
* some minor modifications of the above rule.
127
*/
128
typedef
struct
_binternal
{
129
u_int32_t
ksize
;
/* key size */
130
pgno_t
pgno
;
/* page number stored on */
131
#define P_BIGDATA 0x01
/* overflow data */
132
#define P_BIGKEY 0x02
/* overflow key */
133
u_char
flags
;
134
char
bytes[1];
/* data */
135
}
BINTERNAL
;
136
137
/* Get the page's BINTERNAL structure at index indx. */
138
#define GETBINTERNAL(pg, indx) \
139
((BINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
140
141
/* Get the number of bytes in the entry. */
142
#define NBINTERNAL(len) \
143
LALIGN(sizeof(u_int32_t) + sizeof(pgno_t) + sizeof(u_char) + (len))
144
145
/* Copy a BINTERNAL entry to the page. */
146
#define WR_BINTERNAL(p, size, pgno, flags) { \
147
*(u_int32_t *)p = size; \
148
p += sizeof(u_int32_t); \
149
*(pgno_t *)p = pgno; \
150
p += sizeof(pgno_t); \
151
*(u_char *)p = flags; \
152
p += sizeof(u_char); \
153
}
154
155
/*
156
* For the recno internal pages, the item is a page number with the number of
157
* keys found on that page and below.
158
*/
159
typedef
struct
_rinternal
{
160
recno_t
nrecs
;
/* number of records */
161
pgno_t
pgno
;
/* page number stored below */
162
}
RINTERNAL
;
163
164
/* Get the page's RINTERNAL structure at index indx. */
165
#define GETRINTERNAL(pg, indx) \
166
((RINTERNAL *)((char *)(pg) + (pg)->linp[indx]))
167
168
/* Get the number of bytes in the entry. */
169
#define NRINTERNAL \
170
LALIGN(sizeof(recno_t) + sizeof(pgno_t))
171
172
/* Copy a RINTERNAL entry to the page. */
173
#define WR_RINTERNAL(p, nrecs, pgno) { \
174
*(recno_t *)p = nrecs; \
175
p += sizeof(recno_t); \
176
*(pgno_t *)p = pgno; \
177
}
178
179
/* For the btree leaf pages, the item is a key and data pair. */
180
typedef
struct
_bleaf
{
181
u_int32_t
ksize
;
/* size of key */
182
u_int32_t
dsize
;
/* size of data */
183
u_char
flags
;
/* P_BIGDATA, P_BIGKEY */
184
char
bytes[1];
/* data */
185
}
BLEAF
;
186
187
/* Get the page's BLEAF structure at index indx. */
188
#define GETBLEAF(pg, indx) \
189
((BLEAF *)((char *)(pg) + (pg)->linp[indx]))
190
191
/* Get the number of bytes in the entry. */
192
#define NBLEAF(p) NBLEAFDBT((p)->ksize, (p)->dsize)
193
194
/* Get the number of bytes in the user's key/data pair. */
195
#define NBLEAFDBT(ksize, dsize) \
196
LALIGN(sizeof(u_int32_t) + sizeof(u_int32_t) + sizeof(u_char) + \
197
(ksize) + (dsize))
198
199
/* Copy a BLEAF entry to the page. */
200
#define WR_BLEAF(p, key, data, flags) { \
201
*(u_int32_t *)p = key->size; \
202
p += sizeof(u_int32_t); \
203
*(u_int32_t *)p = data->size; \
204
p += sizeof(u_int32_t); \
205
*(u_char *)p = flags; \
206
p += sizeof(u_char); \
207
memmove(p, key->data, key->size); \
208
p += key->size; \
209
memmove(p, data->data, data->size); \
210
}
211
212
/* For the recno leaf pages, the item is a data entry. */
213
typedef
struct
_rleaf
{
214
u_int32_t
dsize
;
/* size of data */
215
u_char
flags
;
/* P_BIGDATA */
216
char
bytes[1];
217
}
RLEAF
;
218
219
/* Get the page's RLEAF structure at index indx. */
220
#define GETRLEAF(pg, indx) \
221
((RLEAF *)((char *)(pg) + (pg)->linp[indx]))
222
223
/* Get the number of bytes in the entry. */
224
#define NRLEAF(p) NRLEAFDBT((p)->dsize)
225
226
/* Get the number of bytes from the user's data. */
227
#define NRLEAFDBT(dsize) \
228
LALIGN(sizeof(u_int32_t) + sizeof(u_char) + (dsize))
229
230
/* Copy a RLEAF entry to the page. */
231
#define WR_RLEAF(p, data, flags) { \
232
*(u_int32_t *)p = data->size; \
233
p += sizeof(u_int32_t); \
234
*(u_char *)p = flags; \
235
p += sizeof(u_char); \
236
memmove(p, data->data, data->size); \
237
}
238
239
/*
240
* A record in the tree is either a pointer to a page and an index in the page
241
* or a page number and an index. These structures are used as a cursor, stack
242
* entry and search returns as well as to pass records to other routines.
243
*
244
* One comment about searches. Internal page searches must find the largest
245
* record less than key in the tree so that descents work. Leaf page searches
246
* must find the smallest record greater than key so that the returned index
247
* is the record's correct position for insertion.
248
*/
249
typedef
struct
_epgno
{
250
pgno_t
pgno
;
/* the page number */
251
indx_t
index
;
/* the index on the page */
252
}
EPGNO
;
253
254
typedef
struct
_epg
{
255
PAGE
*
page
;
/* the (pinned) page */
256
indx_t
index
;
/* the index on the page */
257
}
EPG
;
258
259
/*
260
* About cursors. The cursor (and the page that contained the key/data pair
261
* that it referenced) can be deleted, which makes things a bit tricky. If
262
* there are no duplicates of the cursor key in the tree (i.e. B_NODUPS is set
263
* or there simply aren't any duplicates of the key) we copy the key that it
264
* referenced when it's deleted, and reacquire a new cursor key if the cursor
265
* is used again. If there are duplicates keys, we move to the next/previous
266
* key, and set a flag so that we know what happened. NOTE: if duplicate (to
267
* the cursor) keys are added to the tree during this process, it is undefined
268
* if they will be returned or not in a cursor scan.
269
*
270
* The flags determine the possible states of the cursor:
271
*
272
* CURS_INIT The cursor references *something*.
273
* CURS_ACQUIRE The cursor was deleted, and a key has been saved so that
274
* we can reacquire the right position in the tree.
275
* CURS_AFTER, CURS_BEFORE
276
* The cursor was deleted, and now references a key/data pair
277
* that has not yet been returned, either before or after the
278
* deleted key/data pair.
279
* XXX
280
* This structure is broken out so that we can eventually offer multiple
281
* cursors as part of the DB interface.
282
*/
283
typedef
struct
_cursor
{
284
EPGNO
pg
;
/* B: Saved tree reference. */
285
DBT
key
;
/* B: Saved key, or key.data == NULL. */
286
recno_t
rcursor
;
/* R: recno cursor (1-based) */
287
288
#define CURS_ACQUIRE 0x01
/* B: Cursor needs to be reacquired. */
289
#define CURS_AFTER 0x02
/* B: Unreturned cursor after key. */
290
#define CURS_BEFORE 0x04
/* B: Unreturned cursor before key. */
291
#define CURS_INIT 0x08
/* RB: Cursor initialized. */
292
u_int8_t
flags
;
293
}
CURSOR
;
294
295
/*
296
* The metadata of the tree. The nrecs field is used only by the RECNO code.
297
* This is because the btree doesn't really need it and it requires that every
298
* put or delete call modify the metadata.
299
*/
300
typedef
struct
_btmeta
{
301
u_int32_t
magic
;
/* magic number */
302
u_int32_t
version
;
/* version */
303
u_int32_t
psize
;
/* page size */
304
u_int32_t
free
;
/* page number of first free page */
305
u_int32_t
nrecs
;
/* R: number of records */
306
307
#define SAVEMETA (B_NODUPS | R_RECNO)
308
u_int32_t
flags
;
/* bt_flags & SAVEMETA */
309
}
BTMETA
;
310
311
/* The in-memory btree/recno data structure. */
312
typedef
struct
_btree
{
313
MPOOL
*
bt_mp
;
/* memory pool cookie */
314
315
DB
*
bt_dbp
;
/* pointer to enclosing DB */
316
317
EPG
bt_cur
;
/* current (pinned) page */
318
PAGE
*
bt_pinned
;
/* page pinned across calls */
319
320
CURSOR
bt_cursor
;
/* cursor */
321
322
#define BT_PUSH(t, p, i) { \
323
t->bt_sp->pgno = p; \
324
t->bt_sp->index = i; \
325
++t->bt_sp; \
326
}
327
#define BT_POP(t) (t->bt_sp == t->bt_stack ? NULL : --t->bt_sp)
328
#define BT_CLR(t) (t->bt_sp = t->bt_stack)
329
EPGNO
bt_stack[50];
/* stack of parent pages */
330
EPGNO
*
bt_sp
;
/* current stack pointer */
331
332
DBT
bt_rkey
;
/* returned key */
333
DBT
bt_rdata
;
/* returned data */
334
335
int
bt_fd
;
/* tree file descriptor */
336
337
pgno_t
bt_free
;
/* next free page */
338
u_int32_t
bt_psize
;
/* page size */
339
indx_t
bt_ovflsize
;
/* cut-off for key/data overflow */
340
int
bt_lorder
;
/* byte order */
341
/* sorted order */
342
enum
{
NOT
, BACK, FORWARD } bt_order;
343
EPGNO
bt_last
;
/* last insert */
344
345
/* B: key comparison function */
346
int (*bt_cmp)
__P
((
const
DBT
*,
const
DBT
*));
347
/* B: prefix comparison function */
348
size_t (*bt_pfx)
__P
((
const
DBT
*,
const
DBT
*));
349
/* R: recno input function */
350
int (*bt_irec)
__P
((
struct
_btree
*,
recno_t
));
351
352
FILE *
bt_rfp
;
/* R: record FILE pointer */
353
int
bt_rfd
;
/* R: record file descriptor */
354
355
caddr_t
bt_cmap
;
/* R: current point in mapped space */
356
caddr_t
bt_smap
;
/* R: start of mapped space */
357
caddr_t
bt_emap
;
/* R: end of mapped space */
358
size_t
bt_msize
;
/* R: size of mapped region. */
359
360
recno_t
bt_nrecs
;
/* R: number of records */
361
size_t
bt_reclen
;
/* R: fixed record length */
362
u_char
bt_bval
;
/* R: delimiting byte/pad character */
363
364
/*
365
* NB:
366
* B_NODUPS and R_RECNO are stored on disk, and may not be changed.
367
*/
368
#define B_INMEM 0x00001
/* in-memory tree */
369
#define B_METADIRTY 0x00002
/* need to write metadata */
370
#define B_MODIFIED 0x00004
/* tree modified */
371
#define B_NEEDSWAP 0x00008
/* if byte order requires swapping */
372
#define B_RDONLY 0x00010
/* read-only tree */
373
374
#define B_NODUPS 0x00020
/* no duplicate keys permitted */
375
#define R_RECNO 0x00080
/* record oriented tree */
376
377
#define R_CLOSEFP 0x00040
/* opened a file pointer */
378
#define R_EOF 0x00100
/* end of input file reached. */
379
#define R_FIXLEN 0x00200
/* fixed length records */
380
#define R_MEMMAPPED 0x00400
/* memory mapped file. */
381
#define R_INMEM 0x00800
/* in-memory file */
382
#define R_MODIFIED 0x01000
/* modified file */
383
#define R_RDONLY 0x02000
/* read-only file */
384
385
#define B_DB_LOCK 0x04000
/* DB_LOCK specified. */
386
#define B_DB_SHMEM 0x08000
/* DB_SHMEM specified. */
387
#define B_DB_TXN 0x10000
/* DB_TXN specified. */
388
u_int32_t
flags
;
389
}
BTREE
;
390
391
#include "
extern.h
"
_btree::bt_rfd
int bt_rfd
Definition:
btree.h:353
_page
Definition:
btree.h:75
_cursor::pg
EPGNO pg
Definition:
btree.h:284
MPOOL
Definition:
mpool.h:66
_rinternal::nrecs
recno_t nrecs
Definition:
btree.h:160
_page::pgno
pgno_t pgno
Definition:
btree.h:76
_rleaf::flags
u_char flags
Definition:
btree.h:215
_rleaf
Definition:
btree.h:213
_btree::bt_smap
caddr_t bt_smap
Definition:
btree.h:356
_btree::bt_cur
EPG bt_cur
Definition:
btree.h:317
_btree::bt_sp
EPGNO * bt_sp
Definition:
btree.h:330
_binternal::pgno
pgno_t pgno
Definition:
btree.h:130
_bleaf::dsize
u_int32_t dsize
Definition:
btree.h:182
_btree::bt_cursor
CURSOR bt_cursor
Definition:
btree.h:320
_cursor::rcursor
recno_t rcursor
Definition:
btree.h:286
_bleaf::flags
u_char flags
Definition:
btree.h:183
_btmeta::psize
u_int32_t psize
Definition:
btree.h:303
_btmeta::flags
u_int32_t flags
Definition:
btree.h:308
_btree::flags
u_int32_t flags
Definition:
btree.h:388
_btree::bt_msize
size_t bt_msize
Definition:
btree.h:358
_rleaf::dsize
u_int32_t dsize
Definition:
btree.h:214
_epg
Definition:
btree.h:254
_epgno::index
indx_t index
Definition:
btree.h:251
DBT
Definition:
db.h:85
_btree::bt_rkey
DBT bt_rkey
Definition:
btree.h:332
_page::lower
indx_t lower
Definition:
btree.h:89
_btmeta::magic
u_int32_t magic
Definition:
btree.h:301
extern.h
indx_t
u_int16_t indx_t
Definition:
db.h:80
_page::upper
indx_t upper
Definition:
btree.h:90
_epgno
Definition:
btree.h:249
_btree::bt_nrecs
recno_t bt_nrecs
Definition:
btree.h:360
_btree
Definition:
btree.h:312
_btree::bt_bval
u_char bt_bval
Definition:
btree.h:362
EPG
struct _epg EPG
_page::flags
u_int32_t flags
Definition:
btree.h:87
_binternal::flags
u_char flags
Definition:
btree.h:133
_btree::bt_pinned
PAGE * bt_pinned
Definition:
btree.h:318
_btree::bt_lorder
int bt_lorder
Definition:
btree.h:340
_btree::bt_rdata
DBT bt_rdata
Definition:
btree.h:333
_rinternal::pgno
pgno_t pgno
Definition:
btree.h:161
_epg::page
PAGE * page
Definition:
btree.h:255
_btree::bt_rfp
FILE * bt_rfp
Definition:
btree.h:352
_page::linp
indx_t linp[1]
Definition:
btree.h:91
_btree::bt_mp
MPOOL * bt_mp
Definition:
btree.h:313
_cursor::key
DBT key
Definition:
btree.h:285
BTREE
struct _btree BTREE
RINTERNAL
struct _rinternal RINTERNAL
pgno_t
u_int32_t pgno_t
Definition:
db.h:78
_cursor
Definition:
btree.h:283
_btmeta::nrecs
u_int32_t nrecs
Definition:
btree.h:305
_page::nextpg
pgno_t nextpg
Definition:
btree.h:78
__P
#define __P(p)
Definition:
include/solaris-compat/compat.h:8
_epg::index
indx_t index
Definition:
btree.h:256
_page::prevpg
pgno_t prevpg
Definition:
btree.h:77
_btmeta::free
u_int32_t free
Definition:
btree.h:304
_btree::bt_psize
u_int32_t bt_psize
Definition:
btree.h:338
_rinternal
Definition:
btree.h:159
BLEAF
struct _bleaf BLEAF
_cursor::flags
u_int8_t flags
Definition:
btree.h:292
CURSOR
struct _cursor CURSOR
mpool.h
_binternal
Definition:
btree.h:128
u_int32_t
unsigned int u_int32_t
Definition:
include/solaris-compat/compat.h:40
_btmeta::version
u_int32_t version
Definition:
btree.h:302
_btree::NOT
Definition:
btree.h:342
BTMETA
struct _btmeta BTMETA
_btree::bt_reclen
size_t bt_reclen
Definition:
btree.h:361
_btree::bt_last
EPGNO bt_last
Definition:
btree.h:343
EPGNO
struct _epgno EPGNO
_epgno::pgno
pgno_t pgno
Definition:
btree.h:250
u_int8_t
unsigned char u_int8_t
Definition:
include/solaris-compat/compat.h:38
_bleaf
Definition:
btree.h:180
BINTERNAL
struct _binternal BINTERNAL
_btree::bt_fd
int bt_fd
Definition:
btree.h:335
_btree::bt_ovflsize
indx_t bt_ovflsize
Definition:
btree.h:339
PAGE
struct _page PAGE
_btree::bt_dbp
DB * bt_dbp
Definition:
btree.h:315
_btree::bt_cmap
caddr_t bt_cmap
Definition:
btree.h:355
__db
Definition:
db.h:129
_bleaf::ksize
u_int32_t ksize
Definition:
btree.h:181
recno_t
u_int32_t recno_t
Definition:
db.h:82
_btree::bt_emap
caddr_t bt_emap
Definition:
btree.h:357
RLEAF
struct _rleaf RLEAF
_binternal::ksize
u_int32_t ksize
Definition:
btree.h:129
_btree::bt_free
pgno_t bt_free
Definition:
btree.h:337
_btmeta
Definition:
btree.h:300
Generated on Sun Aug 8 2021 19:43:09 for Asterisk - The Open Source Telephony Project by
1.8.13