Stxxl
1.4.0
|
00001 /*************************************************************************** 00002 * include/stxxl/bits/mng/mng.h 00003 * 00004 * Part of the STXXL. See http://stxxl.sourceforge.net 00005 * 00006 * Copyright (C) 2002-2007 Roman Dementiev <dementiev@mpi-sb.mpg.de> 00007 * Copyright (C) 2007, 2009 Johannes Singler <singler@ira.uka.de> 00008 * Copyright (C) 2008-2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de> 00009 * 00010 * Distributed under the Boost Software License, Version 1.0. 00011 * (See accompanying file LICENSE_1_0.txt or copy at 00012 * http://www.boost.org/LICENSE_1_0.txt) 00013 **************************************************************************/ 00014 00015 #ifndef STXXL_MNG_HEADER 00016 #define STXXL_MNG_HEADER 00017 00018 #include <memory> 00019 #include <iostream> 00020 #include <iomanip> 00021 #include <fstream> 00022 #include <vector> 00023 #include <map> 00024 #include <algorithm> 00025 #include <string> 00026 #include <cstdlib> 00027 00028 #ifdef STXXL_BOOST_CONFIG 00029 #include <boost/config.hpp> 00030 #endif 00031 00032 #ifdef BOOST_MSVC 00033 #include <memory.h> 00034 #endif 00035 00036 #include <stxxl/bits/deprecated.h> 00037 #include <stxxl/bits/io/request.h> 00038 #include <stxxl/bits/io/file.h> 00039 #include <stxxl/bits/io/create_file.h> 00040 #include <stxxl/bits/noncopyable.h> 00041 #include <stxxl/bits/singleton.h> 00042 #include <stxxl/bits/mng/bid.h> 00043 #include <stxxl/bits/mng/diskallocator.h> 00044 #include <stxxl/bits/mng/block_alloc.h> 00045 #include <stxxl/bits/mng/config.h> 00046 00047 00048 __STXXL_BEGIN_NAMESPACE 00049 00050 //! \defgroup mnglayer Block management layer 00051 //! Group of classes which help controlling external memory space, 00052 //! managing disks, and allocating and deallocating blocks of external storage 00053 //! \{ 00054 00055 //! \brief Block manager class 00056 00057 //! Manages allocation and deallocation of blocks in multiple/single disk setting 00058 //! \remarks is a singleton 00059 class block_manager : public singleton<block_manager> 00060 { 00061 friend class singleton<block_manager>; 00062 00063 DiskAllocator ** disk_allocators; 00064 file ** disk_files; 00065 00066 unsigned ndisks; 00067 block_manager(); 00068 00069 unsigned long long m_totalalloc, m_maxalloc; 00070 00071 protected: 00072 template <class BIDType, class DiskAssignFunctor, class BIDIteratorClass> 00073 void new_blocks_int( 00074 const unsigned_type nblocks, 00075 const DiskAssignFunctor & functor, 00076 unsigned_type offset, 00077 BIDIteratorClass out); 00078 00079 public: 00080 //! \brief Allocates new blocks 00081 00082 //! Allocates new blocks according to the strategy 00083 //! given by \b functor and stores block identifiers 00084 //! to the range [ \b bidbegin, \b bidend) 00085 //! Allocation will be lined up with previous partial allocations 00086 //! of \b offset blocks. 00087 //! \param functor object of model of \b allocation_strategy concept 00088 //! \param bidbegin bidirectional BID iterator object 00089 //! \param bidend bidirectional BID iterator object 00090 //! \param offset advance for \b functor to line up partial allocations 00091 template <class DiskAssignFunctor, class BIDIteratorClass> 00092 void new_blocks( 00093 const DiskAssignFunctor & functor, 00094 BIDIteratorClass bidbegin, 00095 BIDIteratorClass bidend, 00096 unsigned_type offset = 0) 00097 { 00098 typedef typename std::iterator_traits<BIDIteratorClass>::value_type bid_type; 00099 new_blocks_int<bid_type>(std::distance(bidbegin, bidend), functor, offset, bidbegin); 00100 } 00101 00102 //! Allocates new blocks according to the strategy 00103 //! given by \b functor and stores block identifiers 00104 //! to the output iterator \b out 00105 //! Allocation will be lined up with previous partial allocations 00106 //! of \b offset blocks. 00107 //! \param nblocks the number of blocks to allocate 00108 //! \param functor object of model of \b allocation_strategy concept 00109 //! \param out iterator object of OutputIterator concept 00110 //! \param offset advance for \b functor to line up partial allocations 00111 //! 00112 //! The \c BlockType template parameter defines the type of block to allocate 00113 template <class BlockType, class DiskAssignFunctor, class BIDIteratorClass> 00114 void new_blocks( 00115 const unsigned_type nblocks, 00116 const DiskAssignFunctor & functor, 00117 BIDIteratorClass out, 00118 unsigned_type offset = 0) 00119 { 00120 typedef typename BlockType::bid_type bid_type; 00121 new_blocks_int<bid_type>(nblocks, functor, offset, out); 00122 } 00123 00124 //! Allocates a new block according to the strategy 00125 //! given by \b functor and stores the block identifier 00126 //! to bid. 00127 //! Allocation will be lined up with previous partial allocations 00128 //! of \b offset blocks. 00129 //! \param functor object of model of \b allocation_strategy concept 00130 //! \param bid BID to store the block identifier 00131 //! \param offset advance for \b functor to line up partial allocations 00132 template <typename DiskAssignFunctor, unsigned BLK_SIZE> 00133 void new_block(const DiskAssignFunctor & functor, BID<BLK_SIZE> & bid, unsigned_type offset = 0) 00134 { 00135 new_blocks_int<BID<BLK_SIZE> >(1, functor, offset, &bid); 00136 } 00137 00138 //! \brief Deallocates blocks 00139 00140 //! Deallocates blocks in the range [ \b bidbegin, \b bidend) 00141 //! \param bidbegin iterator object of \b bid_iterator concept 00142 //! \param bidend iterator object of \b bid_iterator concept 00143 template <class BIDIteratorClass> 00144 void delete_blocks(const BIDIteratorClass & bidbegin, const BIDIteratorClass & bidend); 00145 00146 //! \brief Deallocates a block 00147 //! \param bid block identifier 00148 template <unsigned BLK_SIZE> 00149 void delete_block(const BID<BLK_SIZE> & bid); 00150 00151 ~block_manager(); 00152 00153 unsigned long long current_allocated() const 00154 { 00155 return m_totalalloc; 00156 } 00157 00158 unsigned long long max_allocated() const 00159 { 00160 return m_maxalloc; 00161 } 00162 }; 00163 00164 00165 template <class BIDType, class DiskAssignFunctor, class OutputIterator> 00166 void block_manager::new_blocks_int( 00167 const unsigned_type nblocks, 00168 const DiskAssignFunctor & functor, 00169 unsigned_type offset, 00170 OutputIterator out) 00171 { 00172 typedef BIDType bid_type; 00173 typedef BIDArray<bid_type::t_size> bid_array_type; 00174 00175 int_type * bl = new int_type[ndisks]; 00176 bid_array_type * disk_bids = new bid_array_type[ndisks]; 00177 file ** disk_ptrs = new file *[nblocks]; 00178 00179 memset(bl, 0, ndisks * sizeof(int_type)); 00180 00181 unsigned_type i; 00182 for (i = 0; i < nblocks; ++i) 00183 { 00184 const int disk = functor(offset + i); 00185 disk_ptrs[i] = disk_files[disk]; 00186 bl[disk]++; 00187 } 00188 00189 for (i = 0; i < ndisks; ++i) 00190 { 00191 if (bl[i]) 00192 { 00193 disk_bids[i].resize(bl[i]); 00194 disk_allocators[i]->new_blocks(disk_bids[i]); 00195 } 00196 } 00197 00198 m_totalalloc += nblocks * BIDType::size; 00199 m_maxalloc = std::max(m_maxalloc, m_totalalloc); 00200 00201 memset(bl, 0, ndisks * sizeof(int_type)); 00202 00203 OutputIterator it = out; 00204 for (i = 0; i != nblocks; ++it, ++i) 00205 { 00206 const int disk = disk_ptrs[i]->get_allocator_id(); 00207 bid_type bid(disk_ptrs[i], disk_bids[disk][bl[disk]++].offset); 00208 *it = bid; 00209 STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:new " << FMT_BID(bid)); 00210 } 00211 00212 delete[] bl; 00213 delete[] disk_bids; 00214 delete[] disk_ptrs; 00215 } 00216 00217 00218 template <unsigned BLK_SIZE> 00219 void block_manager::delete_block(const BID<BLK_SIZE> & bid) 00220 { 00221 m_totalalloc -= BLK_SIZE; 00222 00223 // do not uncomment it 00224 //assert(bid.storage->get_allocator_id() < config::get_instance()->disks_number()); 00225 if (!bid.is_managed()) 00226 return; // self managed disk 00227 STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:delete " << FMT_BID(bid)); 00228 assert(bid.storage->get_allocator_id() >= 0); 00229 disk_allocators[bid.storage->get_allocator_id()]->delete_block(bid); 00230 disk_files[bid.storage->get_allocator_id()]->discard(bid.offset, bid.size); 00231 } 00232 00233 00234 template <class BIDIteratorClass> 00235 void block_manager::delete_blocks( 00236 const BIDIteratorClass & bidbegin, 00237 const BIDIteratorClass & bidend) 00238 { 00239 for (BIDIteratorClass it = bidbegin; it != bidend; it++) 00240 { 00241 delete_block(*it); 00242 } 00243 } 00244 00245 // in bytes 00246 #ifndef STXXL_DEFAULT_BLOCK_SIZE 00247 #define STXXL_DEFAULT_BLOCK_SIZE(type) (2 * 1024 * 1024) // use traits 00248 #endif 00249 00250 00251 class FileCreator 00252 { 00253 public: 00254 _STXXL_DEPRECATED( 00255 static file * create(const std::string & io_impl, 00256 const std::string & filename, 00257 int options, 00258 int queue_id = file::DEFAULT_QUEUE, 00259 int allocator_id = file::NO_ALLOCATOR) 00260 ) 00261 { 00262 return create_file(io_impl, filename, options, queue_id, allocator_id); 00263 } 00264 }; 00265 00266 //! \} 00267 00268 __STXXL_END_NAMESPACE 00269 00270 #endif // !STXXL_MNG_HEADER 00271 // vim: et:ts=4:sw=4