Thrill  0.1
create_file.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/io/create_file.cpp
3  *
4  * Part of FOXXLL. See http://foxxll.org
5  *
6  * Copyright (C) 2002 Roman Dementiev <[email protected]>
7  * Copyright (C) 2008, 2010 Andreas Beckmann <[email protected]>
8  * Copyright (C) 2008, 2009 Johannes Singler <[email protected]>
9  * Copyright (C) 2013 Timo Bingmann <[email protected]>
10  *
11  * Distributed under the Boost Software License, Version 1.0.
12  * (See accompanying file LICENSE_1_0.txt or copy at
13  * http://www.boost.org/LICENSE_1_0.txt)
14  **************************************************************************/
15 
17 
18 #include <ostream>
19 #include <stdexcept>
20 #include <string>
21 
24 #include <foxxll/io.hpp>
25 #include <foxxll/mng/config.hpp>
26 
27 namespace foxxll {
28 
30  const std::string& filename,
31  int options, int physical_device_id, int disk_allocator_id)
32 {
33  // construct temporary disk_config structure
34  disk_config cfg(filename, 0, io_impl);
35  cfg.queue = physical_device_id;
36  cfg.direct =
40 
41  return create_file(cfg, options, disk_allocator_id);
42 }
43 
44 file_ptr create_file(disk_config& cfg, int mode, int disk_allocator_id)
45 {
46  // apply disk_config settings to open mode
47 
48  mode &= ~(file::DIRECT | file::REQUIRE_DIRECT); // clear DIRECT and REQUIRE_DIRECT
49 
50  switch (cfg.direct) {
52  break;
54  mode |= file::DIRECT;
55  break;
58  break;
59  }
60 
61  // automatically enumerate disks as separate device ids
62 
64  {
66  }
67  else
68  {
70  }
71 
72  // *** Select fileio Implementation
73 
74  if (cfg.io_impl == "syscall")
75  {
77  tlx::make_counting<syscall_file>(
78  cfg.path, mode, cfg.queue, disk_allocator_id, cfg.device_id
79  );
80  result->lock();
81 
82  // if marked as device but file is not -> throw!
83  if (cfg.raw_device && !result->is_device())
84  {
86  io_error, "Disk " << cfg.path << " was expected to be "
87  "a raw block device, but it is a normal file!"
88  );
89  }
90 
91  // if is raw_device -> get size and remove some flags.
92  if (result->is_device())
93  {
94  cfg.raw_device = true;
95  cfg.size = result->size();
96  cfg.autogrow = cfg.delete_on_exit = cfg.unlink_on_open = false;
97  }
98 
99  if (cfg.unlink_on_open)
100  result->unlink();
101 
102  return result;
103  }
104  else if (cfg.io_impl == "fileperblock_syscall")
105  {
107  tlx::make_counting<fileperblock_file<syscall_file> >(
108  cfg.path, mode, cfg.queue, disk_allocator_id, cfg.device_id
109  );
110  result->lock();
111  return result;
112  }
113  else if (cfg.io_impl == "memory")
114  {
116  tlx::make_counting<memory_file>(
117  cfg.queue, disk_allocator_id, cfg.device_id
118  );
119  result->lock();
120  return result;
121  }
122 #if FOXXLL_HAVE_LINUXAIO_FILE
123  // linuxaio can have the desired queue length, specified as queue_length=?
124  else if (cfg.io_impl == "linuxaio")
125  {
126  // linuxaio_queue is a singleton.
128 
130  tlx::make_counting<linuxaio_file>(
131  cfg.path, mode, cfg.queue, disk_allocator_id,
132  cfg.device_id, cfg.queue_length
133  );
134 
135  result->lock();
136 
137  // if marked as device but file is not -> throw!
138  if (cfg.raw_device && !result->is_device())
139  {
140  FOXXLL_THROW(
141  io_error, "Disk " << cfg.path << " was expected to be "
142  "a raw block device, but it is a normal file!"
143  );
144  }
145 
146  // if is raw_device -> get size and remove some flags.
147  if (result->is_device())
148  {
149  cfg.raw_device = true;
150  cfg.size = result->size();
151  cfg.autogrow = cfg.delete_on_exit = cfg.unlink_on_open = false;
152  }
153 
154  if (cfg.unlink_on_open)
155  result->unlink();
156 
157  return result;
158  }
159 #endif
160 #if FOXXLL_HAVE_MMAP_FILE
161  else if (cfg.io_impl == "mmap")
162  {
164  tlx::make_counting<mmap_file>(
165  cfg.path, mode, cfg.queue, disk_allocator_id, cfg.device_id
166  );
167  result->lock();
168 
169  if (cfg.unlink_on_open)
170  result->unlink();
171 
172  return result;
173  }
174  else if (cfg.io_impl == "fileperblock_mmap")
175  {
177  tlx::make_counting<fileperblock_file<mmap_file> >(
178  cfg.path, mode, cfg.queue, disk_allocator_id, cfg.device_id
179  );
180  result->lock();
181  return result;
182  }
183 #endif
184 #if FOXXLL_HAVE_WINCALL_FILE
185  else if (cfg.io_impl == "wincall")
186  {
188  tlx::make_counting<wincall_file>(
189  cfg.path, mode, cfg.queue, disk_allocator_id, cfg.device_id
190  );
191  result->lock();
192  return result;
193  }
194  else if (cfg.io_impl == "fileperblock_wincall")
195  {
197  tlx::make_counting<fileperblock_file<wincall_file> >(
198  cfg.path, mode, cfg.queue, disk_allocator_id, cfg.device_id
199  );
200  result->lock();
201  return result;
202  }
203 #endif
204 
205  FOXXLL_THROW(
206  std::runtime_error,
207  "Unsupported disk I/O implementation '" << cfg.io_impl << "'."
208  );
209 }
210 
211 } // namespace foxxll
212 
213 /**************************************************************************/
external_size_type size
file size to initially allocate
Definition: config.hpp:46
void update_max_device_id(unsigned int devid)
Update the automatic physical device id counter.
Definition: config.cpp:199
unsigned int next_device_id()
Returns next automatic physical device id counter.
Definition: config.cpp:194
std::string path
the file path used by the io implementation
Definition: config.hpp:43
static const unsigned int DEFAULT_DEVICE_ID
Definition: file.hpp:92
#define FOXXLL_THROW(exception_type, error_message)
Throws exception_type with "Error in [function] : [error_message]".
bool unlink_on_open
unlink file immediately after opening (available on most Unix)
Definition: config.hpp:103
std::string io_impl
io implementation to access file
Definition: config.hpp:49
implies DIRECT, fail if opening with DIRECT flag does not work.
Definition: file.hpp:86
file_ptr create_file(const std::string &io_impl, const std::string &filename, int options, int physical_device_id, int disk_allocator_id)
create fileio object from io_impl string and a few parameters
Definition: create_file.cpp:29
FOXXLL library namespace
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220
static instance_pointer get_instance()
return instance or create base instance if empty
Definition: singleton.hpp:41
offset_type size() final
High-performance smart pointer used as a wrapping reference counting pointer.
bool is_device() const
return true if file is special device node
bool raw_device
turned on by syscall fileio when the path points to a raw block device
Definition: config.hpp:100
int queue_length
desired queue length for linuxaio_file and linuxaio_queue
Definition: config.hpp:106
static const int DEFAULT_LINUXAIO_QUEUE
Definition: file.hpp:90
void lock() final
Locks file for reading and writing (acquires a lock in the file system).
Definition: memory_file.cpp:54
void lock() final
Locks file for reading and writing (acquires a lock in the file system).
bool delete_on_exit
delete file on program exit (default for autoconfigurated files)
Definition: config.hpp:81
bool autogrow
autogrow file if more disk space is needed, automatically set if size == 0.
Definition: config.hpp:78
unsigned int device_id
Definition: config.hpp:97
enum foxxll::disk_config::direct_type direct
void unlink()
unlink file without closing it.