diff options
author | Brad King <brad.king@kitware.com> | 2006-04-14 02:56:32 (GMT) |
---|---|---|
committer | Brad King <brad.king@kitware.com> | 2006-04-14 02:56:32 (GMT) |
commit | b8a589bb1d5e4d1e10d0da77048ca9522755095c (patch) | |
tree | e43d73ef06cb4d737b2c8b25276fce2eda361dfe /Source | |
parent | 58d0c5e17670a61d7fb9b4be5978e1b29f801bb4 (diff) | |
download | CMake-b8a589bb1d5e4d1e10d0da77048ca9522755095c.zip CMake-b8a589bb1d5e4d1e10d0da77048ca9522755095c.tar.gz CMake-b8a589bb1d5e4d1e10d0da77048ca9522755095c.tar.bz2 |
ENH: Improved implementation of FilesDiffer to avoid allocating enough memory for the entire file twice. Instead using a block-at-a-time comparison.
Diffstat (limited to 'Source')
-rw-r--r-- | Source/kwsys/SystemTools.cxx | 47 |
1 files changed, 28 insertions, 19 deletions
diff --git a/Source/kwsys/SystemTools.cxx b/Source/kwsys/SystemTools.cxx index b404914..93cc5b3 100644 --- a/Source/kwsys/SystemTools.cxx +++ b/Source/kwsys/SystemTools.cxx @@ -1419,7 +1419,8 @@ bool SystemTools::CopyFileIfDifferent(const char* source, return true; } - +#define KWSYS_ST_BUFFER 4096 + bool SystemTools::FilesDiffer(const char* source, const char* destination) { @@ -1459,28 +1460,36 @@ bool SystemTools::FilesDiffer(const char* source, return true; } - char* source_buf = new char[statSource.st_size]; - char* dest_buf = new char[statSource.st_size]; + // Compare the files a block at a time. + char source_buf[KWSYS_ST_BUFFER]; + char dest_buf[KWSYS_ST_BUFFER]; + long nleft = statSource.st_size; + while(nleft > 0) + { + // Read a block from each file. + long nnext = (nleft > KWSYS_ST_BUFFER)? KWSYS_ST_BUFFER : nleft; + finSource.read(source_buf, nnext); + finDestination.read(dest_buf, nnext); - finSource.read(source_buf, statSource.st_size); - finDestination.read(dest_buf, statSource.st_size); + // If either failed to read assume they are different. + if(static_cast<long>(finSource.gcount()) != nnext || + static_cast<long>(finDestination.gcount()) != nnext) + { + return true; + } - if(statSource.st_size != static_cast<long>(finSource.gcount()) || - statSource.st_size != static_cast<long>(finDestination.gcount())) - { - // Failed to read files. - delete [] source_buf; - delete [] dest_buf; - return true; - } - int ret = memcmp((const void*)source_buf, - (const void*)dest_buf, - statSource.st_size); + // If this block differs the file differs. + if(memcmp((const void*)source_buf, (const void*)dest_buf, nnext) != 0) + { + return true; + } - delete [] dest_buf; - delete [] source_buf; + // Update the byte count remaining. + nleft -= nnext; + } - return ret != 0; + // No differences found. + return false; } |