Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * io/fileperblock_file.cpp 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2008, 2009 Johannes Singler <singler@ira.uka.de> 00007 * Copyright (C) 2008 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00008 * 00009 * Distributed under the Boost Software License, Version 1.0. 00010 * (See accompanying file LICENSE_1_0.txt or copy at 00011 * http://www.boost.org/LICENSE_1_0.txt) 00012 **************************************************************************/ 00013 00014 #include <sstream> 00015 #include <iomanip> 00016 #include <cstdio> 00017 #include <stxxl/bits/io/fileperblock_file.h> 00018 #include <stxxl/bits/io/syscall_file.h> 00019 #include <stxxl/bits/io/mmap_file.h> 00020 #include <stxxl/bits/io/boostfd_file.h> 00021 #include <stxxl/bits/io/wincall_file.h> 00022 #include <stxxl/bits/io/serving_request.h> 00023 #include <stxxl/bits/common/aligned_alloc.h> 00024 00025 __STXXL_BEGIN_NAMESPACE 00026 00027 template <class base_file_type> 00028 fileperblock_file<base_file_type>::fileperblock_file( 00029 const std::string & filename_prefix, 00030 int mode, 00031 int queue_id, 00032 int allocator_id) 00033 : disk_queued_file(queue_id, allocator_id), filename_prefix(filename_prefix), mode(mode), 00034 lock_file_created(false), lock_file(filename_prefix + "_fpb_lock", mode, queue_id) 00035 { } 00036 00037 template <class base_file_type> 00038 fileperblock_file<base_file_type>::~fileperblock_file() 00039 { 00040 if (lock_file_created) 00041 ::remove((filename_prefix + "_fpb_lock").c_str()); 00042 } 00043 00044 template <class base_file_type> 00045 std::string fileperblock_file<base_file_type>::filename_for_block(unsigned_type offset) 00046 { 00047 std::ostringstream name; 00048 //enough for 1 billion blocks 00049 name << filename_prefix << "_fpb_" << std::setw(20) << std::setfill('0') << offset; 00050 return name.str(); 00051 } 00052 00053 template <class base_file_type> 00054 void fileperblock_file<base_file_type>::serve(const request * req) throw (io_error) 00055 { 00056 assert(req->get_file() == this); 00057 00058 base_file_type base_file(filename_for_block(req->get_offset()), mode, get_queue_id()); 00059 base_file.set_size(req->get_size()); 00060 00061 request_ptr derived(new serving_request(default_completion_handler(), &base_file, req->get_buffer(), 0, req->get_size(), req->get_type())); 00062 request_ptr dummy = derived; 00063 derived->serve(); 00064 } 00065 00066 template <class base_file_type> 00067 void fileperblock_file<base_file_type>::lock() 00068 { 00069 if (!lock_file_created) 00070 { 00071 //create lock file and fill it with one page, an empty file cannot be locked 00072 const int page_size = BLOCK_ALIGN; 00073 void * one_page = aligned_alloc<BLOCK_ALIGN>(page_size); 00074 lock_file.set_size(page_size); 00075 request_ptr r = lock_file.awrite(one_page, 0, page_size, default_completion_handler()); 00076 r->wait(); 00077 aligned_dealloc<BLOCK_ALIGN>(one_page); 00078 lock_file_created = true; 00079 } 00080 lock_file.lock(); 00081 } 00082 00083 template <class base_file_type> 00084 void fileperblock_file<base_file_type>::discard(offset_type offset, offset_type length) 00085 { 00086 STXXL_UNUSED(length); 00087 #ifdef STXXL_FILEPERBLOCK_NO_DELETE 00088 ::truncate(filename_for_block(offset).c_str(), 0); 00089 #else 00090 ::remove(filename_for_block(offset).c_str()); 00091 #endif 00092 00093 STXXL_VERBOSE2("discard " << offset << " + " << length); 00094 } 00095 00096 template <class base_file_type> 00097 void fileperblock_file<base_file_type>::export_files(offset_type offset, offset_type length, std::string filename) 00098 { 00099 std::string original(filename_for_block(offset)); 00100 filename.insert(0, original.substr(0, original.find_last_of("/") + 1)); 00101 ::remove(filename.c_str()); 00102 ::rename(original.c_str(), filename.c_str()); 00103 #ifndef BOOST_MSVC 00104 //TODO: implement on Windows 00105 ::truncate(filename.c_str(), length); 00106 #endif 00107 } 00108 00109 template <class base_file_type> 00110 const char * fileperblock_file<base_file_type>::io_type() const 00111 { 00112 return "fileperblock"; 00113 } 00114 00115 //////////////////////////////////////////////////////////////////////////// 00116 00117 template class fileperblock_file<syscall_file>; 00118 00119 #if STXXL_HAVE_MMAP_FILE 00120 template class fileperblock_file<mmap_file>; 00121 #endif 00122 00123 #if STXXL_HAVE_WINCALL_FILE 00124 template class fileperblock_file<wincall_file>; 00125 #endif 00126 00127 #if STXXL_HAVE_BOOSTFD_FILE 00128 template class fileperblock_file<boostfd_file>; 00129 #endif 00130 00131 __STXXL_END_NAMESPACE