Thrill  0.1
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
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.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(),
76  NO_ALLOCATOR, DEFAULT_DEVICE_ID, file_stats_);
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>
105 void fileperblock_file<base_file_type>::discard(offset_type offset, offset_type length)
106 {
107  tlx::unused(length);
108 #ifdef FOXXLL_FILEPERBLOCK_NO_DELETE
109  if (::truncate(filename_for_block(offset).c_str(), 0) != 0)
110  LOG1 << "truncate() error on path=" << filename_for_block(offset) << " error=" << strerror(errno);
111 #else
112  if (::remove(filename_for_block(offset).c_str()) != 0)
113  LOG1 << "remove() error on path=" << filename_for_block(offset) << " error=" << strerror(errno);
114 #endif
115 
116  LOG << "discard " << offset << " + " << length;
117 }
118 
119 template <class base_file_type>
120 void fileperblock_file<base_file_type>::export_files(offset_type offset, offset_type length, std::string filename)
121 {
122  std::string original(filename_for_block(offset));
123  filename.insert(0, original.substr(0, original.find_last_of("/") + 1));
124  if (::remove(filename.c_str()) != 0)
125  LOG1 << "remove() error on path=" << filename << " error=" << strerror(errno);
126 
127  if (::rename(original.c_str(), filename.c_str()) != 0)
128  LOG1 << "rename() error on path=" << filename << " to=" << original << " error=" << strerror(errno);
129 
130 #if !FOXXLL_WINDOWS
131  //TODO: implement on Windows
132  if (::truncate(filename.c_str(), as_signed(length)) != 0) {
133  FOXXLL_THROW_ERRNO(io_error, "Error doing truncate()");
134  }
135 #else
136  tlx::unused(length);
137 #endif
138 }
139 
140 template <class base_file_type>
142 {
143  return "fileperblock";
144 }
145 
146 ////////////////////////////////////////////////////////////////////////////
147 
148 template class fileperblock_file<syscall_file>;
149 
150 #if FOXXLL_HAVE_MMAP_FILE
151 template class fileperblock_file<mmap_file>;
152 #endif
153 
154 #if FOXXLL_HAVE_WINCALL_FILE
155 template class fileperblock_file<wincall_file>;
156 #endif
157 
158 } // namespace foxxll
159 
160 /******************************************************************************/
161 
162 /**************************************************************************/
#define LOG1
Definition: logger.hpp:145
Implementation of some file methods based on serving_request.
const char * io_type() const final
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]".
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)
std::string filename_for_block(offset_type offset)
Constructs a file name for a given block.
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
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 LOG
Default logging method: output if the local debug variable is true.
Definition: logger.hpp:141