Skip to content

Commit bd95c74

Browse files
committed
Code cleanup for pg_buffercache, from Mark Kirkwood.
1 parent c2c0b14 commit bd95c74

File tree

1 file changed

+34
-66
lines changed

1 file changed

+34
-66
lines changed

contrib/pg_buffercache/pg_buffercache_pages.c

Lines changed: 34 additions & 66 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,14 @@
33
* pg_buffercache_pages.c
44
* display some contents of the buffer cache
55
*
6-
* $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.10 2006/10/19 18:32:46 tgl Exp $
6+
* $PostgreSQL: pgsql/contrib/pg_buffercache/pg_buffercache_pages.c,v 1.11 2006/10/22 17:49:21 tgl Exp $
77
*-------------------------------------------------------------------------
88
*/
99
#include "postgres.h"
10-
#include "funcapi.h"
10+
11+
#include "access/heapam.h"
1112
#include "catalog/pg_type.h"
13+
#include "funcapi.h"
1214
#include "storage/buf_internals.h"
1315
#include "storage/bufmgr.h"
1416
#include "utils/relcache.h"
@@ -26,15 +28,13 @@ Datum pg_buffercache_pages(PG_FUNCTION_ARGS);
2628
*/
2729
typedef struct
2830
{
29-
3031
uint32 bufferid;
3132
Oid relfilenode;
3233
Oid reltablespace;
3334
Oid reldatabase;
3435
BlockNumber blocknum;
3536
bool isvalid;
3637
bool isdirty;
37-
3838
} BufferCachePagesRec;
3939

4040

@@ -43,11 +43,8 @@ typedef struct
4343
*/
4444
typedef struct
4545
{
46-
47-
AttInMetadata *attinmeta;
46+
TupleDesc tupdesc;
4847
BufferCachePagesRec *record;
49-
char *values[NUM_BUFFERCACHE_PAGES_ELEM];
50-
5148
} BufferCachePagesContext;
5249

5350

