Thrill  0.1
fileperblock_file.cpp
Go to the documentation of this file.
1 /***************************************************************************
2  * foxxll/io/fileperblock_file.cpp
3  *
4  * Part of FOXXLL. See http://foxxll.org
5  *
6  * Copyright (C) 2008, 2009 Johannes Singler <[email protected]>
7  * Copyright (C) 2008 Andreas Beckmann <[email protected]>
8  *
9  * Distributed under the Boost Software License, Version 1.0.
10  * (See accompanying file LICENSE_1_0.txt or copy at
11  * http://www.boost.org/LICENSE_1_0.txt)
12  **************************************************************************/
13 
14 #include <cassert>
15 #include <cstdio>
16 #include <iomanip>
17 #include <sstream>
18 #include <string>
19 
20 #include <tlx/counting_ptr.hpp>
21 #include <tlx/logger/core.hpp>
22 #include <tlx/unused.hpp>
23 
27 #include <foxxll/config.hpp>
29 #include <foxxll/io/file.hpp>
31 #include <foxxll/io/mmap_file.hpp>
32 #include <foxxll/io/request.hpp>
37 
38 namespace foxxll {
39 
40 template <class base_file_type>
42  const std::string& filename_prefix,
43  int mode,
44  int queue_id,
45  int allocator_id,
46  unsigned int device_id)
47  : file(device_id),
48  disk_queued_file(queue_id, allocator_id),
49  filename_prefix_(filename_prefix),
50  mode_(mode),
51  current_size_(0)
52 { }
53 
54 template <class base_file_type>
56 {
57  if (lock_file_)
58  lock_file_->close_remove();
59 }
60 
61 template <class base_file_type>
63 {
64  std::ostringstream name;
65  //enough for 1 billion blocks
66  name << filename_prefix_ << "_fpb_" << std::setw(20) << std::setfill('0') << offset;
67  return name.str();
68 }
69 
70 template <class base_file_type>
72  void* buffer, offset_type offset,
74 {
75  base_file_type base_file(filename_for_block(offset), mode_, get_queue_id(),
77  base_file.set_size(bytes);
78  base_file.serve(buffer, 0, bytes, op);
79 }
80 
81 template <class base_file_type>
83 {
84  if (!lock_file_)
85  {
86  lock_file_ = tlx::make_counting<base_file_type>(
87  filename_prefix_ + "_fpb_lock", mode_, get_queue_id()
88  );
89 
90  //create lock file and fill it with one page, an empty file cannot be locked
91  const int page_size = BlockAlignment;
92  void* one_page = aligned_alloc<BlockAlignment>(page_size);
93 #if FOXXLL_WITH_VALGRIND
94  memset(one_page, 0, page_size);
95 #endif
96  lock_file_->set_size(page_size);
97  request_ptr r = lock_file_->awrite(one_page, 0, page_size);
98  r->wait();
99  aligned_dealloc<BlockAlignment>(one_page);
100  }
101  lock_file_->lock();
102 }
103 
104 template <class base_file_type>
106 {
107  tlx::unused(length);
108 #ifdef FOXXLL_FILEPERBLOCK_NO_DELETE
109  if (::truncate(filename_for_block(offset).c_str(), 0) != 0)
110  TLX_LOG1 << "truncate() error on path=" << filename_for_block(offset)
111  << " error=" << strerror(errno);
112 #else
113  if (::remove(filename_for_block(offset).c_str()) != 0)
114  TLX_LOG1 << "remove() error on path=" << filename_for_block(offset)
115  << " error=" << strerror(errno);
116 #endif
117 
118  TLX_LOG << "discard " << offset << " + " << length;
119 }
120 
121 template <class base_file_type>
123 {
124  std::string original(filename_for_block(offset));
125  filename.insert(0, original.substr(0, original.find_last_of("/") + 1));
126  if (::remove(filename.c_str()) != 0)
127  TLX_LOG1 << "remove() error on path=" << filename
128  << " error=" << strerror(errno);
129 
130  if (::rename(original.c_str(), filename.c_str()) != 0)
131  TLX_LOG1 << "rename() error on path=" << filename
132  << " to=" << original << " error=" << strerror(errno);
133 
134 #if !FOXXLL_WINDOWS
135  //TODO: implement on Windows
136  if (::truncate(filename.c_str(), as_signed(length)) != 0) {
137  FOXXLL_THROW_ERRNO(io_error, "Error doing truncate()");
138  }
139 #else
140  tlx::unused(length);
141 #endif
142 }
143 
144 template <class base_file_type>
146 {
147  return "fileperblock";
148 }
149 
150 ////////////////////////////////////////////////////////////////////////////
151 
152 template class fileperblock_file<syscall_file>;
153 
154 #if FOXXLL_HAVE_MMAP_FILE
155 template class fileperblock_file<mmap_file>;
156 #endif
157 
158 #if FOXXLL_HAVE_WINCALL_FILE
159 template class fileperblock_file<wincall_file>;
160 #endif
161 
162 } // namespace foxxll
163 
164 /******************************************************************************/
165 
166 /**************************************************************************/
static const unsigned int DEFAULT_DEVICE_ID
Definition: file.hpp:92
request::offset_type offset_type
the offset of a request, also the size of the file
Definition: file.hpp:58
Implementation of some file methods based on serving_request.
const char * io_type() const final
file_stats * file_stats_
Definition: file.hpp:200
constexpr size_t BlockAlignment
Definition: request.hpp:34
void unused(Types &&...)
Definition: unused.hpp:20
request::size_type size_type
the size of a request
Definition: file.hpp:60
virtual void discard(offset_type offset, offset_type length)
#define FOXXLL_THROW_ERRNO(exception_type, error_message)
Throws exception_type with "Error in [function] : [error_message] : [errno message]".
tlx::counting_ptr< base_file_type > lock_file_
fileperblock_file(const std::string &filename_prefix, int mode, int queue_id=DEFAULT_QUEUE, int allocator_id=NO_ALLOCATOR, unsigned int device_id=DEFAULT_DEVICE_ID)
static int truncate(const char *path, external_size_type length)
std::string filename_for_block(offset_type offset)
Constructs a file name for a given block.
FOXXLL library namespace
std::basic_string< char, std::char_traits< char >, Allocator< char > > string
string with Manager tracking
Definition: allocator.hpp:220
virtual void lock()
Locks file for reading and writing (acquires a lock in the file system).
High-performance smart pointer used as a wrapping reference counting pointer.
static const size_t bytes
number of bytes in uint_pair
Definition: uint_types.hpp:75
std::make_signed< Integral >::type as_signed(Integral value)
Return the given value casted to the corresponding signed type.
Definition: types.hpp:39
static const int NO_ALLOCATOR
Definition: file.hpp:91
#define TLX_LOG1
Definition: core.hpp:145
void serve(void *buffer, offset_type offset, size_type bytes, request::read_or_write op) final
virtual void export_files(offset_type offset, offset_type length, std::string filename)
Rename the file corresponding to the offset such that it is out of reach for deleting.
#define TLX_LOG
Default logging method: output if the local debug variable is true.
Definition: core.hpp:141
int get_queue_id() const override