1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
|
/*-------------------------------------------------------------------------
*
* buf_internals.h--
* Internal definitions.
*
*
* Copyright (c) 1994, Regents of the University of California
*
* $Id: buf_internals.h,v 1.21 1998/02/26 04:43:21 momjian Exp $
*
* NOTE
* If BUFFERPAGE0 is defined, then 0 will be used as a
* valid buffer page number.
*
*-------------------------------------------------------------------------
*/
#ifndef BUFMGR_INTERNALS_H
#define BUFMGR_INTERNALS_H
#include <storage/lmgr.h>
#include <storage/buf.h>
/* Buf Mgr constants */
/* in bufmgr.c */
extern int NBuffers;
extern int Data_Descriptors;
extern int Free_List_Descriptor;
extern int Lookup_List_Descriptor;
extern int Num_Descriptors;
/*
* Flags for buffer descriptors
*/
#define BM_DIRTY (1 << 0)
#define BM_PRIVATE (1 << 1)
#define BM_VALID (1 << 2)
#define BM_DELETED (1 << 3)
#define BM_FREE (1 << 4)
#define BM_IO_IN_PROGRESS (1 << 5)
#define BM_IO_ERROR (1 << 6)
#define BM_JUST_DIRTIED (1 << 7)
typedef bits16 BufFlags;
typedef struct sbufdesc BufferDesc;
typedef struct sbufdesc BufferHdr;
typedef struct buftag BufferTag;
/* long * so alignment will be correct */
typedef long **BufferBlock;
struct buftag
{
LRelId relId;
BlockNumber blockNum; /* blknum relative to begin of reln */
};
#define CLEAR_BUFFERTAG(a)\
(a)->relId.dbId = InvalidOid; \
(a)->relId.relId = InvalidOid; \
(a)->blockNum = InvalidBlockNumber
#define INIT_BUFFERTAG(a,xx_reln,xx_blockNum) \
{ \
(a)->blockNum = xx_blockNum;\
(a)->relId = RelationGetLRelId(xx_reln); \
}
#ifdef NOT_USED
#define COPY_BUFFERTAG(a,b)\
{ \
(a)->blockNum = (b)->blockNum;\
LRelIdAssign(*(a),*(b));\
}
#define EQUAL_BUFFERTAG(a,b) \
(((a)->blockNum == (b)->blockNum) &&\
(OID_Equal((a)->relId.relId,(b)->relId.relId)))
#endif
#define BAD_BUFFER_ID(bid) ((bid<1) || (bid>(NBuffers)))
#define INVALID_DESCRIPTOR (-3)
/*
* bletch hack -- anyplace that we declare space for relation or
* database names, we just use '16', not a symbolic constant, to
* specify their lengths. BM_NAMESIZE is the length of these names,
* and is used in the buffer manager code. somebody with lots of
* spare time should do this for all the other modules, too.
*/
#define BM_NAMESIZE 16
/*
* struct sbufdesc -- shared buffer cache metadata for a single
* shared buffer descriptor.
*
* We keep the name of the database and relation in which this
* buffer appears in order to avoid a catalog lookup on cache
* flush if we don't have the reldesc in the cache. It is also
* possible that the relation to which this buffer belongs is
* not visible to all backends at the time that it gets flushed.
* Dbname, relname, dbid, and relid are enough to determine where
* to put the buffer, for all storage managers.
*/
#define PADDED_SBUFDESC_SIZE 128
/* DO NOT CHANGE THIS NEXT STRUCTURE:
It is used only to get padding information for the real sbufdesc structure
It should match the sbufdesc structure exactly except for a missing sb_pad
*/
struct sbufdesc_unpadded
{
Buffer freeNext;
Buffer freePrev;
SHMEM_OFFSET data;
BufferTag tag;
int buf_id;
BufFlags flags;
unsigned refcount;
#ifdef HAS_TEST_AND_SET
slock_t io_in_progress_lock;
#endif /* HAS_TEST_AND_SET */
char sb_dbname[NAMEDATALEN];
/* NOTE NO PADDING OF THE MEMBER HERE */
char sb_relname[NAMEDATALEN];
};
/* THE REAL STRUCTURE - the structure above must match it, minus sb_pad */
struct sbufdesc
{
Buffer freeNext; /* link for freelist chain */
Buffer freePrev;
SHMEM_OFFSET data; /* pointer to data in buf pool */
/* tag and id must be together for table lookup to work */
BufferTag tag; /* file/block identifier */
int buf_id; /* maps global desc to local desc */
BufFlags flags; /* described below */
unsigned refcount; /* # of times buffer is pinned */
#ifdef HAS_TEST_AND_SET
/* can afford a dedicated lock if test-and-set locks are available */
slock_t io_in_progress_lock;
#endif /* HAS_TEST_AND_SET */
char sb_dbname[NAMEDATALEN]; /* name of db in which buf belongs */
/*
* I padded this structure to a power of 2 (PADDED_SBUFDESC_SIZE)
* because BufferDescriptorGetBuffer is called a billion times and it
* does an C pointer subtraction (i.e., "x - y" -> array index of x
* relative to y, which is calculated using division by struct size).
* Integer ".div" hits you for 35 cycles, as opposed to a 1-cycle
* "sra" ... this hack cut 10% off of the time to create the Wisconsin
* database! It eats up more shared memory, of course, but we're
* (allegedly) going to make some of these types bigger soon anyway...
* -pma 1/2/93
*/
/*
* please, don't take the sizeof() this member and use it for
* something important
*/
char sb_relname[NAMEDATALEN + /* name of reln */
PADDED_SBUFDESC_SIZE - sizeof(struct sbufdesc_unpadded)];
};
/*
* mao tracing buffer allocation
*/
/*#define BMTRACE*/
#ifdef BMTRACE
typedef struct _bmtrace
{
int bmt_pid;
long bmt_buf;
long bmt_dbid;
long bmt_relid;
int bmt_blkno;
int bmt_op;
#define BMT_NOTUSED 0
#define BMT_ALLOCFND 1
#define BMT_ALLOCNOTFND 2
#define BMT_DEALLOC 3
} bmtrace;
#endif /* BMTRACE */
/*
* Bufmgr Interface:
*/
/* Internal routines: only called by buf.c */
/*freelist.c*/
extern void AddBufferToFreelist(BufferDesc *bf);
extern void PinBuffer(BufferDesc *buf);
extern void PinBuffer_Debug(char *file, int line, BufferDesc *buf);
extern void UnpinBuffer(BufferDesc *buf);
extern BufferDesc *GetFreeBuffer(void);
extern void InitFreeList(bool init);
/* buf_table.c */
extern void InitBufTable(void);
extern BufferDesc *BufTableLookup(BufferTag *tagPtr);
extern bool BufTableDelete(BufferDesc *buf);
extern bool BufTableInsert(BufferDesc *buf);
/* bufmgr.c */
extern BufferDesc *BufferDescriptors;
extern BufferBlock BufferBlocks;
extern long *PrivateRefCount;
extern long *LastRefCount;
extern long *CommitInfoNeedsSave;
extern SPINLOCK BufMgrLock;
/* localbuf.c */
extern long *LocalRefCount;
extern BufferDesc *LocalBufferDescriptors;
extern int NLocBuffer;
extern BufferDesc *
LocalBufferAlloc(Relation reln, BlockNumber blockNum,
bool *foundPtr);
extern int WriteLocalBuffer(Buffer buffer, bool release);
extern int FlushLocalBuffer(Buffer buffer, bool release);
extern void InitLocalBuffer(void);
extern void LocalBufferSync(void);
extern void ResetLocalBufferPool(void);
#endif /* BUFMGR_INTERNALS_H */
|