|
9 | 9 | *
|
10 | 10 | *
|
11 | 11 | * IDENTIFICATION
|
12 |
| - * $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.74 2006/03/31 23:32:06 tgl Exp $ |
| 12 | + * $PostgreSQL: pgsql/src/backend/storage/buffer/localbuf.c,v 1.75 2006/12/27 22:31:54 tgl Exp $ |
13 | 13 | *
|
14 | 14 | *-------------------------------------------------------------------------
|
15 | 15 | */
|
@@ -48,6 +48,7 @@ static HTAB *LocalBufHash = NULL;
|
48 | 48 |
|
49 | 49 |
|
50 | 50 | static void InitLocalBuffers(void);
|
| 51 | +static Block GetLocalBufferStorage(void); |
51 | 52 |
|
52 | 53 |
|
53 | 54 | /*
|
@@ -167,12 +168,8 @@ LocalBufferAlloc(Relation reln, BlockNumber blockNum, bool *foundPtr)
|
167 | 168 | */
|
168 | 169 | if (LocalBufHdrGetBlock(bufHdr) == NULL)
|
169 | 170 | {
|
170 |
| - char *data; |
171 |
| - |
172 |
| - data = (char *) MemoryContextAlloc(TopMemoryContext, BLCKSZ); |
173 |
| - |
174 | 171 | /* Set pointer for use by BufferGetBlock() macro */
|
175 |
| - LocalBufHdrGetBlock(bufHdr) = (Block) data; |
| 172 | + LocalBufHdrGetBlock(bufHdr) = GetLocalBufferStorage(); |
176 | 173 | }
|
177 | 174 |
|
178 | 175 | /*
|
@@ -334,6 +331,54 @@ InitLocalBuffers(void)
|
334 | 331 | NLocBuffer = nbufs;
|
335 | 332 | }
|
336 | 333 |
|
| 334 | +/* |
| 335 | + * GetLocalBufferStorage - allocate memory for a local buffer |
| 336 | + * |
| 337 | + * The idea of this function is to aggregate our requests for storage |
| 338 | + * so that the memory manager doesn't see a whole lot of relatively small |
| 339 | + * requests. Since we'll never give back a local buffer once it's created |
| 340 | + * within a particular process, no point in burdening memmgr with separately |
| 341 | + * managed chunks. |
| 342 | + */ |
| 343 | +static Block |
| 344 | +GetLocalBufferStorage(void) |
| 345 | +{ |
| 346 | + static char *cur_block = NULL; |
| 347 | + static int next_buf_in_block = 0; |
| 348 | + static int num_bufs_in_block = 0; |
| 349 | + static int total_bufs_allocated = 0; |
| 350 | + |
| 351 | + char *this_buf; |
| 352 | + |
| 353 | + Assert(total_bufs_allocated < NLocBuffer); |
| 354 | + |
| 355 | + if (next_buf_in_block >= num_bufs_in_block) |
| 356 | + { |
| 357 | + /* Need to make a new request to memmgr */ |
| 358 | + int num_bufs; |
| 359 | + |
| 360 | + /* Start with a 16-buffer request; subsequent ones double each time */ |
| 361 | + num_bufs = Max(num_bufs_in_block * 2, 16); |
| 362 | + /* But not more than what we need for all remaining local bufs */ |
| 363 | + num_bufs = Min(num_bufs, NLocBuffer - total_bufs_allocated); |
| 364 | + /* And don't overflow MaxAllocSize, either */ |
| 365 | + num_bufs = Min(num_bufs, MaxAllocSize / BLCKSZ); |
| 366 | + |
| 367 | + /* Allocate space from TopMemoryContext so it never goes away */ |
| 368 | + cur_block = (char *) MemoryContextAlloc(TopMemoryContext, |
| 369 | + num_bufs * BLCKSZ); |
| 370 | + next_buf_in_block = 0; |
| 371 | + num_bufs_in_block = num_bufs; |
| 372 | + } |
| 373 | + |
| 374 | + /* Allocate next buffer in current memory block */ |
| 375 | + this_buf = cur_block + next_buf_in_block * BLCKSZ; |
| 376 | + next_buf_in_block++; |
| 377 | + total_bufs_allocated++; |
| 378 | + |
| 379 | + return (Block) this_buf; |
| 380 | +} |
| 381 | + |
337 | 382 | /*
|
338 | 383 | * AtEOXact_LocalBuffers - clean up at end of transaction.
|
339 | 384 | *
|
|
0 commit comments