From b8a589bb1d5e4d1e10d0da77048ca9522755095c Mon Sep 17 00:00:00 2001 From: Brad King Date: Thu, 13 Apr 2006 22:56:32 -0400 Subject: ENH: Improved implementation of FilesDiffer to avoid allocating enough memory for the entire file twice. Instead using a block-at-a-time comparison. --- Source/kwsys/SystemTools.cxx | 47 ++++++++++++++++++++++++++------------------ 1 file 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(finSource.gcount()) != nnext || + static_cast(finDestination.gcount()) != nnext) + { + return true; + } - if(statSource.st_size != static_cast(finSource.gcount()) || - statSource.st_size != static_cast(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; } -- cgit v0.12