1/*-
2 * See the file LICENSE for redistribution information.
3 *
4 * Copyright (c) 1999,2008 Oracle.  All rights reserved.
5 *
6 * $Id: qam.h,v 12.16 2008/01/08 20:58:18 bostic Exp $
7 */
8
9#ifndef	_DB_QAM_H_
10#define	_DB_QAM_H_
11
12#if defined(__cplusplus)
13extern "C" {
14#endif
15
16/*
17 * QAM data elements: a status field and the data.
18 */
19typedef struct _qamdata {
20	u_int8_t  flags;	/* 00: delete bit. */
21#define	QAM_VALID	0x01
22#define	QAM_SET		0x02
23	u_int8_t  data[1];	/* Record. */
24} QAMDATA;
25
26struct __queue;		typedef struct __queue QUEUE;
27struct __qcursor;	typedef struct __qcursor QUEUE_CURSOR;
28
29struct __qcursor {
30	/* struct __dbc_internal */
31	__DBC_INTERNAL
32
33	/* Queue private part */
34
35	/* Per-thread information: queue private. */
36	db_recno_t	 recno;		/* Current record number. */
37
38	u_int32_t	 flags;
39};
40
41typedef struct __mpfarray {
42	u_int32_t n_extent;		/* Number of extents in table. */
43	u_int32_t low_extent;		/* First extent open. */
44	u_int32_t hi_extent;		/* Last extent open. */
45	struct __qmpf {
46		int pinref;
47		DB_MPOOLFILE *mpf;
48	} *mpfarray;			 /* Array of open extents. */
49} MPFARRAY;
50
51/*
52 * The in-memory, per-tree queue data structure.
53 */
54struct __queue {
55	db_pgno_t q_meta;		/* Database meta-data page. */
56	db_pgno_t q_root;		/* Database root page. */
57
58	int	  re_pad;		/* Fixed-length padding byte. */
59	u_int32_t re_len;		/* Length for fixed-length records. */
60	u_int32_t rec_page;		/* records per page */
61	u_int32_t page_ext;		/* Pages per extent */
62	MPFARRAY array1, array2;	/* File arrays. */
63
64					/* Extent file configuration: */
65	DBT pgcookie;			/* Initialized pgcookie. */
66	DB_PGINFO pginfo;		/* Initialized pginfo struct. */
67
68	char *path;			/* Space allocated to file pathname. */
69	char *name;			/* The name of the file. */
70	char *dir;			/* The dir of the file. */
71	int mode;			/* Mode to open extents. */
72};
73
74/* Format for queue extent names. */
75#define	QUEUE_EXTENT		"%s%c__dbq.%s.%d"
76#define	QUEUE_EXTENT_HEAD	"__dbq.%s."
77#define	QUEUE_EXTENT_PREFIX	"__dbq."
78
79typedef struct __qam_filelist {
80	DB_MPOOLFILE *mpf;
81	u_int32_t id;
82} QUEUE_FILELIST;
83
84/*
85 * Calculate the page number of a recno.
86 *
87 * Number of records per page =
88 *	Divide the available space on the page by the record len + header.
89 *
90 * Page number for record =
91 *	divide the physical record number by the records per page
92 *	add the root page number
93 *	For now the root page will always be 1, but we might want to change
94 *	in the future (e.g. multiple fixed len queues per file).
95 *
96 * Index of record on page =
97 *	physical record number, less the logical pno times records/page
98 */
99#define	CALC_QAM_RECNO_PER_PAGE(dbp)					\
100    (((dbp)->pgsize - QPAGE_SZ(dbp)) /					\
101    (u_int32_t)DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) +		\
102    ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)))
103
104#define	QAM_RECNO_PER_PAGE(dbp)	(((QUEUE*)(dbp)->q_internal)->rec_page)
105
106#define	QAM_RECNO_PAGE(dbp, recno)					\
107    (((QUEUE *)(dbp)->q_internal)->q_root				\
108    + (((recno) - 1) / QAM_RECNO_PER_PAGE(dbp)))
109
110#define	QAM_PAGE_EXTENT(dbp, pgno)					\
111    (((pgno) - 1) / ((QUEUE *)(dbp)->q_internal)->page_ext)
112
113#define	QAM_RECNO_EXTENT(dbp, recno)					\
114    QAM_PAGE_EXTENT(dbp, QAM_RECNO_PAGE(dbp, recno))
115
116#define	QAM_RECNO_INDEX(dbp, pgno, recno)				\
117    (((recno) - 1) - (QAM_RECNO_PER_PAGE(dbp)				\
118    * (pgno - ((QUEUE *)(dbp)->q_internal)->q_root)))
119
120#define	QAM_GET_RECORD(dbp, page, index)				\
121    ((QAMDATA *)((u_int8_t *)(page) + (QPAGE_SZ(dbp) +			\
122    (DB_ALIGN((uintmax_t)SSZA(QAMDATA, data) +				\
123    ((QUEUE *)(dbp)->q_internal)->re_len, sizeof(u_int32_t)) * index))))
124
125#define	QAM_AFTER_CURRENT(meta, recno)					\
126    ((recno) >= (meta)->cur_recno &&					\
127    ((meta)->first_recno <= (meta)->cur_recno ||			\
128    ((recno) < (meta)->first_recno &&					\
129    (recno) - (meta)->cur_recno < (meta)->first_recno - (recno))))
130
131#define	QAM_BEFORE_FIRST(meta, recno)					\
132    ((recno) < (meta)->first_recno &&					\
133    ((meta)->first_recno <= (meta)->cur_recno ||			\
134    ((recno) > (meta)->cur_recno &&					\
135    (recno) - (meta)->cur_recno > (meta)->first_recno - (recno))))
136
137#define	QAM_NOT_VALID(meta, recno)					\
138    (recno == RECNO_OOB ||						\
139	QAM_BEFORE_FIRST(meta, recno) || QAM_AFTER_CURRENT(meta, recno))
140
141/*
142 * Log opcodes for the mvptr routine.
143 */
144#define	QAM_SETFIRST		0x01
145#define	QAM_SETCUR		0x02
146#define	QAM_TRUNCATE		0x04
147
148typedef enum {
149	QAM_PROBE_GET,
150	QAM_PROBE_PUT,
151	QAM_PROBE_DIRTY,
152	QAM_PROBE_MPF
153} qam_probe_mode;
154
155/*
156 * Ops for __qam_nameop.
157 */
158typedef enum {
159	QAM_NAME_DISCARD,
160	QAM_NAME_RENAME,
161	QAM_NAME_REMOVE
162} qam_name_op;
163
164#define	__qam_fget(dbc, pgnoaddr, flags, addrp)		\
165	__qam_fprobe(dbc, *pgnoaddr,					\
166	    addrp, QAM_PROBE_GET, DB_PRIORITY_UNCHANGED, flags)
167
168#define	__qam_fput(dbc, pgno, addrp, priority) 			\
169	__qam_fprobe(dbc, pgno, addrp, QAM_PROBE_PUT, priority, 0)
170
171#define	__qam_dirty(dbc, pgno, pagep, priority) 		\
172	__qam_fprobe(dbc, pgno, pagep, QAM_PROBE_DIRTY, priority, 0)
173
174#if defined(__cplusplus)
175}
176#endif
177
178#include "dbinc_auto/qam_auto.h"
179#include "dbinc_auto/qam_ext.h"
180#endif /* !_DB_QAM_H_ */
181