@@ -56,10 +53,10 @@ typedef struct
5653
* relation node/tablespace/database/blocknum and dirty indicator.
5754
*/
5855
PG_FUNCTION_INFO_V1(pg_buffercache_pages);
56+
5957
Datum
6058
pg_buffercache_pages(PG_FUNCTION_ARGS)
6159
{
62-
6360
FuncCallContext *funcctx;
6461
Datum result;
6562
MemoryContext oldcontext;
@@ -77,7 +74,10 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
7774
/* Switch context when allocating stuff to be used in later calls */
7875
oldcontext = MemoryContextSwitchTo(funcctx->multi_call_memory_ctx);
7976

80-
/* Construct a tuple to return. */
77+
/* Create a user function context for cross-call persistence */
78+
fctx = (BufferCachePagesContext *) palloc(sizeof(BufferCachePagesContext));
79+
80+
/* Construct a tuple descriptor for the result rows. */
8181
tupledesc = CreateTemplateTupleDesc(NUM_BUFFERCACHE_PAGES_ELEM, false);
8282
TupleDescInitEntry(tupledesc, (AttrNumber) 1, "bufferid",
8383
INT4OID, -1, 0);
@@ -92,27 +92,14 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
9292
TupleDescInitEntry(tupledesc, (AttrNumber) 6, "isdirty",
9393
BOOLOID, -1, 0);
9494

95-
/* Generate attribute metadata needed later to produce tuples */
96-
funcctx->attinmeta = TupleDescGetAttInMetadata(tupledesc);
97-
98-
/*
99-
* Create a function context for cross-call persistence and initialize
100-
* the buffer counters.
101-
*/
102-
fctx = (BufferCachePagesContext *) palloc(sizeof(BufferCachePagesContext));
103-
funcctx->max_calls = NBuffers;
104-
funcctx->user_fctx = fctx;
95+
fctx->tupdesc = BlessTupleDesc(tupledesc);
10596

10697
/* Allocate NBuffers worth of BufferCachePagesRec records. */
10798
fctx->record = (BufferCachePagesRec *) palloc(sizeof(BufferCachePagesRec) * NBuffers);
10899

109-
/* allocate the strings for tuple formation */
110-
fctx->values[0] = (char *) palloc(3 * sizeof(uint32) + 1);
111-
fctx->values[1] = (char *) palloc(3 * sizeof(uint32) + 1);
112-
fctx->values[2] = (char *) palloc(3 * sizeof(uint32) + 1);
113-
fctx->values[3] = (char *) palloc(3 * sizeof(uint32) + 1);
114-
fctx->values[4] = (char *) palloc(3 * sizeof(uint32) + 1);
115-
fctx->values[5] = (char *) palloc(2);
100+
/* Set max calls and remember the user function context. */
101+
funcctx->max_calls = NBuffers;
102+
funcctx->user_fctx = fctx;
116103

117104
/* Return to original context when allocating transient memory */
118105
MemoryContextSwitchTo(oldcontext);
@@ -167,19 +154,11 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
167154
if (funcctx->call_cntr < funcctx->max_calls)
168155
{
169156
uint32 i = funcctx->call_cntr;
170-
char *values[NUM_BUFFERCACHE_PAGES_ELEM];
171-
int j;
172-
173-
/*
174-
* Use a temporary values array, initially pointing to fctx->values,
175-
* so it can be reassigned w/o losing the storage for subsequent
176-
* calls.
177-
*/
178-
for (j = 0; j < NUM_BUFFERCACHE_PAGES_ELEM; j++)
179-
{
180-
values[j] = fctx->values[j];
181-
}
157+
Datum values[NUM_BUFFERCACHE_PAGES_ELEM];
158+
bool nulls[NUM_BUFFERCACHE_PAGES_ELEM];
182159

160+
values[0] = Int32GetDatum(fctx->record[i].bufferid);
161+
nulls[0] = false;
183162

184163
/*
185164
* Set all fields except the bufferid to null if the buffer is unused
@@ -188,43 +167,32 @@ pg_buffercache_pages(PG_FUNCTION_ARGS)
188167
if (fctx->record[i].blocknum == InvalidBlockNumber ||
189168
fctx->record[i].isvalid == false)
190169
{
191-
192-
sprintf(values[0], "%u", fctx->record[i].bufferid);
193-
values[1] = NULL;
194-
values[2] = NULL;
195-
values[3] = NULL;
196-
values[4] = NULL;
197-
values[5] = NULL;
198-
170+
nulls[1] = true;
171+
nulls[2] = true;
172+
nulls[3] = true;
173+
nulls[4] = true;
174+
nulls[5] = true;
199175
}
200176
else
201177
{
202-
203-
sprintf(values[0], "%u", fctx->record[i].bufferid);
204-
sprintf(values[1], "%u", fctx->record[i].relfilenode);
205-
sprintf(values[2], "%u", fctx->record[i].reltablespace);
206-
sprintf(values[3], "%u", fctx->record[i].reldatabase);
207-
sprintf(values[4], "%u", fctx->record[i].blocknum);
208-
if (fctx->record[i].isdirty)
209-
{
210-
strcpy(values[5], "t");
211-
}
212-
else
213-
{
214-
strcpy(values[5], "f");
215-
}
216-
178+
values[1] = ObjectIdGetDatum(fctx->record[i].relfilenode);
179+
nulls[1] = false;
180+
values[2] = ObjectIdGetDatum(fctx->record[i].reltablespace);
181+
nulls[2] = false;
182+
values[3] = ObjectIdGetDatum(fctx->record[i].reldatabase);
183+
nulls[3] = false;
184+
values[4] = Int64GetDatum((int64) fctx->record[i].blocknum);
185+
nulls[4] = false;
186+
values[5] = BoolGetDatum(fctx->record[i].isdirty);
187+
nulls[5] = false;
217188
}
218189

219-
220190
/* Build and return the tuple. */
221-
tuple = BuildTupleFromCStrings(funcctx->attinmeta, values);
191+
tuple = heap_form_tuple(fctx->tupdesc, values, nulls);
222192
result = HeapTupleGetDatum(tuple);
223193

224-
225194
SRF_RETURN_NEXT(funcctx, result);
226195
}
227196
else
228197
SRF_RETURN_DONE(funcctx);
229-
230198
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy