http://stxxl.sourceforge.net
<dementiev@mpi-sb.mpg.de>
<beckmann@cs.uni-frankfurt.de>
<singler@ira.uka.de>
<tb@panthema.net>
http://www.boost.org/LICENSE_1_0.txt
#include <stxxl/bits/common/error_handling.h>
#include <stxxl/bits/common/exceptions.h>
#include <stxxl/bits/io/create_file.h>
#include <stxxl/bits/io/io.h>
#include <stxxl/bits/mng/config.h>
#include <ostream>
#include <stdexcept>
STXXL_BEGIN_NAMESPACE
file * create_file(const std::string& io_impl,
const std::string& filename,
int options, int physical_device_id, int disk_allocator_id)
{
disk_config cfg(filename, 0, io_impl);
cfg.queue = physical_device_id;
cfg.direct =
(options& file::REQUIRE_DIRECT) ? disk_config::DIRECT_ON :
(options& file::DIRECT) ? disk_config::DIRECT_TRY :
disk_config::DIRECT_OFF;
return create_file(cfg, options, disk_allocator_id);
}
file * create_file(disk_config& cfg, int mode, int disk_allocator_id)
{
mode &= ~(file::DIRECT | file::REQUIRE_DIRECT);
switch (cfg.direct) {
case disk_config::DIRECT_OFF:
break;
case disk_config::DIRECT_TRY:
mode |= file::DIRECT;
break;
case disk_config::DIRECT_ON:
mode |= file::DIRECT | file::REQUIRE_DIRECT;
break;
}
if (cfg.io_impl == "syscall")
{
ufs_file_base* result =
new syscall_file(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
if (cfg.raw_device && !result->is_device())
{
delete result;
STXXL_THROW(io_error, "Disk " << cfg.path << " was expected to be raw block device, but it is a normal file!");
}
if (result->is_device())
{
cfg.raw_device = true;
cfg.size = result->size();
cfg.autogrow = cfg.delete_on_exit = cfg.unlink_on_open = false;
}
if (cfg.unlink_on_open)
result->unlink();
return result;
}
else if (cfg.io_impl == "fileperblock_syscall")
{
fileperblock_file<syscall_file>* result =
new fileperblock_file<syscall_file>(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
else if (cfg.io_impl == "memory")
{
mem_file* result = new mem_file(cfg.queue, disk_allocator_id);
result->lock();
return result;
}
#if STXXL_HAVE_MMAP_FILE
else if (cfg.io_impl == "mmap")
{
ufs_file_base* result =
new mmap_file(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
if (cfg.unlink_on_open)
result->unlink();
return result;
}
else if (cfg.io_impl == "fileperblock_mmap")
{
fileperblock_file<mmap_file>* result =
new fileperblock_file<mmap_file>(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
#endif
#if STXXL_HAVE_SIMDISK_FILE
else if (cfg.io_impl == "simdisk")
{
mode &= ~(file::DIRECT | file::REQUIRE_DIRECT);
ufs_file_base* result =
new sim_disk_file(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
#endif
#if STXXL_HAVE_WINCALL_FILE
else if (cfg.io_impl == "wincall")
{
wfs_file_base* result =
new wincall_file(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
else if (cfg.io_impl == "fileperblock_wincall")
{
fileperblock_file<wincall_file>* result =
new fileperblock_file<wincall_file>(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
#endif
#if STXXL_HAVE_BOOSTFD_FILE
else if (cfg.io_impl == "boostfd")
{
boostfd_file* result =
new boostfd_file(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
else if (cfg.io_impl == "fileperblock_boostfd")
{
fileperblock_file<boostfd_file>* result =
new fileperblock_file<boostfd_file>(cfg.path, mode, cfg.queue, disk_allocator_id);
result->lock();
return result;
}
#endif
#if STXXL_HAVE_WBTL_FILE
else if (cfg.io_impl == "wbtl")
{
ufs_file_base* backend =
new syscall_file(cfg.path, mode, -1, -1);
wbtl_file* result =
new stxxl::wbtl_file(backend, 16 * 1024 * 1024, 2, cfg.queue, disk_allocator_id);
result->lock();
if (cfg.unlink_on_open)
backend->unlink();
return result;
}
#endif
STXXL_THROW(std::runtime_error,
"Unsupported disk I/O implementation '" << cfg.io_impl << "'.");
}
STXXL_END_NAMESPACE