~drizzle-trunk/drizzle/development

1455.3.1 by Vladimir Kolesnikov
lp:drizzle + pbxt 1.1 + test results
1
/* Copyright (c) 2005 PrimeBase Technologies GmbH
2
 *
3
 * PrimeBase XT
4
 *
5
 * This program is free software; you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation; either version 2 of the License, or
8
 * (at your option) any later version.
9
 *
10
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program; if not, write to the Free Software
17
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
 *
19
 * 2005-05-24	Paul McCullagh
20
 *
21
 * H&G2JCtL
22
 */
23
#ifndef __xt_cache_h__
24
#define __xt_cache_h__
25
26
//#define XT_USE_MYSYS
27
28
#include "filesys_xt.h"
29
#include "index_xt.h"
30
31
struct XTOpenTable;
32
struct XTIdxReadBuffer;
33
34
#ifdef DEBUG
35
//#define XT_USE_CACHE_DEBUG_SIZES
36
#endif
37
38
#ifdef XT_USE_CACHE_DEBUG_SIZES
39
#define XT_INDEX_CACHE_SEGMENT_SHIFTS	1
40
#else
41
#define XT_INDEX_CACHE_SEGMENT_SHIFTS	3
42
#endif
43
44
#define IDX_CAC_BLOCK_FREE				0
45
#define IDX_CAC_BLOCK_CLEAN				1
46
#define IDX_CAC_BLOCK_DIRTY				2				/* On the dirty list! */
47
#define IDX_CAC_BLOCK_FLUSHING			3				/* This page needs to be written to the index log. */
48
#define IDX_CAC_BLOCK_LOGGED			4				/* This page needs to be transfered from the index log to the index. */
49
50
#define IDX_CAC_MODIFYABLE(x)			((x) == IDX_CAC_BLOCK_CLEAN || (x) == IDX_CAC_BLOCK_DIRTY || (x) == IDX_CAC_BLOCK_LOGGED)
51
#define IDX_CAC_NOT_FREE(x)				((x) != IDX_CAC_BLOCK_FREE)
52
53
#ifdef XT_NO_ATOMICS
54
#define XT_IPAGE_USE_PTHREAD_RW
55
#else
56
#define XT_IPAGE_USE_SPINXSLOCK
57
#endif
58
59
#if defined(XT_IPAGE_USE_PTHREAD_RW)
60
#define XT_IPAGE_LOCK_TYPE				xt_rwlock_type
61
#define XT_IPAGE_INIT_LOCK(s, i)		xt_init_rwlock_with_autoname(s, i)
62
#define XT_IPAGE_FREE_LOCK(s, i)		xt_free_rwlock(i)	
63
#define XT_IPAGE_READ_LOCK(i)			xt_slock_rwlock_ns(i)
64
#define XT_IPAGE_WRITE_LOCK(i, s)		xt_xlock_rwlock_ns(i)
65
#define XT_IPAGE_WRITE_TRY_LOCK(i, s)	xt_xlock_try_rwlock_ns(i)
66
#define XT_IPAGE_UNLOCK(i, x)			xt_unlock_rwlock_ns(i)
67
#elif defined(XT_IPAGE_USE_SPINXSLOCK)
68
#define XT_IPAGE_LOCK_TYPE				XTSpinXSLockRec
69
#define XT_IPAGE_INIT_LOCK(s, i)		xt_spinxslock_init_with_autoname(s, i)
70
#define XT_IPAGE_FREE_LOCK(s, i)		xt_spinxslock_free(s, i)	
71
#define XT_IPAGE_READ_LOCK(i)			xt_spinxslock_slock(i)
72
#define XT_IPAGE_WRITE_LOCK(i, o)		xt_spinxslock_xlock(i, FALSE, o)
73
#define XT_IPAGE_WRITE_TRY_LOCK(i, o)	xt_spinxslock_xlock(i, TRUE, o)
74
#define XT_IPAGE_UNLOCK(i, x)			xt_spinxslock_unlock(i, x)
75
#else // XT_IPAGE_USE_SKEW_RW
76
#error Please define the lock type
77
#endif
78
79
enum XTPageLockType { XT_LOCK_READ, XT_LOCK_WRITE, XT_XLOCK_LEAF, XT_XLOCK_DEL_LEAF };
80
enum XTPageUnlockType { XT_UNLOCK_NONE, XT_UNLOCK_READ, XT_UNLOCK_WRITE, XT_UNLOCK_R_UPDATE, XT_UNLOCK_W_UPDATE };
81
82
/* A block is X locked if it is being changed or freed.
83
 * A block is S locked if it is being read.
84
 */
