aboutsummaryrefslogtreecommitdiff
path: root/src/libutil/serialise.hh
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2011-12-15 16:19:53 +0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2011-12-15 16:19:53 +0000
commit5a1b9ed0aa3a0c240b667dbe504b61b2b68e4d16 (patch)
treec55e8148f4aca9cc12294b33bdd052ae3934a71b /src/libutil/serialise.hh
parenta67b8ae22450a0fe10698042b452f5f2f322e008 (diff)
* Refactoring: move sink/source buffering into separate classes.
* Buffer the HashSink. This speeds up hashing a bit because it prevents lots of calls to the hash update functions (e.g. nix-hash went from 9.3s to 8.7s of user time on the closure of my /var/run/current-system).
Diffstat (limited to 'src/libutil/serialise.hh')
-rw-r--r--src/libutil/serialise.hh96
1 files changed, 55 insertions, 41 deletions
diff --git a/src/libutil/serialise.hh b/src/libutil/serialise.hh
index b8d4d7a84..a0588668f 100644
--- a/src/libutil/serialise.hh
+++ b/src/libutil/serialise.hh
@@ -11,7 +11,25 @@ namespace nix {
struct Sink
{
virtual ~Sink() { }
- virtual void operator () (const unsigned char * data, unsigned int len) = 0;
+ virtual void operator () (const unsigned char * data, size_t len) = 0;
+};
+
+
+/* A buffered abstract sink. */
+struct BufferedSink : Sink
+{
+ size_t bufSize, bufPos;
+ unsigned char * buffer;
+
+ BufferedSink(size_t bufSize = 32 * 1024)
+ : bufSize(bufSize), bufPos(0), buffer(0) { }
+ ~BufferedSink();
+
+ void operator () (const unsigned char * data, size_t len);
+
+ void flush();
+
+ virtual void write(const unsigned char * data, size_t len) = 0;
};
@@ -20,56 +38,52 @@ struct Source
{
virtual ~Source() { }
- /* The callee should store exactly *len bytes in the buffer
- pointed to by data. It should block if that much data is not
- yet available, or throw an error if it is not going to be
- available. */
- virtual void operator () (unsigned char * data, unsigned int len) = 0;
+ /* Store exactly ‘len’ bytes in the buffer pointed to by ‘data’.
+ It blocks if that much data is not yet available, or throws an
+ error if it is not going to be available. */
+ virtual void operator () (unsigned char * data, size_t len) = 0;
};
-/* A sink that writes data to a file descriptor (using a buffer). */
-struct FdSink : Sink
+/* A buffered abstract source. */
+struct BufferedSource : Source
{
- int fd;
- unsigned int bufSize, bufPos;
+ size_t bufSize, bufPosIn, bufPosOut;
unsigned char * buffer;
- FdSink() : fd(-1), bufSize(32 * 1024), bufPos(0), buffer(0) { }
+ BufferedSource(size_t bufSize = 32 * 1024)
+ : bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(0) { }
+ ~BufferedSource();
- FdSink(int fd, unsigned int bufSize = 32 * 1024)
- : fd(fd), bufSize(bufSize), bufPos(0), buffer(0) { }
-
- ~FdSink()
- {
- flush();
- if (buffer) delete[] buffer;
- }
+ void operator () (unsigned char * data, size_t len);
- void operator () (const unsigned char * data, unsigned int len);
-
- void flush();
+ /* Store up to ‘len’ in the buffer pointed to by ‘data’, and
+ return the number of bytes stored. If should block until at
+ least one byte is available. */
+ virtual size_t read(unsigned char * data, size_t len) = 0;
};
-/* A source that reads data from a file descriptor. */
-struct FdSource : Source
+/* A sink that writes data to a file descriptor. */
+struct FdSink : BufferedSink
{
int fd;
- unsigned int bufSize, bufPosIn, bufPosOut;
- unsigned char * buffer;
- FdSource() : fd(-1), bufSize(32 * 1024), bufPosIn(0), bufPosOut(0), buffer(0) { }
-
- FdSource(int fd, unsigned int bufSize = 32 * 1024)
- : fd(fd), bufSize(bufSize), bufPosIn(0), bufPosOut(0), buffer(0) { }
-
- ~FdSource()
- {
- if (buffer) delete[] buffer;
- }
+ FdSink() : fd(-1) { }
+ FdSink(int fd) : fd(fd) { }
+ ~FdSink() { flush(); }
- void operator () (unsigned char * data, unsigned int len);
+ void write(const unsigned char * data, size_t len);
+};
+
+
+/* A source that reads data from a file descriptor. */
+struct FdSource : BufferedSource
+{
+ int fd;
+ FdSource() : fd(-1) { }
+ FdSource(int fd) : fd(fd) { }
+ size_t read(unsigned char * data, size_t len);
};
@@ -77,7 +91,7 @@ struct FdSource : Source
struct StringSink : Sink
{
string s;
- virtual void operator () (const unsigned char * data, unsigned int len)
+ void operator () (const unsigned char * data, size_t len)
{
s.append((const char *) data, len);
}
@@ -88,9 +102,9 @@ struct StringSink : Sink
struct StringSource : Source
{
const string & s;
- unsigned int pos;
+ size_t pos;
StringSource(const string & _s) : s(_s), pos(0) { }
- virtual void operator () (unsigned char * data, unsigned int len)
+ virtual void operator () (unsigned char * data, size_t len)
{
s.copy((char *) data, len, pos);
pos += len;
@@ -100,13 +114,13 @@ struct StringSource : Source
};
-void writePadding(unsigned int len, Sink & sink);
+void writePadding(size_t len, Sink & sink);
void writeInt(unsigned int n, Sink & sink);
void writeLongLong(unsigned long long n, Sink & sink);
void writeString(const string & s, Sink & sink);
void writeStringSet(const StringSet & ss, Sink & sink);
-void readPadding(unsigned int len, Source & source);
+void readPadding(size_t len, Source & source);
unsigned int readInt(Source & source);
unsigned long long readLongLong(Source & source);
string readString(Source & source);