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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 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
38
#ifdef XT_USE_CACHE_DEBUG_SIZES
39
#define XT_INDEX_CACHE_SEGMENT_SHIFTS 1
41
#define XT_INDEX_CACHE_SEGMENT_SHIFTS 3
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. */
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)
54
#define XT_IPAGE_USE_PTHREAD_RW
56
#define XT_IPAGE_USE_SPINXSLOCK
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
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 };
82
/* A block is X locked if it is being changed or freed.
83
* A block is S locked if it is being read.
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. */
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
110
xtWord1 cb_data[XT_INDEX_PAGE_SIZE];
112
} XTIndBlockRec, *XTIndBlockPtr;
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;
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;
130
typedef struct XTIndHandleBlock {
131
xtWord4 hb_ref_count;
132
struct XTIndHandleBlock *hb_next;
133
XTIdxBranchDRec hb_branch;
134
} XTIndHandleBlockRec, *XTIndHandleBlockPtr;
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. */
143
XTIndBlockPtr ih_cache_block;
144
XTIndHandleBlockPtr ih_handle_block;
146
XTIdxBranchDPtr ih_branch;
147
} XTIndHandleRec, *XTIndHandlePtr;
149
void xt_ind_init(XTThreadPtr self, size_t cache_size);
150
void xt_ind_exit(XTThreadPtr self);
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);
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);
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);
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);
177
//#define DEBUG_CHECK_IND_CACHE
180
//#define XT_TRACE_INDEX
182
#ifdef XT_TRACE_INDEX
183
#define IDX_TRACE(x, y, z) xt_trace(x, y, z)
185
#define IDX_TRACE(x, y, z)