Stxxl  1.4.0
include/stxxl/bits/mng/mng.h
Go to the documentation of this file.
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
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines