diff options
author | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-09-22T13·10+0000 |
---|---|---|
committer | Eelco Dolstra <e.dolstra@tudelft.nl> | 2006-09-22T13·10+0000 |
commit | 666babbbfa2fc168b8d511a35065d352b4979dae (patch) | |
tree | 85f46294983bf38d17100b12d7067d7149356d0d /src/libstore | |
parent | 385c6f87373303f6e4c9f4e67e02507641a268f2 (diff) |
* Use a bounded amount of memory in scanForReferences() by not reading
regular files into memory all at once.
Diffstat (limited to 'src/libstore')
-rw-r--r-- | src/libstore/references.cc | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/libstore/references.cc b/src/libstore/references.cc index 836d9aa9ac8d..19cb288bdd6b 100644 --- a/src/libstore/references.cc +++ b/src/libstore/references.cc @@ -1,5 +1,3 @@ -#define __STDC_LIMIT_MACROS - #include "references.hh" #include "hash.hh" #include "util.hh" @@ -13,8 +11,6 @@ #include <dirent.h> #include <fcntl.h> -#include <stdint.h> - namespace nix { @@ -80,14 +76,35 @@ void checkPath(const string & path, AutoCloseFD fd = open(path.c_str(), O_RDONLY); if (fd == -1) throw SysError(format("opening file `%1%'") % path); - if (st.st_size >= SIZE_MAX) - throw Error(format("cannot allocate %1% bytes") % st.st_size); + size_t bufSize = 1024 * 1024; + assert(refLength <= bufSize); + unsigned char * buf = new unsigned char[bufSize]; - unsigned char * buf = new unsigned char[st.st_size]; + size_t left = st.st_size; + bool firstBlock = true; + + while (left > 0) { + checkInterrupt(); + + size_t read = left > bufSize ? bufSize : left; + size_t copiedBytes = 0; + + if (!firstBlock) { + /* Move the last (refLength - 1) bytes from the last + block to the start of the buffer to deal with + references that cross block boundaries. */ + copiedBytes = refLength - 1; + if (read + copiedBytes > bufSize) + read -= copiedBytes; + memcpy(buf, buf + (bufSize - copiedBytes), copiedBytes); + } + firstBlock = false; - readFull(fd, buf, st.st_size); + readFull(fd, buf + copiedBytes, read); + left -= read; - search(st.st_size, buf, ids, seen); + search(copiedBytes + read, buf, ids, seen); + } delete[] buf; /* !!! autodelete */ } |