• Main Page
  • Related Pages
  • Modules
  • Namespaces
  • Classes
  • Files
  • Examples
  • File List

mng.h

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 <[email protected]>
00007  *  Copyright (C) 2007 Johannes Singler <[email protected]>
00008  *  Copyright (C) 2008-2009 Andreas Beckmann <[email protected]>
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/io/request.h>
00037 #include <stxxl/bits/io/file.h>
00038 #include <stxxl/bits/noncopyable.h>
00039 #include <stxxl/bits/singleton.h>
00040 #include <stxxl/bits/mng/bid.h>
00041 #include <stxxl/bits/mng/diskallocator.h>
00042 #include <stxxl/bits/mng/block_alloc.h>
00043 #include <stxxl/bits/mng/config.h>
00044 
00045 
00046 __STXXL_BEGIN_NAMESPACE
00047 
00052 
00054 
00057 class block_manager : public singleton<block_manager>
00058 {
00059     friend class singleton<block_manager>;
00060 
00061     DiskAllocator ** disk_allocators;
00062     file ** disk_files;
00063 
00064     unsigned ndisks;
00065     block_manager();
00066 
00067 protected:
00068     template <class BIDType, class DiskAssignFunctor, class BIDIteratorClass>
00069     void new_blocks_int(
00070         const unsigned_type nblocks,
00071         const DiskAssignFunctor & functor,
00072         unsigned_type offset,
00073         BIDIteratorClass out);
00074 
00075 public:
00077 
00087     template <class DiskAssignFunctor, class BIDIteratorClass>
00088     void new_blocks(
00089         const DiskAssignFunctor & functor,
00090         BIDIteratorClass bidbegin,
00091         BIDIteratorClass bidend,
00092         unsigned_type offset = 0)
00093     {
00094         typedef typename std::iterator_traits<BIDIteratorClass>::value_type bid_type;
00095         new_blocks_int<bid_type>(std::distance(bidbegin, bidend), functor, offset, bidbegin);
00096     }
00097 
00109     template <class BlockType, class DiskAssignFunctor, class BIDIteratorClass>
00110     void new_blocks(
00111         const unsigned_type nblocks,
00112         const DiskAssignFunctor & functor,
00113         BIDIteratorClass out,
00114         unsigned_type offset = 0)
00115     {
00116         typedef typename BlockType::bid_type bid_type;
00117         new_blocks_int<bid_type>(nblocks, functor, offset, out);
00118     }
00119 
00128     template <typename DiskAssignFunctor, unsigned BLK_SIZE>
00129     void new_block(const DiskAssignFunctor & functor, BID<BLK_SIZE> & bid, unsigned_type offset = 0)
00130     {
00131         new_blocks_int<BID<BLK_SIZE> >(1, functor, offset, &bid);
00132     }
00133 
00135 
00139     template <class BIDIteratorClass>
00140     void delete_blocks(const BIDIteratorClass & bidbegin, const BIDIteratorClass & bidend);
00141 
00144     template <unsigned BLK_SIZE>
00145     void delete_block(const BID<BLK_SIZE> & bid);
00146 
00147     ~block_manager();
00148 };
00149 
00150 
00151 template <class BIDType, class DiskAssignFunctor, class OutputIterator>
00152 void block_manager::new_blocks_int(
00153     const unsigned_type nblocks,
00154     const DiskAssignFunctor & functor,
00155     unsigned_type offset,
00156     OutputIterator out)
00157 {
00158     typedef BIDType bid_type;
00159     typedef BIDArray<bid_type::t_size> bid_array_type;
00160 
00161     int_type * bl = new int_type[ndisks];
00162     bid_array_type * disk_bids = new bid_array_type[ndisks];
00163     file ** disk_ptrs = new file *[nblocks];
00164 
00165     memset(bl, 0, ndisks * sizeof(int_type));
00166 
00167     unsigned_type i;
00168     for (i = 0; i < nblocks; ++i)
00169     {
00170         const int disk = functor(offset + i);
00171         disk_ptrs[i] = disk_files[disk];
00172         bl[disk]++;
00173     }
00174 
00175     for (i = 0; i < ndisks; ++i)
00176     {
00177         if (bl[i])
00178         {
00179             disk_bids[i].resize(bl[i]);
00180             const stxxl::int64 old_capacity =
00181                 disk_allocators[i]->get_total_bytes();
00182             const stxxl::int64 new_capacity =
00183                 disk_allocators[i]->new_blocks(disk_bids[i]);
00184             if (old_capacity != new_capacity)
00185             {
00186                 // resize the file
00187                 disk_files[i]->set_size(new_capacity);
00188                 if (new_capacity != disk_allocators[i]->get_total_bytes())
00189                     STXXL_ERRMSG("File resizing failed: actual size " << disk_allocators[i]->get_total_bytes() << " != requested size " << new_capacity);
00190             }
00191         }
00192     }
00193 
00194     memset(bl, 0, ndisks * sizeof(int_type));
00195 
00196     OutputIterator it = out;
00197     for (i = 0; i != nblocks; ++it, ++i)
00198     {
00199         const int disk = disk_ptrs[i]->get_allocator_id();
00200         bid_type bid(disk_ptrs[i], disk_bids[disk][bl[disk]++].offset);
00201         *it = bid;
00202         STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:new    " << FMT_BID(bid));
00203     }
00204 
00205     delete[] bl;
00206     delete[] disk_bids;
00207     delete[] disk_ptrs;
00208 }
00209 
00210 
00211 template <unsigned BLK_SIZE>
00212 void block_manager::delete_block(const BID<BLK_SIZE> & bid)
00213 {
00214     // do not uncomment it
00215     //assert(bid.storage->get_allocator_id() < config::get_instance()->disks_number());
00216     if (!bid.is_managed())
00217         return;  // self managed disk
00218     STXXL_VERBOSE_BLOCK_LIFE_CYCLE("BLC:delete " << FMT_BID(bid));
00219     assert(bid.storage->get_allocator_id() >= 0);
00220     disk_allocators[bid.storage->get_allocator_id()]->delete_block(bid);
00221     disk_files[bid.storage->get_allocator_id()]->discard(bid.offset, bid.size);
00222 }
00223 
00224 
00225 template <class BIDIteratorClass>
00226 void block_manager::delete_blocks(
00227     const BIDIteratorClass & bidbegin,
00228     const BIDIteratorClass & bidend)
00229 {
00230     for (BIDIteratorClass it = bidbegin; it != bidend; it++)
00231     {
00232         delete_block(*it);
00233     }
00234 }
00235 
00236 // in bytes
00237 #ifndef STXXL_DEFAULT_BLOCK_SIZE
00238     #define STXXL_DEFAULT_BLOCK_SIZE(type) (2 * 1024 * 1024) // use traits
00239 #endif
00240 
00242 
00243 __STXXL_END_NAMESPACE
00244 
00245 #endif // !STXXL_MNG_HEADER
00246 // vim: et:ts=4:sw=4

Generated by  doxygen 1.7.1