1
/* Copyright (C) 2005 PrimeBase Technologies GmbH
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.
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.
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
19
* 2005-05-24 Paul McCullagh
23
#ifndef __xt_cache_h__
24
#define __xt_cache_h__
26
//#define XT_USE_MYSYS
28
#include "filesys_xt.h"
32
struct XTIdxReadBuffer;
35
//#define XT_USE_CACHE_DEBUG_SIZES
36
//#define CHECK_BLOCK_TRAILERS
39
#ifdef XT_USE_CACHE_DEBUG_SIZES
40
#define XT_INDEX_CACHE_SEGMENT_SHIFTS 1
42
#define XT_INDEX_CACHE_SEGMENT_SHIFTS 3
45
#define IDX_CAC_BLOCK_FREE 0
46
#define IDX_CAC_BLOCK_CLEAN 1
47
#define IDX_CAC_BLOCK_DIRTY 2 /* On the dirty list! */
48
#define IDX_CAC_BLOCK_FLUSHING 3 /* This page needs to be written to the index log. */
49
#define IDX_CAC_BLOCK_LOGGED 4 /* This page needs to be transfered from the index log to the index. */
51
#define IDX_CAC_MODIFYABLE(x) ((x) == IDX_CAC_BLOCK_CLEAN || (x) == IDX_CAC_BLOCK_DIRTY || (x) == IDX_CAC_BLOCK_LOGGED)
52
#define IDX_CAC_NOT_FREE(x) ((x) != IDX_CAC_BLOCK_FREE)
55
#define XT_IPAGE_USE_PTHREAD_RW
57
#define XT_IPAGE_USE_SPINXSLOCK
60
#if defined(XT_IPAGE_USE_PTHREAD_RW)
61
#define XT_IPAGE_LOCK_TYPE xt_rwlock_type
62
#define XT_IPAGE_INIT_LOCK(s, i) xt_init_rwlock_with_autoname(s, i)
63
#define XT_IPAGE_FREE_LOCK(s, i) xt_free_rwlock(i)
64
#define XT_IPAGE_READ_LOCK(i) xt_slock_rwlock_ns(i)
65
#define XT_IPAGE_WRITE_LOCK(i, s) xt_xlock_rwlock_ns(i)
66
#define XT_IPAGE_WRITE_TRY_LOCK(i, s) xt_xlock_try_rwlock_ns(i)
67
#define XT_IPAGE_UNLOCK(i, x) xt_unlock_rwlock_ns(i)
68
#elif defined(XT_IPAGE_USE_SPINXSLOCK)
69
#define XT_IPAGE_LOCK_TYPE XTSpinXSLockRec
70
#define XT_IPAGE_INIT_LOCK(s, i) xt_spinxslock_init_with_autoname(s, i)
71
#define XT_IPAGE_FREE_LOCK(s, i) xt_spinxslock_free(s, i)
72
#define XT_IPAGE_READ_LOCK(i) xt_spinxslock_slock(i)
73
#define XT_IPAGE_WRITE_LOCK(i, o) xt_spinxslock_xlock(i, FALSE, o)
74
#define XT_IPAGE_WRITE_TRY_LOCK(i, o) xt_spinxslock_xlock(i, TRUE, o)
75
#define XT_IPAGE_UNLOCK(i, x) xt_spinxslock_unlock(i, x)
76
#else // XT_IPAGE_USE_SKEW_RW
77
#error Please define the lock type
80
enum XTPageLockType { XT_LOCK_READ, XT_LOCK_WRITE, XT_XLOCK_LEAF, XT_XLOCK_DEL_LEAF };
81
enum XTPageUnlockType { XT_UNLOCK_NONE, XT_UNLOCK_READ, XT_UNLOCK_WRITE, XT_UNLOCK_R_UPDATE, XT_UNLOCK_W_UPDATE };
83
/* A block is X locked if it is being changed or freed.
84
* A block is S locked if it is being read.
86
typedef struct XTIndBlock {
87
xtIndexNodeID cb_address; /* The block address. */
88
u_int cb_file_id; /* The file id of the block. */
89
/* This is protected by cs_lock */
90
struct XTIndBlock *cb_next; /* Pointer to next block on hash list, or next free block on free list. */
91
/* This is protected by mi_dirty_lock */
92
struct XTIndBlock *cb_dirty_next; /* Double link for dirty blocks, next pointer. */
93
struct XTIndBlock *cb_dirty_prev; /* Double link for dirty blocks, previous pointer. */
94
/* This is protected by cg_lock */
95
xtWord4 cb_ru_time; /* If this is in the top 1/4 don't change position in MRU list. */
96
struct XTIndBlock *cb_mr_used; /* More recently used blocks. */
97
struct XTIndBlock *cb_lr_used; /* Less recently used blocks. */
98
/* Protected by cb_lock: */
99
XT_IPAGE_LOCK_TYPE cb_lock;
100
xtWord1 cb_state; /* Block status. */
101
#ifdef IND_OPT_DATA_WRITTEN
102
xtBool1 cb_header; /* TRUE if the header changed. */
103
xtWord2 cb_min_pos; /* The minimum dirty byte. */
104
xtWord2 cb_max_pos; /* The maximum dirty byte. */
106
volatile xtWord2 cb_handle_count; /* TRUE if this page is referenced by a handle. */
107
xtWord2 cp_del_count; /* Number of deleted entries. */
108
#ifdef XT_USE_DIRECT_IO_ON_INDEX
111
xtWord1 cb_data[XT_INDEX_PAGE_SIZE];
113
#ifdef CHECK_BLOCK_TRAILERS
116
} XTIndBlockRec, *XTIndBlockPtr;
118
typedef struct XTIndReference {
119
xtBool ir_xlock; /* Set to TRUE if the cache block is X locked. */
120
xtBool ir_updated; /* Set to TRUE if the cache block is updated. */
121
XTIndBlockPtr ir_block;
122
XTIdxBranchDPtr ir_branch;
123
} XTIndReferenceRec, *XTIndReferencePtr;
125
typedef struct XTIndFreeBlock {
126
XTDiskValue1 if_zero1_1; /* Must be set to zero. */
127
XTDiskValue1 if_zero2_1; /* Must be set to zero. */
128
XTDiskValue1 if_status_1;
129
XTDiskValue1 if_unused1_1;
130
XTDiskValue4 if_unused2_4;
131
XTDiskValue8 if_next_block_8;
132
} XTIndFreeBlockRec, *XTIndFreeBlockPtr;
134
typedef struct XTIndHandleBlock {
135
xtWord4 hb_ref_count;
136
struct XTIndHandleBlock *hb_next;
137
XTIdxBranchDRec hb_branch;
138
} XTIndHandleBlockRec, *XTIndHandleBlockPtr;
140
typedef struct XTIndHandle {
141
struct XTIndHandle *ih_next;
142
struct XTIndHandle *ih_prev;
143
XTSpinLockRec ih_lock;
144
xtIndexNodeID ih_address;
145
xtBool ih_cache_reference; /* True if this handle references the cache. */
147
XTIndBlockPtr ih_cache_block;
148
XTIndHandleBlockPtr ih_handle_block;
150
XTIdxBranchDPtr ih_branch;
151
} XTIndHandleRec, *XTIndHandlePtr;
153
void xt_ind_init(XTThreadPtr self, size_t cache_size);
154
void xt_ind_exit(XTThreadPtr self);
156
xtInt8 xt_ind_get_usage();
157
xtInt8 xt_ind_get_size();
158
u_int xt_ind_get_blocks();
159
u_int xt_ind_get_free_blocks();
160
xtBool xt_ind_write(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID offset, size_t size, xtWord1 *data);
161
xtBool xt_ind_write_cache(struct XTOpenTable *ot, xtIndexNodeID offset, size_t size, xtWord1 *data);
162
xtBool xt_ind_free_block(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID offset);
163
xtBool xt_ind_read_bytes(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID offset, size_t size, xtWord1 *data);
164
void xt_ind_check_cache(XTIndexPtr ind);
165
xtBool xt_ind_reserve(struct XTOpenTable *ot, u_int count, XTIdxBranchDPtr not_this);
166
void xt_ind_free_reserved(struct XTOpenTable *ot);
167
void xt_ind_unreserve(struct XTOpenTable *ot);
169
xtBool xt_ind_fetch(struct XTOpenTable *ot, XTIndexPtr ind, xtIndexNodeID node, XTPageLockType ltype, XTIndReferencePtr iref);
170
xtBool xt_ind_get(struct XTOpenTable *ot, xtIndexNodeID address, XTIndReferencePtr iref);
171
xtBool xt_ind_release(struct XTOpenTable *ot, XTIndexPtr ind, XTPageUnlockType utype, XTIndReferencePtr iref);
173
void xt_ind_lock_handle(XTIndHandlePtr handle);
174
void xt_ind_unlock_handle(XTIndHandlePtr handle);
175
xtBool xt_ind_copy_on_write(XTIndReferencePtr iref);
177
XTIndHandlePtr xt_ind_get_handle(struct XTOpenTable *ot, XTIndexPtr ind, XTIndReferencePtr iref);
178
void xt_ind_release_handle(XTIndHandlePtr handle, xtBool have_lock, XTThreadPtr thread);
180
#ifdef CHECK_BLOCK_TRAILERS
181
extern void check_block_trailers();
185
//#define DEBUG_CHECK_IND_CACHE
188
//#define XT_TRACE_INDEX
190
#ifdef XT_TRACE_INDEX
191
#define IDX_TRACE(x, y, z) xt_trace(x, y, z)
193
#define IDX_TRACE(x, y, z)