http://stxxl.sourceforge.net
<dementiev@ira.uka.de>
<singler@kit.edu>
<beckmann@cs.uni-frankfurt.de>
http://www.boost.org/LICENSE_1_0.txt
#include <stxxl/bits/io/boostfd_file.h>
#if STXXL_HAVE_BOOSTFD_FILE
#include <stxxl/bits/io/iostats.h>
#include <stxxl/bits/common/error_handling.h>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/fstream.hpp>
#include <boost/version.hpp>
STXXL_BEGIN_NAMESPACE
void boostfd_file::serve(const request* req) throw (io_error)
{
scoped_mutex_lock fd_lock(fd_mutex);
assert(req->get_file() == this);
offset_type offset = req->get_offset();
void* buffer = req->get_buffer();
size_type bytes = req->get_size();
request::request_type type = req->get_type();
try
{
file_des.seek(offset, BOOST_IOS::beg);
}
catch (const std::exception& ex)
{
STXXL_THROW_ERRNO
(io_error,
"Error doing seek() in boostfd_request::serve()" <<
" offset=" << offset <<
" this=" << this <<
" buffer=" << buffer <<
" bytes=" << bytes <<
" type=" << ((type == request::READ) ? "READ" : "WRITE") <<
" : " << ex.what());
}
stats::scoped_read_write_timer read_write_timer(bytes, type == request::WRITE);
if (type == request::READ)
{
try
{
std::streamsize rc = file_des.read((char*)buffer, bytes);
if (rc != std::streamsize(bytes)) {
STXXL_THROW_ERRNO(io_error, " partial read: " << rc << " missing " << (bytes - rc) << " out of " << bytes << " bytes");
}
}
catch (const std::exception& ex)
{
STXXL_THROW_ERRNO
(io_error,
"Error doing read() in boostfd_request::serve()" <<
" offset=" << offset <<
" this=" << this <<
" buffer=" << buffer <<
" bytes=" << bytes <<
" type=" << ((type == request::READ) ? "READ" : "WRITE") <<
" : " << ex.what());
}
}
else
{
try
{
std::streamsize rc = file_des.write((char*)buffer, bytes);
if (rc != std::streamsize(bytes)) {
STXXL_THROW_ERRNO(io_error, " partial write: " << rc << " missing " << (bytes - rc) << " out of " << bytes << " bytes");
}
}
catch (const std::exception& ex)
{
STXXL_THROW_ERRNO
(io_error,
"Error doing write() in boostfd_request::serve()" <<
" offset=" << offset <<
" this=" << this <<
" buffer=" << buffer <<
" bytes=" << bytes <<
" type=" << ((type == request::READ) ? "READ" : "WRITE") <<
" : " << ex.what());
}
}
}
const char* boostfd_file::io_type() const
{
return "boostfd";
}
boostfd_file::boostfd_file(
const std::string& filename,
int mode,
int queue_id, int allocator_id) : disk_queued_file(queue_id, allocator_id), mode_(mode)
{
BOOST_IOS::openmode boostfd_mode =
(mode & RDWR) ? (BOOST_IOS::out | BOOST_IOS::in) :
(mode & WRONLY) ? (BOOST_IOS::out) :
(mode & RDONLY) ? (BOOST_IOS::in) :
BOOST_IOS::in;
#if defined(BOOST_FILESYSTEM_VERSION) && (BOOST_FILESYSTEM_VERSION >= 3)
const boost::filesystem::path fspath(filename);
#else
const boost::filesystem::path fspath(filename,
boost::filesystem::native);
#endif
if (mode & TRUNC)
{
if (boost::filesystem::exists(fspath))
{
boost::filesystem::remove(fspath);
boost::filesystem::ofstream f(fspath);
f.close();
assert(boost::filesystem::exists(fspath));
}
}
if (mode & CREAT)
{
if (!boost::filesystem::exists(fspath))
{
boost::filesystem::ofstream f(fspath);
f.close();
assert(boost::filesystem::exists(fspath));
}
}
if (mode & DIRECT)
{
STXXL_MSG("Warning: open()ing " << filename << " without DIRECT mode, boostfd does not support it.");
}
if (mode & REQUIRE_DIRECT)
{
STXXL_ERRMSG("Error: open()ing " << filename << " with REQUIRE_DIRECT mode, but boostfd does not support it.");
return;
}
if (mode & SYNC)
{
}
#if (BOOST_VERSION >= 104100)
file_des.open(filename, boostfd_mode);
#else
file_des.open(filename, boostfd_mode, boostfd_mode);
#endif
}
boostfd_file::~boostfd_file()
{
scoped_mutex_lock fd_lock(fd_mutex);
file_des.close();
}
inline file::offset_type boostfd_file::_size()
{
return file_des.seek(0, BOOST_IOS::end);
}
file::offset_type boostfd_file::size()
{
scoped_mutex_lock fd_lock(fd_mutex);
return _size();
}
void boostfd_file::set_size(offset_type newsize)
{
scoped_mutex_lock fd_lock(fd_mutex);
#ifndef NDEBUG
offset_type oldsize = _size();
#endif
file_des.seek(newsize, BOOST_IOS::beg);
file_des.seek(0, BOOST_IOS::beg);
assert(_size() >= oldsize);
}
void boostfd_file::lock()
{
}
STXXL_END_NAMESPACE
#endif