LCOV - code coverage report
Current view: top level - vset/memory/fsb - chunk.hpp (source / functions) Hit Total Coverage
Test: v-set-coverage.info Lines: 61 67 91.0 %
Date: 2019-09-12 Functions: 77 103 74.8 %

          Line data    Source code
       1             : //
       2             : // Author: Vladimir Migashko <migashko@gmail.com>, (C) 2012
       3             : //
       4             : // Copyright: See COPYING file that comes with this distribution
       5             : //
       6             : 
       7             : #ifndef VSET_MEMORY_FSB_CHUNK_HPP
       8             : #define VSET_MEMORY_FSB_CHUNK_HPP
       9             : 
      10             : #include <fas/system/nullptr.hpp>
      11             : #include <stdexcept>
      12             : 
      13             : namespace vset { namespace memory{ namespace fsb{
      14             : 
      15             : template<typename T>
      16             : struct chunk
      17             : {
      18             :   typedef chunk<T> self;
      19             :   typedef T value_type;
      20             : 
      21             :   size_t bits;
      22             :   T data[sizeof(size_t)*8];
      23             : 
      24          38 :   chunk()
      25             :     : bits(0)
      26          38 :     , data()
      27          38 :   {}
      28             : 
      29       11087 :   bool filled() const
      30             :   {
      31       11087 :     return bits == static_cast<size_t>(-1);
      32             :   }
      33             : 
      34       50776 :   bool empty() const
      35             :   {
      36       50776 :     return bits == 0;
      37             :   }
      38             : 
      39       22694 :   static size_t max_count()
      40             :   {
      41       22694 :     return sizeof(size_t)*8;
      42             :   }
      43             :   
      44             :   static size_t head_size()
      45             :   {
      46             :     return sizeof(size_t);
      47             :   }
      48             : 
      49         242 :   size_t count() const
      50             :   {
      51         242 :     if ( this->empty() )
      52             :     {
      53           0 :       return 0;
      54             :     }
      55         242 :     else if ( this->filled() )
      56             :     {
      57          36 :       return this->max_count();
      58             :     }
      59             : 
      60         206 :     size_t cnt = 0;
      61       13390 :     for ( size_t i = 0; i < sizeof(size_t)*8; ++i )
      62             :     {
      63       13184 :       cnt += ( 0 != (bits & ( static_cast<size_t>(1) << i)) );
      64             :     }
      65         206 :     return cnt;
      66             :   }
      67             : 
      68             :   static size_t size()
      69             :   {
      70             :     return sizeof(self);
      71             :   }
      72             : 
      73             :   void clear()
      74             :   {
      75             :     bits = 0;
      76             :   }
      77             : 
      78       30276 :   const T* first_value() const
      79             :   {
      80       30276 :     size_t index = next_occuped(0);
      81       30276 :     if ( index == static_cast<size_t>(-1) )
      82             :     {
      83           0 :       return fas_nullptr;
      84             :     }
      85       30276 :     return data + index;
      86             :   }
      87             : 
      88             :   T* first_value()
      89             :   {
      90             :     return const_cast<T*>( const_cast<const self*>(this)->first_value()  );
      91             :   }
      92             : 
      93          40 :   const T* last_value() const
      94             :   {
      95          40 :     size_t index = pred_occuped( max_count() - 1 );
      96          40 :     if ( index == static_cast<size_t>(-1) )
      97             :     {
      98           0 :       return fas_nullptr;
      99             :     }
     100          40 :     return data + index;
     101             :   }
     102             : 
     103             :   T* last_value()
     104             :   {
     105             :     return const_cast<T*>( const_cast<const self*>(this)->last_value()  );
     106             :   }
     107             : 
     108      124227 :   const T* next_value(const T* current) const
     109             :   {
     110      124227 :     size_t index = this->next_occuped( static_cast<size_t>(current - data + 1) );
     111      124227 :     if ( index == static_cast<size_t>(-1) )
     112             :     {
     113       20265 :       return fas_nullptr;
     114             :     }
     115      103962 :     return data + index;
     116             :   }
     117             : 
     118             :   T* next_value(T* current)
     119             :   {
     120             :     return const_cast<T*>( const_cast<const self*>(this)->next_value(current) );
     121             :   }
     122             : 
     123       22343 :   const T* pred_value(const T* current) const
     124             :   {
     125       22343 :     size_t index = this->pred_occuped( static_cast<size_t>(current - data - 1) );
     126       22343 :     if ( index == static_cast<size_t>(-1) )
     127             :     {
     128        1977 :       return fas_nullptr;
     129             :     }
     130       20366 :     return data + index;
     131             :   }
     132             : 
     133             :   T* pred_value(T* current)
     134             :   {
     135             :     return const_cast<T*>( const_cast<const self*>(this)->pred_value(current) );
     136             :   }
     137             :   
     138      154503 :   size_t next_occuped(size_t pos = 0) const
     139             :   {
     140     1357422 :     for ( size_t i = pos; i < sizeof(size_t)*8; ++i )
     141             :     {
     142     1337157 :       if ( bits & ( static_cast<size_t>(1) << i) )
     143             :       {
     144      134238 :         return i;
     145             :       }
     146             :     }
     147       20265 :     return static_cast<size_t>(-1);
     148             :   }
     149             : 
     150       22383 :   size_t pred_occuped(size_t pos = max_count() - 1) const
     151             :   {
     152       22615 :     for ( size_t i = pos ; i < max_count(); --i )
     153             :     {
     154       20638 :       if ( bits & ( static_cast<size_t>(1) << i) )
     155             :       {
     156       20406 :         return i;
     157             :       }
     158             :     }
     159        1977 :     return static_cast<size_t>(-1);
     160             :   }
     161             : 
     162       10833 :   size_t first_free() const
     163             :   {
     164       55318 :     for ( size_t i = 0; i < sizeof(size_t)*8; ++i )
     165             :     {
     166       55318 :       if ( ! ( bits & ( static_cast<size_t>(1) << i) ) )
     167             :       {
     168       10833 :         return i;
     169             :       }
     170             :     }
     171           0 :     return static_cast<size_t>(-1);
     172             :   }
     173             : 
     174       10833 :   T* mark()
     175             :   {
     176       10833 :     size_t index = first_free();
     177       10833 :     if ( index == static_cast<size_t>(-1) )
     178             :     {
     179           0 :       return fas_nullptr;
     180             :     }
     181       10833 :     return mark(index);
     182             :   }
     183             : 
     184       10833 :   T* mark(size_t index)
     185             :   {
     186       10833 :     bits |= ( static_cast<size_t>(1) <<  index );
     187       10833 :     return data + index;
     188             :   }
     189             : 
     190       10008 :   void free(T* addr)
     191             :   {
     192       10008 :     size_t index = static_cast<size_t>(addr - data);
     193       10008 :     if ( index < 64 )
     194             :     {
     195       10008 :       bits &= ~( static_cast<size_t>(1)<<index);
     196             :     }
     197             :     else
     198             :     {
     199           0 :       throw std::invalid_argument("chunk<T>::free");
     200             :     }
     201       10008 :   }
     202             : };
     203             : 
     204             : }}}
     205             : 
     206             : #endif

Generated by: LCOV version 1.10