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

Commit2970afa

Browse files
committed
Add PQresultMemorySize function to report allocated size of a PGresult.
This number can be useful for application memory management, and theoverhead to track it seems pretty trivial.Lars Kanis, reviewed by Pavel Stehule, some mods by meDiscussion:https://postgr.es/m/fa16a288-9685-14f2-97c8-b8ac84365a4f@greiz-reinsdorf.de
1 parente7a2217 commit2970afa

File tree

5 files changed

+70
-6
lines changed

5 files changed

+70
-6
lines changed

‎doc/src/sgml/libpq.sgml

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6387,6 +6387,32 @@ void *PQresultAlloc(PGresult *res, size_t nBytes);
63876387
</listitem>
63886388
</varlistentry>
63896389

6390+
<varlistentry id="libpq-pqresultmemorysize">
6391+
<term>
6392+
<function>PQresultMemorySize</function>
6393+
<indexterm>
6394+
<primary>PQresultMemorySize</primary>
6395+
</indexterm>
6396+
</term>
6397+
6398+
<listitem>
6399+
<para>
6400+
Retrieves the number of bytes allocated for
6401+
a <structname>PGresult</structname> object.
6402+
<synopsis>
6403+
size_t PQresultMemorySize(const PGresult *res);
6404+
</synopsis>
6405+
</para>
6406+
6407+
<para>
6408+
This value is the sum of all <function>malloc</function> requests
6409+
associated with the <structname>PGresult</structname> object, that is,
6410+
all the space that will be freed by <function>PQclear</function>.
6411+
This information can be useful for managing memory consumption.
6412+
</para>
6413+
</listitem>
6414+
</varlistentry>
6415+
63906416
<varlistentry id="libpq-pqlibversion">
63916417
<term>
63926418
<function>PQlibVersion</function>
@@ -6960,6 +6986,14 @@ void *PQinstanceData(const PGconn *conn, PGEventProc proc);
69606986
int PQresultSetInstanceData(PGresult *res, PGEventProc proc, void *data);
69616987
</synopsis>
69626988
</para>
6989+
6990+
<para>
6991+
Beware that any storage represented by <parameter>data</parameter>
6992+
will not be accounted for by <function>PQresultMemorySize</function>,
6993+
unless it is allocated using <function>PQresultAlloc</function>.
6994+
(Doing so is recommendable because it eliminates the need to free
6995+
such storage explicitly when the result is destroyed.)
6996+
</para>
69636997
</listitem>
69646998
</varlistentry>
69656999

‎src/interfaces/libpq/exports.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -172,3 +172,4 @@ PQsslAttribute 169
172172
PQsetErrorContextVisibility 170
173173
PQresultVerboseErrorMessage 171
174174
PQencryptPasswordConn 172
175+
PQresultMemorySize 173

‎src/interfaces/libpq/fe-exec.c

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ static intstatic_client_encoding = PG_SQL_ASCII;
5151
staticboolstatic_std_strings= false;
5252

5353

54-
staticPGEvent*dupEvents(PGEvent*events,intcount);
54+
staticPGEvent*dupEvents(PGEvent*events,intcount,size_t*memSize);
5555
staticboolpqAddTuple(PGresult*res,PGresAttValue*tup,
5656
constchar**errmsgp);
5757
staticboolPQsendQueryStart(PGconn*conn);
@@ -166,6 +166,7 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
166166
result->curBlock=NULL;
167167
result->curOffset=0;
168168
result->spaceLeft=0;
169+
result->memorySize=sizeof(PGresult);
169170

170171
if (conn)
171172
{
@@ -193,7 +194,8 @@ PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status)
193194
/* copy events last; result must be valid if we need to PQclear */
194195
if (conn->nEvents>0)
195196
{
196-
result->events=dupEvents(conn->events,conn->nEvents);
197+
result->events=dupEvents(conn->events,conn->nEvents,
198+
&result->memorySize);
197199
if (!result->events)
198200
{
199201
PQclear(result);
@@ -344,7 +346,8 @@ PQcopyResult(const PGresult *src, int flags)
344346
/* Wants to copy PGEvents? */
345347
if ((flags&PG_COPYRES_EVENTS)&&src->nEvents>0)
346348
{
347-
dest->events=dupEvents(src->events,src->nEvents);
349+
dest->events=dupEvents(src->events,src->nEvents,
350+
&dest->memorySize);
348351
if (!dest->events)
349352
{
350353
PQclear(dest);
@@ -379,17 +382,20 @@ PQcopyResult(const PGresult *src, int flags)
379382
* Copy an array of PGEvents (with no extra space for more).
380383
* Does not duplicate the event instance data, sets this to NULL.
381384
* Also, the resultInitialized flags are all cleared.
385+
* The total space allocated is added to *memSize.
382386
*/
383387
staticPGEvent*
384-
dupEvents(PGEvent*events,intcount)
388+
dupEvents(PGEvent*events,intcount,size_t*memSize)
385389
{
386390
PGEvent*newEvents;
391+
size_tmsize;
387392
inti;
388393

389394
if (!events||count <=0)
390395
returnNULL;
391396

392-
newEvents= (PGEvent*)malloc(count*sizeof(PGEvent));
397+
msize=count*sizeof(PGEvent);
398+
newEvents= (PGEvent*)malloc(msize);
393399
if (!newEvents)
394400
returnNULL;
395401

@@ -407,8 +413,10 @@ dupEvents(PGEvent *events, int count)
407413
free(newEvents);
408414
returnNULL;
409415
}
416+
msize+=strlen(events[i].name)+1;
410417
}
411418

419+
*memSize+=msize;
412420
returnnewEvents;
413421
}
414422

@@ -567,9 +575,12 @@ pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
567575
*/
568576
if (nBytes >=PGRESULT_SEP_ALLOC_THRESHOLD)
569577
{
570-
block= (PGresult_data*)malloc(nBytes+PGRESULT_BLOCK_OVERHEAD);
578+
size_talloc_size=nBytes+PGRESULT_BLOCK_OVERHEAD;
579+
580+
block= (PGresult_data*)malloc(alloc_size);
571581
if (!block)
572582
returnNULL;
583+
res->memorySize+=alloc_size;
573584
space=block->space+PGRESULT_BLOCK_OVERHEAD;
574585
if (res->curBlock)
575586
{
@@ -594,6 +605,7 @@ pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
594605
block= (PGresult_data*)malloc(PGRESULT_DATA_BLOCKSIZE);
595606
if (!block)
596607
returnNULL;
608+
res->memorySize+=PGRESULT_DATA_BLOCKSIZE;
597609
block->next=res->curBlock;
598610
res->curBlock=block;
599611
if (isBinary)
@@ -615,6 +627,18 @@ pqResultAlloc(PGresult *res, size_t nBytes, bool isBinary)
615627
returnspace;
616628
}
617629

630+
/*
631+
* PQresultMemorySize -
632+
*Returns total space allocated for the PGresult.
633+
*/
634+
size_t
635+
PQresultMemorySize(constPGresult*res)
636+
{
637+
if (!res)
638+
return0;
639+
returnres->memorySize;
640+
}
641+
618642
/*
619643
* pqResultStrdup -
620644
*Like strdup, but the space is subsidiary PGresult space.
@@ -927,6 +951,8 @@ pqAddTuple(PGresult *res, PGresAttValue *tup, const char **errmsgp)
927951
realloc(res->tuples,newSize*sizeof(PGresAttValue*));
928952
if (!newTuples)
929953
return false;/* malloc or realloc failed */
954+
res->memorySize+=
955+
(newSize-res->tupArrSize)*sizeof(PGresAttValue*);
930956
res->tupArrSize=newSize;
931957
res->tuples=newTuples;
932958
}

‎src/interfaces/libpq/libpq-fe.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -516,6 +516,7 @@ extern PGresult *PQmakeEmptyPGresult(PGconn *conn, ExecStatusType status);
516516
externPGresult*PQcopyResult(constPGresult*src,intflags);
517517
externintPQsetResultAttrs(PGresult*res,intnumAttributes,PGresAttDesc*attDescs);
518518
externvoid*PQresultAlloc(PGresult*res,size_tnBytes);
519+
externsize_tPQresultMemorySize(constPGresult*res);
519520
externintPQsetvalue(PGresult*res,inttup_num,intfield_num,char*value,intlen);
520521

521522
/* Quoting strings before inclusion in queries. */

‎src/interfaces/libpq/libpq-int.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -208,6 +208,8 @@ struct pg_result
208208
PGresult_data*curBlock;/* most recently allocated block */
209209
intcurOffset;/* start offset of free space in block */
210210
intspaceLeft;/* number of free bytes remaining in block */
211+
212+
size_tmemorySize;/* total space allocated for this PGresult */
211213
};
212214

213215
/* PGAsyncStatusType defines the state of the query-execution state machine */

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp