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

Commit3ec5232

Browse files
committed
Patch to cure O(N^2) behavior in libpq when reading a long
message under a kernel that only returns one packet per recv() call. Thisdidn't use to matter much, but it starts to get annoying with multi-megabyteEXPLAIN VERBOSE responses...
1 parentad4a574 commit3ec5232

File tree

1 file changed

+25
-3
lines changed

1 file changed

+25
-3
lines changed

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

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*
2525
*
2626
* IDENTIFICATION
27-
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.29 1999/08/31 01:37:36 tgl Exp $
27+
* $Header: /cvsroot/pgsql/src/interfaces/libpq/fe-misc.c,v 1.30 1999/09/13 03:00:19 tgl Exp $
2828
*
2929
*-------------------------------------------------------------------------
3030
*/
@@ -307,6 +307,7 @@ pqReadReady(PGconn *conn)
307307
int
308308
pqReadData(PGconn*conn)
309309
{
310+
intsomeread=0;
310311
intnread;
311312

312313
if (conn->sock<0)
@@ -359,11 +360,11 @@ pqReadData(PGconn *conn)
359360
/* Some systems return EAGAIN/EWOULDBLOCK for no data */
360361
#ifdefEAGAIN
361362
if (errno==EAGAIN)
362-
return0;
363+
returnsomeread;
363364
#endif
364365
#if defined(EWOULDBLOCK)&& (!defined(EAGAIN)|| (EWOULDBLOCK!=EAGAIN))
365366
if (errno==EWOULDBLOCK)
366-
return0;
367+
returnsomeread;
367368
#endif
368369
/* We might get ECONNRESET here if using TCP and backend died */
369370
#ifdefECONNRESET
@@ -378,9 +379,30 @@ pqReadData(PGconn *conn)
378379
if (nread>0)
379380
{
380381
conn->inEnd+=nread;
382+
/*
383+
* Hack to deal with the fact that some kernels will only give us
384+
* back 1 packet per recv() call, even if we asked for more and there
385+
* is more available. If it looks like we are reading a long message,
386+
* loop back to recv() again immediately, until we run out of data
387+
* or buffer space. Without this, the block-and-restart behavior of
388+
* libpq's higher levels leads to O(N^2) performance on long messages.
389+
*
390+
* Since we left-justified the data above, conn->inEnd gives the
391+
* amount of data already read in the current message. We consider
392+
* the message "long" once we have acquired 32k ...
393+
*/
394+
if (conn->inEnd>32768&&
395+
(conn->inBufSize-conn->inEnd) >=8192)
396+
{
397+
someread=1;
398+
gototryAgain;
399+
}
381400
return1;
382401
}
383402

403+
if (someread)
404+
return1;/* got a zero read after successful tries */
405+
384406
/*
385407
* A return value of 0 could mean just that no data is now available,
386408
* or it could mean EOF --- that is, the server has closed the

0 commit comments

Comments
 (0)

[8]ページ先頭

©2009-2025 Movatter.jp