00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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
00207
00208 if (!bid.is_managed())
00209 return;
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
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