STXXL  1.4-dev
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
create_file.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * lib/io/create_file.cpp
3  *
4  * Part of the STXXL. See http://stxxl.sourceforge.net
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 
19 #include <stxxl/bits/io/io.h>
20 #include <stxxl/bits/mng/config.h>
21 
22 #include <ostream>
23 #include <stdexcept>
24 
26 
27 file * create_file(const std::string& io_impl,
28  const std::string& filename,
29  int options, int physical_device_id, int disk_allocator_id)
30 {
31  // construct temporary disk_config structure
32  disk_config cfg(filename, 0, io_impl);
33  cfg.queue = physical_device_id;
34  cfg.direct =
35  (options& file::REQUIRE_DIRECT) ? disk_config::DIRECT_ON :
36  (options& file::DIRECT) ? disk_config::DIRECT_TRY :
37  disk_config::DIRECT_OFF;
38 
39  return create_file(cfg, options, disk_allocator_id);
40 }
41 
42 file * create_file(disk_config& cfg, int mode, int disk_allocator_id)
43 {
44  // apply disk_config settings to open mode
45 
46  mode &= ~(file::DIRECT | file::REQUIRE_DIRECT); // clear DIRECT and REQUIRE_DIRECT
47 
48  switch (cfg.direct) {
49  case disk_config::DIRECT_OFF:
50  break;
51  case disk_config::DIRECT_TRY:
52  mode |= file::DIRECT;
53  break;
54  case disk_config::DIRECT_ON:
55  mode |= file::DIRECT | file::REQUIRE_DIRECT;
56  break;
57  }
58 
59  // automatically enumerate disks as separate device ids
60 
61  if (cfg.device_id == file::DEFAULT_DEVICE_ID)
62  {
63  cfg.device_id = config::get_instance()->get_next_device_id();
64  }
65  else
66  {
67  config::get_instance()->update_max_device_id(cfg.device_id);
68  }
69 
70  // *** Select fileio Implementation
71 
72  if (cfg.io_impl == "syscall")
73  {
74  ufs_file_base* result =
75  new syscall_file(cfg.path, mode, cfg.queue, disk_allocator_id,
76  cfg.device_id);
77  result->lock();
78 
79  // if marked as device but file is not -> throw!
80  if (cfg.raw_device && !result->is_device())
81  {
82  delete result;
83  STXXL_THROW(io_error, "Disk " << cfg.path << " was expected to be "
84  "a raw block device, but it is a normal file!");
85  }
86 
87  // if is raw_device -> get size and remove some flags.
88  if (result->is_device())
89  {
90  cfg.raw_device = true;
91  cfg.size = result->size();
92  cfg.autogrow = cfg.delete_on_exit = cfg.unlink_on_open = false;
93  }
94 
95  if (cfg.unlink_on_open)
96  result->unlink();
97 
98  return result;
99  }
100  else if (cfg.io_impl == "fileperblock_syscall")
101  {
103  new fileperblock_file<syscall_file>(cfg.path, mode, cfg.queue,
104  disk_allocator_id, cfg.device_id);
105  result->lock();
106  return result;
107  }
108  else if (cfg.io_impl == "memory")
109  {
110  mem_file* result = new mem_file(cfg.queue, disk_allocator_id, cfg.device_id);
111  result->lock();
112  return result;
113  }
114 #if STXXL_HAVE_LINUXAIO_FILE
115  // linuxaio can have the desired queue length, specified as queue_length=?
116  else if (cfg.io_impl == "linuxaio")
117  {
118  // linuxaio_queue is a singleton.
119  cfg.queue = file::DEFAULT_LINUXAIO_QUEUE;
120 
121  ufs_file_base* result =
122  new linuxaio_file(cfg.path, mode, cfg.queue, disk_allocator_id,
123  cfg.device_id, cfg.queue_length);
124 
125  result->lock();
126 
127  // if marked as device but file is not -> throw!
128  if (cfg.raw_device && !result->is_device())
129  {
130  delete result;
131  STXXL_THROW(io_error, "Disk " << cfg.path << " was expected to be "
132  "a raw block device, but it is a normal file!");
133  }
134 
135  // if is raw_device -> get size and remove some flags.
136  if (result->is_device())
137  {
138  cfg.raw_device = true;
139  cfg.size = result->size();
140  cfg.autogrow = cfg.delete_on_exit = cfg.unlink_on_open = false;
141  }
142 
143  if (cfg.unlink_on_open)
144  result->unlink();
145 
146  return result;
147  }
148 #endif
149 #if STXXL_HAVE_MMAP_FILE
150  else if (cfg.io_impl == "mmap")
151  {
152  ufs_file_base* result =
153  new mmap_file(cfg.path, mode, cfg.queue, disk_allocator_id,
154  cfg.device_id);
155  result->lock();
156 
157  if (cfg.unlink_on_open)
158  result->unlink();
159 
160  return result;
161  }
162  else if (cfg.io_impl == "fileperblock_mmap")
163  {
165  new fileperblock_file<mmap_file>(cfg.path, mode, cfg.queue,
166  disk_allocator_id, cfg.device_id);
167  result->lock();
168  return result;
169  }
170 #endif
171 #if STXXL_HAVE_SIMDISK_FILE
172  else if (cfg.io_impl == "simdisk")
173  {
174  mode &= ~(file::DIRECT | file::REQUIRE_DIRECT); // clear the DIRECT flag, this file is supposed to be on tmpfs
175  ufs_file_base* result =
176  new sim_disk_file(cfg.path, mode, cfg.queue, disk_allocator_id,
177  cfg.device_id);
178  result->lock();
179  return result;
180  }
181 #endif
182 #if STXXL_HAVE_WINCALL_FILE
183  else if (cfg.io_impl == "wincall")
184  {
185  wfs_file_base* result =
186  new wincall_file(cfg.path, mode, cfg.queue, disk_allocator_id,
187  cfg.device_id);
188  result->lock();
189  return result;
190  }
191  else if (cfg.io_impl == "fileperblock_wincall")
192  {
194  new fileperblock_file<wincall_file>(cfg.path, mode, cfg.queue,
195  disk_allocator_id, cfg.device_id);
196  result->lock();
197  return result;
198  }
199 #endif
200 #if STXXL_HAVE_BOOSTFD_FILE
201  else if (cfg.io_impl == "boostfd")
202  {
203  boostfd_file* result =
204  new boostfd_file(cfg.path, mode, cfg.queue, disk_allocator_id,
205  cfg.device_id);
206  result->lock();
207  return result;
208  }
209  else if (cfg.io_impl == "fileperblock_boostfd")
210  {
212  new fileperblock_file<boostfd_file>(cfg.path, mode, cfg.queue,
213  disk_allocator_id, cfg.device_id);
214  result->lock();
215  return result;
216  }
217 #endif
218 #if STXXL_HAVE_WBTL_FILE
219  else if (cfg.io_impl == "wbtl")
220  {
221  ufs_file_base* backend =
222  new syscall_file(cfg.path, mode, -1, -1); // FIXME: ID
223  wbtl_file* result =
224  new stxxl::wbtl_file(backend, 16 * 1024 * 1024, 2, cfg.queue,
225  disk_allocator_id);
226  result->lock();
227 
228  if (cfg.unlink_on_open)
229  backend->unlink();
230 
231  return result;
232  }
233 #endif
234 
235  STXXL_THROW(std::runtime_error,
236  "Unsupported disk I/O implementation '" << cfg.io_impl << "'.");
237 }
238 
240 // vim: et:ts=4:sw=4
void lock()
Locks file for reading and writing (acquires a lock in the file system).
file * create_file(const std::string &io_impl, const std::string &filename, int options, int physical_device_id=file::DEFAULT_QUEUE, int disk_allocator_id=file::NO_ALLOCATOR)
create fileio object from io_impl string and a few parameters
Definition: create_file.cpp:27
int queue
select request queue for disk. Use different queues for files on different disks. queue=-1 -&gt; default...
Definition: config.h:91
Implementation of file based on the Linux kernel interface for asynchronous I/O.
Definition: linuxaio_file.h:34
bool unlink_on_open
unlink file immediately after opening (available on most Unix)
Definition: config.h:101
#define STXXL_THROW(exception_type, error_message)
Throws exception_type with &quot;Error in [function] : [error_message]&quot;.
Implementation of disk emulation.
Definition: simdisk_file.h:114
void lock()
Locks file for reading and writing (acquires a lock in the file system).
void lock()
Locks file for reading and writing (acquires a lock in the file system).
Definition: mem_file.cpp:51
bool delete_on_exit
delete file on program exit (default for autoconfigurated files)
Definition: config.h:79
Defines interface of file.
Definition: file.h:56
Implementation of memory mapped access file.
Definition: mmap_file.h:31
std::string path
the file path used by the io implementation
Definition: config.h:41
Encapsulate the configuration of one &quot;disk&quot;. The disk is actually a file I/O object which block_manag...
Definition: config.h:34
void unlink()
unlink file without closing it.
bool autogrow
autogrow file if more disk space is needed, automatically set if size == 0.
Definition: config.h:76
#define STXXL_BEGIN_NAMESPACE
Definition: namespace.h:16
void lock()
Locks file for reading and writing (acquires a lock in the file system).
Implementation of file based on other files, dynamically allocate one file per block. Allows for dynamic disk space consumption.
unsigned int device_id
the selected physical device id (e.g. for calculating prefetching sequences). If -1 then the device i...
Definition: config.h:95
Implementation of file based on buffered writes and block remapping via a translation layer...
Definition: wbtl_file.h:36
int queue_length
desired queue length for linuxaio_file and linuxaio_queue
Definition: config.h:104
Implementation of file based on Windows native I/O calls.
Definition: wincall_file.h:39
Implementation of file based on new[] and memcpy.
Definition: mem_file.h:27
bool raw_device
turned on by syscall fileio when the path points to a raw block device
Definition: config.h:98
Base for Windows file system implementations.
Definition: wfs_file_base.h:33
Base for UNIX file system implementations.
Definition: ufs_file_base.h:33
enum stxxl::disk_config::direct_type direct
Implementation of file based on UNIX syscalls.
Definition: syscall_file.h:28
offset_type size()
Returns size of the file.
std::string io_impl
io implementation to access file
Definition: config.h:47
uint64 size
file size to initially allocate
Definition: config.h:44
virtual void lock()
Locks file for reading and writing (acquires a lock in the file system).
bool is_device() const
return true if file is special device node
#define STXXL_END_NAMESPACE
Definition: namespace.h:17