Re: Flushing large data immediately in pqcomm

Поиск
Список
Период
Сортировка
От Melih Mutlu
Тема Re: Flushing large data immediately in pqcomm
Дата
Msg-id CAGPVpCQAUPtOYVrw-877CEb41sC1RT-Tt30jrWQG9Wtt0L6R9g@mail.gmail.com
обсуждение исходный текст
Ответ на Re: Flushing large data immediately in pqcomm  (Heikki Linnakangas <hlinnaka@iki.fi>)
Список pgsql-hackers


Heikki Linnakangas <hlinnaka@iki.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

В списке pgsql-hackers по дате отправления:

Предыдущее
От: Peter Eisentraut
Дата:
Сообщение: Re: [HACKERS] make async slave to wait for lsn to be replayed
Следующее
От: Tom Lane
Дата:
Сообщение: Re: Catalog domain not-null constraints