85
typedef struct XTIndBlock {
86
	xtIndexNodeID		cb_address;						/* The block address. */
87
	u_int				cb_file_id;						/* The file id of the block. */
88
	/* This is protected by cs_lock */
89
	struct XTIndBlock	*cb_next;						/* Pointer to next block on hash list, or next free block on free list. */
90
	/* This is protected by mi_dirty_lock */
91
	struct XTIndBlock	*cb_dirty_next;					/* Double link for dirty blocks, next pointer. */
92
	struct XTIndBlock	*cb_dirty_prev;					/* Double link for dirty blocks, previous pointer. */
93
	/* This is protected by cg_lock */
94
	xtWord4				cb_ru_time;						/* If this is in the top 1/4 don't change position in MRU list. */
95
	struct XTIndBlock	*cb_mr_used;					/* More recently used blocks. */
96
	struct XTIndBlock	*cb_lr_used;					/* Less recently used blocks. */
97
	/* Protected by cb_lock: */
98
	XT_IPAGE_LOCK_TYPE	cb_lock;
99
	xtWord1				cb_state;						/* Block status. */
100
#ifdef IND_OPT_DATA_WRITTEN
101
	xtBool1				cb_header;						/* TRUE if the header changed. */
102
	xtWord2				cb_min_pos;						/* The minimum dirty byte. */
103
	xtWord2				cb_max_pos;						/* The maximum dirty byte. */
104
#endif
105
	volatile xtWord2	cb_handle_count;				/* TRUE if this page is referenced by a handle. */
106
	xtWord2				cp_del_count;					/* Number of deleted entries. */
107
#ifdef XT_USE_DIRECT_IO_ON_INDEX
108
	xtWord1				*cb_data;
109
#else
110
	xtWord1				cb_data[XT_INDEX_PAGE_SIZE];
111
#endif
112
} XTIndBlockRec, *XTIndBlockPtr;
113
114
typedef struct XTIndReference {
115
	xtBool					ir_xlock;					/* Set to TRUE if the cache block is X locked. */
116
	xtBool					ir_updated;					/* Set to TRUE if the cache block is updated. */
117
	XTIndBlockPtr			ir_block;
118
	XTIdxBranchDPtr			ir_branch;
119
} XTIndReferenceRec, *XTIndReferencePtr;
120
121
typedef struct XTIndFreeBlock {
122
	XTDiskValue1			if_zero1_1;					/* Must be set to zero. */
123
	XTDiskValue1			if_zero2_1;					/* Must be set to zero. */
124
	XTDiskValue1			if_status_1;
125
	XTDiskValue1			if_unused1_1;
126
	XTDiskValue4			if_unused2_4;
127
	XTDiskValue8			if_next_block_8;
128
} XTIndFreeBlockRec, *XTIndFreeBlockPtr;
129
130
typedef struct XTIndHandleBlock {
131
	xtWord4					hb_ref_count;
132
	struct XTIndHandleBlock	*hb_next;
133
	XTIdxBranchDRec			hb_branch;
134
} XTIndHandleBlockRec, *XTIndHandleBlockPtr;
135
136
typedef struct XTIndHandle {
137
	struct XTIndHandle		*ih_next;
138
	struct XTIndHandle		*ih_prev;
139
	XTSpinLockRec			ih_lock;
140
	xtIndexNodeID			ih_address;
141
	xtBool					ih_cache_reference;		/* True if this handle references the cache. */
142
	union {
143
		XTIndBlockPtr		ih_cache_block;
144
		XTIndHandleBlockPtr	ih_handle_block;
145
	} x;
146
	XTIdxBranchDPtr			ih_branch;
147
} XTIndHandleRec, *XTIndHandlePtr;
148
149
void			xt_ind_init(XTThreadPtr self, size_t cache_size);
150
void			xt_ind_exit(XTThreadPtr self);
151
152
xtInt8			xt_ind_get_usage();
153
xtInt8			xt_ind_get_size();
154
u_int			xt_ind_get_blocks();
155
u_int			xt_ind_get_free_blocks();
156
xtBool			xt_ind_write(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID offset, size_t size, xtWord1 *data);
157
xtBool			xt_ind_write_cache(struct XTOpenTable *ot, xtIndexNodeID offset, size_t size, xtWord1 *data);
158
xtBool			xt_ind_free_block(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID offset);
159
xtBool			xt_ind_read_bytes(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID offset, size_t size, xtWord1 *data);
160
void			xt_ind_check_cache(XTIndexPtr ind);
161
xtBool			xt_ind_reserve(struct XTOpenTable *ot, u_int count, XTIdxBranchDPtr not_this);
162
void			xt_ind_free_reserved(struct XTOpenTable *ot);
163
void			xt_ind_unreserve(struct XTOpenTable *ot);
164
165
xtBool			xt_ind_fetch(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID node, XTPageLockType ltype, XTIndReferencePtr iref);
166
xtBool			xt_ind_get(struct XTOpenTable *ot, xtIndexNodeID address, XTIndReferencePtr iref);
167
xtBool			xt_ind_release(struct XTOpenTable *ot, XTIndexPtr ind, XTPageUnlockType utype, XTIndReferencePtr iref);
168
169
void			xt_ind_lock_handle(XTIndHandlePtr handle);
170
void			xt_ind_unlock_handle(XTIndHandlePtr handle);
171
xtBool			xt_ind_copy_on_write(XTIndReferencePtr iref);
172
173
XTIndHandlePtr	xt_ind_get_handle(struct XTOpenTable *ot, XTIndexPtr ind, XTIndReferencePtr iref);
174
void			xt_ind_release_handle(XTIndHandlePtr handle, xtBool have_lock, XTThreadPtr thread);
175
176
#ifdef DEBUG
177
//#define DEBUG_CHECK_IND_CACHE
178
#endif
179
180
//#define XT_TRACE_INDEX
181
182
#ifdef XT_TRACE_INDEX
183
#define IDX_TRACE(x, y, z)		xt_trace(x, y, z)
184
#else
185
#define IDX_TRACE(x, y, z)
186
#endif
187
188
#endif