forked from lix-project/lix
* Buffer reads in FdSource. Together with write buffering, this
significantly cuts down the number of syscalls (e.g., for "nix-store -qR /var/run/current-system" via the daemon, it reduced the number of syscalls in the client from 29134 to 4766 and in the daemon from 44266 to 20666).
This commit is contained in:
parent
3a48282b06
commit
a3e0656cbb
|
@ -2,6 +2,7 @@
|
||||||
#include "util.hh"
|
#include "util.hh"
|
||||||
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
|
#include <cerrno>
|
||||||
|
|
||||||
|
|
||||||
namespace nix {
|
namespace nix {
|
||||||
|
@ -38,7 +39,28 @@ void FdSink::flush()
|
||||||
|
|
||||||
void FdSource::operator () (unsigned char * data, unsigned int len)
|
void FdSource::operator () (unsigned char * data, unsigned int len)
|
||||||
{
|
{
|
||||||
readFull(fd, data, len);
|
if (!buffer) buffer = new unsigned char[bufSize];
|
||||||
|
|
||||||
|
while (len) {
|
||||||
|
if (!bufPosIn) {
|
||||||
|
/* Read as much data as is available (up to the buffer
|
||||||
|
size). */
|
||||||
|
checkInterrupt();
|
||||||
|
ssize_t n = read(fd, (char *) buffer, bufSize);
|
||||||
|
if (n == -1) {
|
||||||
|
if (errno == EINTR) continue;
|
||||||
|
throw SysError("reading from file");
|
||||||
|
}
|
||||||
|
if (n == 0) throw EndOfFile("unexpected end-of-file");
|
||||||
|
bufPosIn = n;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Copy out the data in the buffer. */
|
||||||
|
size_t n = len > bufPosIn - bufPosOut ? bufPosIn - bufPosOut : len;
|
||||||
|
memcpy(data, buffer + bufPosOut, n);
|
||||||
|
data += n; bufPosOut += n; len -= n;
|
||||||
|
if (bufPosIn == bufPosOut) bufPosIn = bufPosOut = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -38,9 +38,7 @@ struct FdSink : Sink
|
||||||
FdSink() : fd(-1), bufSize(32 * 1024), bufPos(0), buffer(0) { }
|
FdSink() : fd(-1), bufSize(32 * 1024), bufPos(0), buffer(0) { }
|
||||||
|
|
||||||
FdSink(int fd, unsigned int bufSize = 32 * 1024)
|
FdSink(int fd, unsigned int bufSize = 32 * 1024)
|
||||||
: fd(fd), bufSize(bufSize), bufPos(0), buffer(0)
|
: fd(fd), bufSize(bufSize), bufPos(0), buffer(0) { }
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
~FdSink()
|
~FdSink()
|
||||||
{
|
{
|
||||||
|
@ -58,15 +56,17 @@ struct FdSink : Sink
|
||||||
struct FdSource : Source
|
struct FdSource : Source
|
||||||
{
|
{
|
||||||
int fd;
|
int fd;
|
||||||
|
unsigned int bufSize, bufPosIn, bufPosOut;
|
||||||
|
unsigned char * buffer;
|
||||||
|
|
||||||
FdSource()
|
FdSource() : fd(-1), bufSize(32 * 1024), bufPosIn(0), bufPosOut(0), buffer(0) { }
|
||||||
{
|
|
||||||
fd = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
FdSource(int fd)
|
FdSource(int fd, unsigned int bufSize = 32 * 1024)
|
||||||
|
: fd(fd), bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(0) { }
|
||||||
|
|
||||||
|
~FdSource()
|
||||||
{
|
{
|
||||||
this->fd = fd;
|
if (buffer) delete[] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
void operator () (unsigned char * data, unsigned int len);
|
void operator () (unsigned char * data, unsigned int len);
|
||||||
|
|
Loading…
Reference in a new issue