Boost logo

Boost-Commit :

From: technews_at_[hidden]
Date: 2007-12-30 17:21:25


Author: turkanis
Date: 2007-12-30 17:21:24 EST (Sun, 30 Dec 2007)
New Revision: 42380
URL: http://svn.boost.org/trac/boost/changeset/42380

Log:
added Borland 5.8.2 workaround and Cygwin optimization; factored use of mapped_file out of create_large_file() into map_large_file; added documentation
Text files modified:
   branches/iostreams_dev/libs/iostreams/test/large_file_test.cpp | 107 ++++++++++++++++++++++++++++++++-------
   1 files changed, 88 insertions(+), 19 deletions(-)

Modified: branches/iostreams_dev/libs/iostreams/test/large_file_test.cpp
==============================================================================
--- branches/iostreams_dev/libs/iostreams/test/large_file_test.cpp (original)
+++ branches/iostreams_dev/libs/iostreams/test/large_file_test.cpp 2007-12-30 17:21:24 EST (Sun, 30 Dec 2007)
@@ -16,6 +16,7 @@
 #include <ctime>
 #include <string>
 #include <boost/config.hpp> // BOOST_STRINGIZE
+#include <boost/detail/workaround.hpp>
 #include <boost/iostreams/detail/config/rtl.hpp>
 #include <boost/iostreams/detail/config/windows_posix.hpp>
 #include <boost/iostreams/detail/execute.hpp>
@@ -26,6 +27,7 @@
 #include <boost/lexical_cast.hpp>
 #include <boost/test/test_tools.hpp>
 #include <boost/test/unit_test.hpp>
+#include <iostream>
 
     // OS-specific headers for low-level i/o.
 
@@ -148,7 +150,7 @@
 
 #endif
 
- // Fetch last mod date of this file
+ // Fetch last mod date of this file ("large_file_test.cpp")
     string timestamp =
         "$Date$";
     if (timestamp.size() != 53) { // Length of auto-generated SVN timestamp
@@ -169,13 +171,47 @@
     }
 
     // If last commit was two days or more before file timestamp, existing
- // file is okay; otherwise, it must be regenerated
+ // file is okay; otherwise, it must be regenerated (the two-day window
+ // compensates for time zone differences)
     return difftime(last_mod, mktime(&commit)) >= 60 * 60 * 48;
 }
 
+//------------------Definition of map_large_file------------------------------//
+
+// Initializes the large file by mapping it in small segments. This is an
+// optimization for Win32; the straightforward implementation using WriteFile
+// and SetFilePointer (see the Borland workaropund below) is painfully slow.
+bool map_large_file()
+{
+ for (stream_offset z = 0; z <= 8; ++z) {
+ try {
+ mapped_file_params params;
+ params.path = file_name;
+ params.offset = z * gigabyte;
+ params.length = 1;
+ params.mode = BOOST_IOS::out;
+ mapped_file file(params);
+ file.begin()[0] = z + 1;
+ } catch (const std::exception&) {
+ remove_large_file();
+ return false;
+ }
+ }
+ return true;
+}
+
 //------------------Definition of create_large_file---------------------------//
 
-// Creates and initializes the large file if it does not already exist
+// Creates and initializes the large file if it does not already exist. The file
+// looks like this:
+//
+// 0 1GB 2GB 3GB 4GB 5GB 6GB 7GB 8GB
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+// 1.....2.....3.....4.....5.....6.....7.....8.....9
+// +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
+//
+// where the characters 1-9 appear at offsets that are multiples of 1GB and the
+// dots represent uninitialized data.
 bool create_large_file()
 {
     // If file exists, has correct size, and is recent, we're done
@@ -199,11 +235,12 @@
         return false;
 
     // Set file pointer
- LARGE_INTEGER length;
- length.HighPart = 0;
- length.LowPart = 0;
- length.QuadPart = file_size;
- if (!SetFilePointerEx(hnd, length, NULL, FILE_BEGIN)) {
+ LONG off_low = static_cast<LONG>(file_size & 0xffffffff);
+ LONG off_high = static_cast<LONG>(file_size >> 32);
+ if ( SetFilePointer(hnd, off_low, &off_high, FILE_BEGIN) ==
+ INVALID_SET_FILE_POINTER &&
+ GetLastError() != NO_ERROR )
+ {
         CloseHandle(hnd);
         remove_large_file();
         return false;
@@ -216,27 +253,47 @@
         return false;
     }
 
+# if !BOOST_WORKAROUND(__BORLANDC__, == 0x582)
+
     // Close handle; all further access is via mapped_file
     CloseHandle(hnd);
 
     // Initialize file data
- for (int z = 0; z <= 8; ++z) {
- try {
- mapped_file_params params;
- params.path = file_name;
- params.offset = z * gigabyte;
- params.length = 1;
- params.mode = BOOST_IOS::out;
- mapped_file file(params);
- file.begin()[0] = z + 1;
- } catch (...) {
+ return map_large_file();
+
+# else // Borland 5.8.2
+
+ // Initialize file data (very slow, even though only 9 writes are required)
+ for (stream_offset z = 0; z <= 8; ++z) {
+
+ // Seek
+ LONG off_low = static_cast<LONG>((z * gigabyte) & 0xffffffff); // == 0
+ LONG off_high = static_cast<LONG>((z * gigabyte) >> 32);
+ if ( SetFilePointer(hnd, off_low, &off_high, FILE_BEGIN) ==
+ INVALID_SET_FILE_POINTER &&
+ GetLastError() != NO_ERROR )
+ {
+ CloseHandle(hnd);
+ remove_large_file();
+ return false;
+ }
+
+ // Write a character
+ char buf[1] = { z + 1 };
+ DWORD result;
+ BOOL success = WriteFile(hnd, buf, 1, &result, NULL);
+ if (!success || result != 1) {
+ CloseHandle(hnd);
+ remove_large_file();
             return false;
         }
     }
 
     // Close file
+ CloseHandle(hnd);
         return true;
 
+# endif // Borland 5.8.2 workaround
 #else // #ifdef BOOST_IOSTREAMS_WINDOWS
 
     // Create file
@@ -258,6 +315,8 @@
         return false;
     }
 
+# ifndef __CYGWIN__
+
     // Initialize file data
     for (int z = 0; z <= 8; ++z) {
 
@@ -284,6 +343,16 @@
     // Close file
     BOOST_IOSTREAMS_FD_CLOSE(fd);
         return true;
+
+# else // Cygwin
+
+ // Close descriptor; all further access is via mapped_file
+ BOOST_IOSTREAMS_FD_CLOSE(fd);
+
+ // Initialize file data
+ return map_large_file();
+
+# endif
 #endif // #ifdef BOOST_IOSTREAMS_WINDOWS
 }
 
@@ -326,7 +395,7 @@
     // Prepare file and file descriptor
     large_file large;
     file_descriptor_source file;
- BOOST_CHECK_MESSAGE(large.exists(), "failed creating file");
+ BOOST_REQUIRE_MESSAGE(large.exists(), "failed creating file");
     BOOST_CHECK_NO_THROW(file.open(large.path(), BOOST_IOS::binary));
 
     // Test seeking using ios_base::beg


Boost-Commit list run by bdawes at acm.org, david.abrahams at rcn.com, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk