Stxxl
1.3.1
|
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 00054 00056 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 protected: 00070 template <class BIDType, class DiskAssignFunctor, class BIDIteratorClass> 00071 void new_blocks_int( 00072 const unsigned_type nblocks, 00073 const DiskAssignFunctor & functor, 00074 unsigned_type offset, 00075 BIDIteratorClass out); 00076 00077 public: 00079 00089 template <class DiskAssignFunctor, class BIDIteratorClass> 00090 void new_blocks( 00091 const DiskAssignFunctor & functor, 00092 BIDIteratorClass bidbegin, 00093 BIDIteratorClass bidend, 00094 unsigned_type offset = 0) 00095 { 00096 typedef typename std::iterator_traits<BIDIteratorClass>::value_type bid_type; 00097 new_blocks_int<bid_type>(std::distance(bidbegin, bidend), functor, offset, bidbegin); 00098 } 00099 00111 template <class BlockType, class DiskAssignFunctor, class BIDIteratorClass> 00112 void new_blocks( 00113 const unsigned_type nblocks, 00114 const DiskAssignFunctor & functor, 00115 BIDIteratorClass out, 00116 unsigned_type offset = 0) 00117 { 00118 typedef typename BlockType::bid_type bid_type; 00119 new_blocks_int<bid_type>(nblocks, functor, offset, out); 00120 } 00121 00130 template <typename DiskAssignFunctor, unsigned BLK_SIZE> 00131 void new_block(const DiskAssignFunctor & functor, BID<BLK_SIZE> & bid, unsigned_type offset = 0) 00132 { 00133 new_blocks_int<BID<BLK_SIZE> >(1, functor, offset, &bid); 00134 } 00135 00137 00141 template <class BIDIteratorClass> 00142 void delete_blocks(const BIDIteratorClass & bidbegin, const BIDIteratorClass & bidend); 00143 00146 template <unsigned BLK_SIZE> 00147 void delete_block(const BID<BLK_SIZE> & bid); 00148 00149 ~block_manager(); 00150 }; 00151 00152 00153 template <class BIDType, class DiskAssignFunctor, class OutputIterator> 00154 void block_manager::new_blocks_int( 00155 const unsigned_type nblocks, 00156 const DiskAssignFunctor & functor, 00157 unsigned_type offset, 00158 OutputIterator out) 00159 { 00160 typedef BIDType bid_type; 00161 typedef BIDArray<bid_type::t_size> bid_array_type; 00162 00163 int_type * bl = new int_type[ndisks]; 00164 bid_array_type * disk_bids = new bid_array_type[ndisks]; 00165 file ** disk_ptrs = new file *[nblocks]; 00166 00167 memset(bl, 0, ndisks * sizeof(int_type)); 00168 00169 unsigned_type i; 00170 for (i = 0; i < nblocks; ++i) 00171 { 00172 const int disk = functor(offset + i); 00173 disk_ptrs[i] = disk_files[disk]; 00174 bl[disk]++; 00175 } 00176 00177 for (i = 0; i < ndisks; ++i) 00178 { 00179 if (bl[i]) 00180 { 00181 disk_bids[i].resize(bl[i]); 00182 disk_allocators[i]->new_blocks(disk_bids[i]); 00183 } 00184 } 00185 00186 memset(bl, 0, ndisks * sizeof(int_type)); 00187 00188 OutputIterator it = out; 00189 for (i = 0; i != nblocks; ++it, ++i) 00190 { 00191 const int disk = disk_ptrs[i]->get_allocator_id(); 00192 bid_type bid(disk_ptrs[i], disk_bids[disk][bl[disk]++].offset); 00193 *it = bid; 00194 STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:new " << FMT_BID(bid)); 00195 } 00196 00197 delete[] bl; 00198 delete[] disk_bids; 00199 delete[] disk_ptrs; 00200 } 00201 00202 00203 template <unsigned BLK_SIZE> 00204 void block_manager::delete_block(const BID<BLK_SIZE> & bid) 00205 { 00206 // do not uncomment it 00207 //assert(bid.storage->get_allocator_id() < config::get_instance()->disks_number()); 00208 if (!bid.is_managed()) 00209 return; // self managed disk 00210 STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:delete " << FMT_BID(bid)); 00211 assert(bid.storage->get_allocator_id() >= 0); 00212 disk_allocators[bid.storage->get_allocator_id()]->delete_block(bid); 00213 disk_files[bid.storage->get_allocator_id()]->discard(bid.offset, bid.size); 00214 } 00215 00216 00217 template <class BIDIteratorClass> 00218 void block_manager::delete_blocks( 00219 const BIDIteratorClass & bidbegin, 00220 const BIDIteratorClass & bidend) 00221 { 00222 for (BIDIteratorClass it = bidbegin; it != bidend; it++) 00223 { 00224 delete_block(*it); 00225 } 00226 } 00227 00228 // in bytes 00229 #ifndef STXXL_DEFAULT_BLOCK_SIZE 00230 #define STXXL_DEFAULT_BLOCK_SIZE(type) (2 * 1024 * 1024) // use traits 00231 #endif 00232 00233 00234 class FileCreator 00235 { 00236 public: 00237 _STXXL_DEPRECATED( 00238 static file * create(const std::string & io_impl, 00239 const std::string & filename, 00240 int options, 00241 int queue_id = file::DEFAULT_QUEUE, 00242 int allocator_id = file::NO_ALLOCATOR) 00243 ) 00244 { 00245 return create_file(io_impl, filename, options, queue_id, allocator_id); 00246 } 00247 }; 00248 00250 00251 __STXXL_END_NAMESPACE 00252 00253 #endif // !STXXL_MNG_HEADER 00254 // vim: et:ts=4:sw=4