about summary refs log tree commit diff
path: root/src/libutil/serialise.hh
diff options
context:
space:
mode:
authorEelco Dolstra <e.dolstra@tudelft.nl>2011-12-15T16·19+0000
committerEelco Dolstra <e.dolstra@tudelft.nl>2011-12-15T16·19+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 b8d4d7a849..a0588668f0 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);