Stxxl  1.4.0
io/fileperblock_file.cpp
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines