Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * io/boostfd_file.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2006 Roman Dementiev <dementiev@ira.uka.de> 00007 * Copyright (C) 2009, 2010 Johannes Singler <singler@kit.edu> 00008 * Copyright (C) 2008, 2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00009 * 00010 * Distributed under the Boost Software License, Version 1.0. 00011 * (See accompanying file LICENSE_1_0.txt or copy at 00012 * http://www.boost.org/LICENSE_1_0.txt) 00013 **************************************************************************/ 00014 00015 #include <stxxl/bits/io/boostfd_file.h> 00016 00017 #if STXXL_HAVE_BOOSTFD_FILE 00018 00019 #include <stxxl/bits/io/iostats.h> 00020 #include <stxxl/bits/common/error_handling.h> 00021 00022 #include <boost/filesystem/operations.hpp> 00023 #include <boost/filesystem/fstream.hpp> 00024 #include <boost/version.hpp> 00025 00026 00027 __STXXL_BEGIN_NAMESPACE 00028 00029 00030 void boostfd_file::serve(const request * req) throw (io_error) 00031 { 00032 scoped_mutex_lock fd_lock(fd_mutex); 00033 assert(req->get_file() == this); 00034 offset_type offset = req->get_offset(); 00035 void * buffer = req->get_buffer(); 00036 size_type bytes = req->get_size(); 00037 request::request_type type = req->get_type(); 00038 00039 try 00040 { 00041 file_des.seek(offset, BOOST_IOS::beg); 00042 } 00043 catch (const std::exception & ex) 00044 { 00045 STXXL_THROW2(io_error, 00046 "Error doing seek() in boostfd_request::serve()" << 00047 " offset=" << offset << 00048 " this=" << this << 00049 " buffer=" << buffer << 00050 " bytes=" << bytes << 00051 " type=" << ((type == request::READ) ? "READ" : "WRITE") << 00052 " : " << ex.what()); 00053 } 00054 00055 stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE); 00056 00057 if (type == request::READ) 00058 { 00059 try 00060 { 00061 std::streamsize rc = file_des.read((char *)buffer, bytes); 00062 if (rc != std::streamsize(bytes)) { 00063 STXXL_THROW2(io_error, " partial read: missing " << (bytes - rc) << " out of " << bytes << " bytes"); 00064 } 00065 } 00066 catch (const std::exception & ex) 00067 { 00068 STXXL_THROW2(io_error, 00069 "Error doing read() in boostfd_request::serve()" << 00070 " offset=" << offset << 00071 " this=" << this << 00072 " buffer=" << buffer << 00073 " bytes=" << bytes << 00074 " type=" << ((type == request::READ) ? "READ" : "WRITE") << 00075 " : " << ex.what()); 00076 } 00077 } 00078 else 00079 { 00080 try 00081 { 00082 std::streamsize rc = file_des.write((char *)buffer, bytes); 00083 if (rc != std::streamsize(bytes)) { 00084 STXXL_THROW2(io_error, " partial read: missing " << (bytes - rc) << " out of " << bytes << " bytes"); 00085 } 00086 } 00087 catch (const std::exception & ex) 00088 { 00089 STXXL_THROW2(io_error, 00090 "Error doing write() in boostfd_request::serve()" << 00091 " offset=" << offset << 00092 " this=" << this << 00093 " buffer=" << buffer << 00094 " bytes=" << bytes << 00095 " type=" << ((type == request::READ) ? "READ" : "WRITE") << 00096 " : " << ex.what()); 00097 } 00098 } 00099 } 00100 00101 const char * boostfd_file::io_type() const 00102 { 00103 return "boostfd"; 00104 } 00105 00106 boostfd_file::boostfd_file( 00107 const std::string & filename, 00108 int mode, 00109 int queue_id, int allocator_id) : disk_queued_file(queue_id, allocator_id), mode_(mode) 00110 { 00111 BOOST_IOS::openmode boostfd_mode; 00112 00113 if (mode & RDONLY) 00114 { 00115 boostfd_mode = BOOST_IOS::in; 00116 } 00117 00118 if (mode & WRONLY) 00119 { 00120 boostfd_mode = BOOST_IOS::out; 00121 } 00122 00123 if (mode & RDWR) 00124 { 00125 boostfd_mode = BOOST_IOS::out | BOOST_IOS::in; 00126 } 00127 00128 #if defined(BOOST_FILESYSTEM_VERSION) && (BOOST_FILESYSTEM_VERSION >= 3) 00129 const boost::filesystem::path fspath(filename); 00130 #else 00131 const boost::filesystem::path fspath(filename, 00132 boost::filesystem::native); 00133 #endif 00134 00135 if (mode & TRUNC) 00136 { 00137 if (boost::filesystem::exists(fspath)) 00138 { 00139 boost::filesystem::remove(fspath); 00140 boost::filesystem::ofstream f(fspath); 00141 f.close(); 00142 assert(boost::filesystem::exists(fspath)); 00143 } 00144 } 00145 00146 if (mode & CREAT) 00147 { 00148 // need to be emulated: 00149 if (!boost::filesystem::exists(fspath)) 00150 { 00151 boost::filesystem::ofstream f(fspath); 00152 f.close(); 00153 assert(boost::filesystem::exists(fspath)); 00154 } 00155 } 00156 00157 #ifndef STXXL_DIRECT_IO_OFF 00158 if (mode & DIRECT) 00159 { 00160 // direct mode not supported in Boost 00161 } 00162 #endif 00163 00164 if (mode & SYNC) 00165 { 00166 // ??? 00167 } 00168 00169 #if (BOOST_VERSION >= 104100) 00170 file_des.open(filename, boostfd_mode); // also compiles with earlier Boost versions, but differs semantically 00171 #else 00172 file_des.open(filename, boostfd_mode, boostfd_mode); 00173 #endif 00174 } 00175 00176 boostfd_file::~boostfd_file() 00177 { 00178 scoped_mutex_lock fd_lock(fd_mutex); 00179 file_des.close(); 00180 } 00181 00182 inline file::offset_type boostfd_file::_size() 00183 { 00184 return file_des.seek(0, BOOST_IOS::end); 00185 } 00186 00187 file::offset_type boostfd_file::size() 00188 { 00189 scoped_mutex_lock fd_lock(fd_mutex); 00190 return _size(); 00191 } 00192 00193 void boostfd_file::set_size(offset_type newsize) 00194 { 00195 scoped_mutex_lock fd_lock(fd_mutex); 00196 offset_type oldsize = _size(); 00197 file_des.seek(newsize, BOOST_IOS::beg); 00198 file_des.seek(0, BOOST_IOS::beg); // not important ? 00199 assert(_size() >= oldsize); 00200 } 00201 00202 void boostfd_file::lock() 00203 { 00204 // FIXME: is there no locking possible/needed/... for boostfd? 00205 } 00206 00207 __STXXL_END_NAMESPACE 00208 00209 #endif // #if STXXL_HAVE_BOOSTFD_FILE 00210 // vim: et:ts=4:sw=4