Movatterモバイル変換


[0]ホーム

URL:


Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commitd65522a

Browse files
committed
Upgrade localbuf.c to use a hash table instead of linear search to
find already-allocated local buffers. This is the last obstaclein the way of setting NLocBuffer to something reasonably large.
1 parent2e62908 commitd65522a

File tree

1 file changed

+100
-46
lines changed

1 file changed

+100
-46
lines changed

‎src/backend/storage/buffer/localbuf.c

Lines changed: 100 additions & 46 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
*
1010
*
1111
* IDENTIFICATION
12-
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.64 2005/03/18 16:16:09 tgl Exp $
12+
* $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.65 2005/03/19 17:39:43 tgl Exp $
1313
*
1414
*-------------------------------------------------------------------------
1515
*/
@@ -18,29 +18,37 @@
1818
#include"storage/buf_internals.h"
1919
#include"storage/bufmgr.h"
2020
#include"storage/smgr.h"
21-
#include"utils/relcache.h"
21+
#include"utils/memutils.h"
2222
#include"utils/resowner.h"
2323

2424

2525
/*#define LBDEBUG*/
2626

27+
/* entry for buffer lookup hashtable */
28+
typedefstruct
29+
{
30+
BufferTagkey;/* Tag of a disk page */
31+
intid;/* Associated local buffer's index */
32+
}LocalBufferLookupEnt;
33+
2734
/* Note: this macro only works on local buffers, not shared ones! */
2835
#defineLocalBufHdrGetBlock(bufHdr)\
2936
LocalBufferBlockPointers[-((bufHdr)->buf_id + 2)]
3037

31-
/* should be a GUC parameter some day */
32-
intNLocBuffer=64;
38+
intNLocBuffer=0;/* until buffers are initialized */
3339

3440
BufferDesc*LocalBufferDescriptors=NULL;
3541
Block*LocalBufferBlockPointers=NULL;
3642
int32*LocalRefCount=NULL;
3743

3844
staticintnextFreeLocalBuf=0;
3945

46+
staticHTAB*LocalBufHash=NULL;
47+
4048

4149
/*
4250
* LocalBufferAlloc -
43-
*allocatea local buffer. We do round robin allocation for now.
51+
*Find or createa local buffer for the given page of the given relation.
4452
*
4553
* API is similar to bufmgr.c's BufferAlloc, except that we do not need
4654
* to do any locking since this is all local.Also, IO_IN_PROGRESS
@@ -50,35 +58,39 @@ BufferDesc *
5058
LocalBufferAlloc(Relationreln,BlockNumberblockNum,bool*foundPtr)
5159
{
5260
BufferTagnewTag;/* identity of requested block */
53-
inti;
54-
inttrycounter;
61+
LocalBufferLookupEnt*hresult;
5562
BufferDesc*bufHdr;
63+
intb;
64+
inttrycounter;
65+
boolfound;
5666

5767
INIT_BUFFERTAG(newTag,reln,blockNum);
5868

59-
/* a low tech search for now -- should use a hashtable */
60-
for (i=0;i<NLocBuffer;i++)
69+
/* See if the desired buffer already exists */
70+
hresult= (LocalBufferLookupEnt*)
71+
hash_search(LocalBufHash, (void*)&newTag,HASH_FIND,NULL);
72+
73+
if (hresult)
6174
{
62-
bufHdr=&LocalBufferDescriptors[i];
63-
if (BUFFERTAGS_EQUAL(bufHdr->tag,newTag))
64-
{
75+
b=hresult->id;
76+
bufHdr=&LocalBufferDescriptors[b];
77+
Assert(BUFFERTAGS_EQUAL(bufHdr->tag,newTag));
6578
#ifdefLBDEBUG
66-
fprintf(stderr,"LB ALLOC (%u,%d) %d\n",
67-
RelationGetRelid(reln),blockNum,-i-1);
79+
fprintf(stderr,"LB ALLOC (%u,%d) %d\n",
80+
RelationGetRelid(reln),blockNum,-b-1);
6881
#endif
6982

70-
LocalRefCount[i]++;
71-
ResourceOwnerRememberBuffer(CurrentResourceOwner,
72-
BufferDescriptorGetBuffer(bufHdr));
73-
if (bufHdr->flags&BM_VALID)
74-
*foundPtr= TRUE;
75-
else
76-
{
77-
/* Previous read attempt must have failed; try again */
78-
*foundPtr= FALSE;
79-
}
80-
returnbufHdr;
83+
LocalRefCount[b]++;
84+
ResourceOwnerRememberBuffer(CurrentResourceOwner,
85+
BufferDescriptorGetBuffer(bufHdr));
86+
if (bufHdr->flags&BM_VALID)
87+
*foundPtr= TRUE;
88+
else
89+
{
90+
/* Previous read attempt must have failed; try again */
91+
*foundPtr= FALSE;
8192
}
93+
returnbufHdr;
8294
}
8395

8496
#ifdefLBDEBUG
@@ -93,7 +105,7 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
93105
trycounter=NLocBuffer;
94106
for (;;)
95107
{
96-
intb=nextFreeLocalBuf;
108+
b=nextFreeLocalBuf;
97109

98110
if (++nextFreeLocalBuf >=NLocBuffer)
99111
nextFreeLocalBuf=0;
@@ -136,31 +148,50 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
136148
(char*)LocalBufHdrGetBlock(bufHdr),
137149
true);
138150

151+
/* Mark not-dirty now in case we error out below */
152+
bufHdr->flags &= ~BM_DIRTY;
153+
139154
LocalBufferFlushCount++;
140155
}
141156

142157
/*
143158
* lazy memory allocation: allocate space on first use of a buffer.
144-
*
145-
* Note this path cannot be taken for a buffer that was previously in
146-
* use, so it's okay to do it (and possibly error out) before marking
147-
* the buffer as not dirty.
148159
*/
149160
if (LocalBufHdrGetBlock(bufHdr)==NULL)
150161
{
151-
char*data= (char*)malloc(BLCKSZ);
162+
char*data;
152163

153-
if (data==NULL)
154-
ereport(ERROR,
155-
(errcode(ERRCODE_OUT_OF_MEMORY),
156-
errmsg("out of memory")));
164+
data= (char*)MemoryContextAlloc(TopMemoryContext,BLCKSZ);
157165

158-
/*
159-
* Set pointer for use by BufferGetBlock() macro.
160-
*/
166+
/* Set pointer for use by BufferGetBlock() macro */
161167
LocalBufHdrGetBlock(bufHdr)= (Block)data;
162168
}
163169

170+
/*
171+
* Update the hash table: remove old entry, if any, and make new one.
172+
*/
173+
if (bufHdr->flags&BM_TAG_VALID)
174+
{
175+
hresult= (LocalBufferLookupEnt*)
176+
hash_search(LocalBufHash, (void*)&bufHdr->tag,
177+
HASH_REMOVE,NULL);
178+
if (!hresult)/* shouldn't happen */
179+
elog(ERROR,"local buffer hash table corrupted");
180+
/* mark buffer invalid just in case hash insert fails */
181+
CLEAR_BUFFERTAG(bufHdr->tag);
182+
bufHdr->flags &= ~(BM_VALID |BM_TAG_VALID);
183+
}
184+
185+
hresult= (LocalBufferLookupEnt*)
186+
hash_search(LocalBufHash, (void*)&newTag,HASH_ENTER,&found);
187+
if (!hresult)
188+
ereport(ERROR,
189+
(errcode(ERRCODE_OUT_OF_MEMORY),
190+
errmsg("out of memory")));
191+
if (found)/* shouldn't happen */
192+
elog(ERROR,"local buffer hash table corrupted");
193+
hresult->id=b;
194+
164195
/*
165196
* it's all ours now.
166197
*/
@@ -215,20 +246,39 @@ WriteLocalBuffer(Buffer buffer, bool release)
215246
void
216247
InitLocalBuffer(void)
217248
{
249+
intnbufs=64;/* should be from a GUC var */
250+
HASHCTLinfo;
218251
inti;
219252

220-
/*
221-
* these aren't going away. I'm not gonna use palloc.
222-
*/
253+
/* Create the lookup hash table */
254+
MemSet(&info,0,sizeof(info));
255+
info.keysize=sizeof(BufferTag);
256+
info.entrysize=sizeof(LocalBufferLookupEnt);
257+
info.hash=tag_hash;
258+
259+
LocalBufHash=hash_create("Local Buffer Lookup Table",
260+
nbufs,
261+
&info,
262+
HASH_ELEM |HASH_FUNCTION);
263+
264+
if (!LocalBufHash)
265+
elog(ERROR,"could not initialize local buffer hash table");
266+
267+
/* Allocate and zero buffer headers and auxiliary arrays */
223268
LocalBufferDescriptors= (BufferDesc*)
224-
calloc(NLocBuffer,sizeof(*LocalBufferDescriptors));
269+
MemoryContextAllocZero(TopMemoryContext,
270+
nbufs*sizeof(BufferDesc));
225271
LocalBufferBlockPointers= (Block*)
226-
calloc(NLocBuffer,sizeof(*LocalBufferBlockPointers));
272+
MemoryContextAllocZero(TopMemoryContext,
273+
nbufs*sizeof(Block));
227274
LocalRefCount= (int32*)
228-
calloc(NLocBuffer,sizeof(*LocalRefCount));
275+
MemoryContextAllocZero(TopMemoryContext,
276+
nbufs*sizeof(int32));
277+
229278
nextFreeLocalBuf=0;
230279

231-
for (i=0;i<NLocBuffer;i++)
280+
/* initialize fields that need to start off nonzero */
281+
for (i=0;i<nbufs;i++)
232282
{
233283
BufferDesc*buf=&LocalBufferDescriptors[i];
234284

@@ -240,6 +290,9 @@ InitLocalBuffer(void)
240290
*/
241291
buf->buf_id=-i-2;
242292
}
293+
294+
/* Initialization done, mark buffers allocated */
295+
NLocBuffer=nbufs;
243296
}
244297

245298
/*
@@ -271,5 +324,6 @@ void
271324
AtProcExit_LocalBuffers(void)
272325
{
273326
/* just zero the refcounts ... */
274-
MemSet(LocalRefCount,0,NLocBuffer*sizeof(*LocalRefCount));
327+
if (LocalRefCount)
328+
MemSet(LocalRefCount,0,NLocBuffer*sizeof(*LocalRefCount));
275329
}

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp