From: | Melih Mutlu <m(dot)melihmutlu(at)gmail(dot)com> |
---|---|
To: | Heikki Linnakangas <hlinnaka(at)iki(dot)fi> |
Cc: | Andres Freund <andres(at)anarazel(dot)de>, PostgreSQL Hackers <pgsql-hackers(at)lists(dot)postgresql(dot)org>, Robert Haas <robertmhaas(at)gmail(dot)com>, Jelte Fennema-Nio <postgres(at)jeltef(dot)nl>, Thomas Munro <thomas(dot)munro(at)gmail(dot)com> |
Subject: | Re: Flushing large data immediately in pqcomm |
Date: | 2024-03-21 23:07:56 |
Message-ID: | CAGPVpCQAUPtOYVrw-877CEb41sC1RT-Tt30jrWQG9Wtt0L6R9g@mail.gmail.com |
Views: | Raw Message | Whole Thread | Download mbox | Resend email |
Thread: | |
Lists: | pgsql-hackers |
Heikki Linnakangas <hlinnaka(at)iki(dot)fi>, 14 Mar 2024 Per, 15:46 tarihinde şunu
yazdı:
> On 14/03/2024 13:22, Melih Mutlu wrote:
> > @@ -1282,14 +1283,32 @@ internal_putbytes(const char *s, size_t len)
> > if (internal_flush())
> > return EOF;
> > }
> > - amount = PqSendBufferSize - PqSendPointer;
> > - if (amount > len)
> > - amount = len;
> > - memcpy(PqSendBuffer + PqSendPointer, s, amount);
> > - PqSendPointer += amount;
> > - s += amount;
> > - len -= amount;
> > +
> > + /*
> > + * If the buffer is empty and data length is larger than
> the buffer
> > + * size, send it without buffering. Otherwise, put as much
> data as
> > + * possible into the buffer.
> > + */
> > + if (!pq_is_send_pending() && len >= PqSendBufferSize)
> > + {
> > + int start = 0;
> > +
> > + socket_set_nonblocking(false);
> > + if (internal_flush_buffer(s, &start, (int *)&len))
> > + return EOF;
> > + }
> > + else
> > + {
> > + amount = PqSendBufferSize - PqSendPointer;
> > + if (amount > len)
> > + amount = len;
> > + memcpy(PqSendBuffer + PqSendPointer, s, amount);
> > + PqSendPointer += amount;
> > + s += amount;
> > + len -= amount;
> > + }
> > }
> > +
> > return 0;
> > }
>
> Two small bugs:
>
> - the "(int *) &len)" cast is not ok, and will break visibly on
> big-endian systems where sizeof(int) != sizeof(size_t).
>
> - If internal_flush_buffer() cannot write all the data in one call, it
> updates 'start' for how much it wrote, and leaves 'end' unchanged. You
> throw the updated 'start' value away, and will send the same data again
> on next iteration.
>
There are two possible options for internal_flush_buffer() in
internal_putbytes() case:
1- Write all the data and return 0. We don't need start or end of the data
in this case.
2- Cannot write all and return EOF. In this case internal_putbytes() also
returns EOF immediately and does not really retry. There will be no next
iteration.
If it was non-blocking, then we may need to keep the new value. But I think
we do not need the updated start value in both cases here. What do you
think?
Thanks,
--
Melih Mutlu
Microsoft
From | Date | Subject | |
---|---|---|---|
Next Message | Tom Lane | 2024-03-21 23:17:28 | Re: Catalog domain not-null constraints |
Previous Message | Tom Lane | 2024-03-21 23:02:47 | Re: Regression tests fail with musl libc because libpq.so can't be loaded |