Stxxl  1.4.0
mng/diskallocator.cpp
Go to the documentation of this file.
00001 /***************************************************************************
00002  *  mng/diskallocator.cpp
00003  *
00004  *  Part of the STXXL. See http://stxxl.sourceforge.net
00005  *
00006  *  Copyright (C) 2002 Roman Dementiev <dementiev@mpi-sb.mpg.de>
00007  *  Copyright (C) 2008, 2010 Andreas Beckmann <beckmann@cs.uni-frankfurt.de>
00008  *
00009  *  Distributed under the Boost Software License, Version 1.0.
00010  *  (See accompanying file LICENSE_1_0.txt or copy at
00011  *  http://www.boost.org/LICENSE_1_0.txt)
00012  **************************************************************************/
00013 
00014 #include <stxxl/bits/mng/diskallocator.h>
00015 #include <stxxl/bits/common/error_handling.h>
00016 
00017 
00018 __STXXL_BEGIN_NAMESPACE
00019 
00020 void DiskAllocator::dump() const
00021 {
00022     int64 total = 0;
00023     sortseq::const_iterator cur = free_space.begin();
00024     STXXL_ERRMSG("Free regions dump:");
00025     for ( ; cur != free_space.end(); ++cur)
00026     {
00027         STXXL_ERRMSG("Free chunk: begin: " << (cur->first) << " size: " << (cur->second));
00028         total += cur->second;
00029     }
00030     STXXL_ERRMSG("Total bytes: " << total);
00031 }
00032 
00033 
00034 void DiskAllocator::deallocation_error(
00035     stxxl::int64 block_pos, stxxl::int64 block_size,
00036     const sortseq::iterator & pred, const sortseq::iterator & succ) const
00037 {
00038     STXXL_ERRMSG("Error deallocating block at " << block_pos << " size " << block_size);
00039     STXXL_ERRMSG(((pred == succ) ? "pred==succ" : "pred!=succ"));
00040     if (pred == free_space.end()) {
00041         STXXL_ERRMSG("pred==free_space.end()");
00042     } else {
00043         if (pred == free_space.begin())
00044             STXXL_ERRMSG("pred==free_space.begin()");
00045         STXXL_ERRMSG("pred: begin=" << pred->first << " size=" << pred->second);
00046     }
00047     if (succ == free_space.end()) {
00048         STXXL_ERRMSG("succ==free_space.end()");
00049     } else {
00050         if (succ == free_space.begin())
00051             STXXL_ERRMSG("succ==free_space.begin()");
00052         STXXL_ERRMSG("succ: begin=" << succ->first << " size=" << succ->second);
00053     }
00054     dump();
00055 }
00056 
00057 
00058 void DiskAllocator::add_free_region(stxxl::int64 block_pos, stxxl::int64 block_size)
00059 {
00060     //assert(block_size);
00061     //dump();
00062     STXXL_VERBOSE2("Deallocating a block with size: " << block_size << " position: " << block_pos);
00063     stxxl::int64 region_pos = block_pos;
00064     stxxl::int64 region_size = block_size;
00065     if (!free_space.empty())
00066     {
00067         sortseq::iterator succ = free_space.upper_bound(region_pos);
00068         sortseq::iterator pred = succ;
00069         if (pred != free_space.begin())
00070             pred--;
00071         if (pred != free_space.end())
00072         {
00073             if (pred->first <= region_pos && pred->first + pred->second > region_pos)
00074             {
00075                 STXXL_THROW(bad_ext_alloc, "DiskAllocator::check_corruption", "Error: double deallocation of external memory, trying to deallocate region " << region_pos << " + " << region_size << "  in empty space [" << pred->first << " + " << pred->second << "]");
00076             }
00077         }
00078         if (succ != free_space.end())
00079         {
00080             if (region_pos <= succ->first && region_pos + region_size > succ->first)
00081             {
00082                 STXXL_THROW(bad_ext_alloc, "DiskAllocator::check_corruption", "Error: double deallocation of external memory, trying to deallocate region " << region_pos << " + " << region_size << "  which overlaps empty space [" << succ->first << " + " << succ->second << "]");
00083             }
00084         }
00085         if (succ == free_space.end())
00086         {
00087             if (pred == free_space.end())
00088             {
00089                 deallocation_error(block_pos, block_size, pred, succ);
00090                 assert(pred != free_space.end());
00091             }
00092             if ((*pred).first + (*pred).second == region_pos)
00093             {
00094                 // coalesce with predecessor
00095                 region_size += (*pred).second;
00096                 region_pos = (*pred).first;
00097                 free_space.erase(pred);
00098             }
00099         }
00100         else
00101         {
00102             if (free_space.size() > 1)
00103             {
00104 #if 0
00105                 if (pred == succ)
00106                 {
00107                     deallocation_error(block_pos, block_size, pred, succ);
00108                     assert(pred != succ);
00109                 }
00110 #endif
00111                 bool succ_is_not_the_first = (succ != free_space.begin());
00112                 if ((*succ).first == region_pos + region_size)
00113                 {
00114                     // coalesce with successor
00115                     region_size += (*succ).second;
00116                     free_space.erase(succ);
00117                 }
00118                 if (succ_is_not_the_first)
00119                 {
00120                     if (pred == free_space.end())
00121                     {
00122                         deallocation_error(block_pos, block_size, pred, succ);
00123                         assert(pred != free_space.end());
00124                     }
00125                     if ((*pred).first + (*pred).second == region_pos)
00126                     {
00127                         // coalesce with predecessor
00128                         region_size += (*pred).second;
00129                         region_pos = (*pred).first;
00130                         free_space.erase(pred);
00131                     }
00132                 }
00133             }
00134             else
00135             {
00136                 if ((*succ).first == region_pos + region_size)
00137                 {
00138                     // coalesce with successor
00139                     region_size += (*succ).second;
00140                     free_space.erase(succ);
00141                 }
00142             }
00143         }
00144     }
00145 
00146     free_space[region_pos] = region_size;
00147     free_bytes += block_size;
00148 
00149     //dump();
00150 }
00151 
00152 __STXXL_END_NAMESPACE
00153 // vim: et:ts=4:sw=4
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Defines