* 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 changed files with 32 additions and 10 deletions
				
			
		|  | @ -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…
	
	Add table
		Add a link
		
	
		Reference in a new issue