LCOV - code coverage report
Current view: top level - zerobuf - Allocator.h (source / functions) Hit Total Coverage
Test: ZeroBuf Lines: 41 51 80.4 %
Date: 2018-01-09 16:38:26 Functions: 82 90 91.1 %

          Line data    Source code
       1             : 
       2             : /* Copyright (c) 2015-2016, Human Brain Project
       3             :  *                          Stefan.Eilemann@epfl.ch
       4             :  *                          grigori.chevtchenko@epfl.ch
       5             :  */
       6             : 
       7             : #ifndef ZEROBUF_ALLOCATOR_H
       8             : #define ZEROBUF_ALLOCATOR_H
       9             : 
      10             : #include <zerobuf/types.h>
      11             : 
      12             : namespace zerobuf
      13             : {
      14             : /**
      15             :  * Allocator base class and interface.
      16             :  *
      17             :  * Implements part of the binary data layout by providing access to the stored
      18             :  * elements. Not intended to be used by application code.
      19             :  */
      20             : class Allocator
      21             : {
      22             : public:
      23         614 :     Allocator() {}
      24         614 :     virtual ~Allocator() {}
      25             :     virtual uint8_t* getData() = 0;
      26             :     virtual const uint8_t* getData() const = 0;
      27             :     virtual size_t getSize() const = 0;
      28             :     virtual void copyBuffer(const void* data, size_t size) = 0;
      29           0 :     virtual void compact(float /*threshold*/)
      30             :     {
      31           0 :         throw std::runtime_error("Compaction not implemented");
      32             :     }
      33           3 :     virtual bool isMovable() const { return false; } // allocation is moveable
      34          63 :     virtual bool isMutable() const { return true; }  // data is mutable
      35             :                                                      /**
      36             :                                                       * Update allocation of the dynamic elem at index to have newSize bytes.
      37             :                                                       *
      38             :                                                       * The offset and size fields in the static section are updated as needed.
      39             :                                                       * Does not copy the old data to the new location.
      40             :                                                       *
      41             :                                                       * @return the pointer to the elem at the new place, or nullptr if it was
      42             :                                                       *         not moved.
      43             :                                                       */
      44           0 :     virtual uint8_t* updateAllocation(size_t /*index*/, bool /*copy*/,
      45             :                                       size_t /*newSize*/)
      46             :     {
      47           0 :         throw std::runtime_error("Dynamic allocation not implemented");
      48             :     }
      49             : 
      50             :     template <class T>
      51       20180 :     T* getItemPtr(const size_t offset)
      52             :     {
      53       20180 :         return reinterpret_cast<T*>(getData() + offset);
      54             :     }
      55             : 
      56             :     template <class T>
      57       46334 :     const T* getItemPtr(const size_t offset) const
      58             :     {
      59       46334 :         return reinterpret_cast<const T*>(getData() + offset);
      60             :     }
      61             : 
      62             :     template <class T>
      63       20026 :     T& getItem(const size_t offset)
      64             :     {
      65       20026 :         return *getItemPtr<T>(offset);
      66             :     }
      67             : 
      68             :     template <class T>
      69       46125 :     T getItem(const size_t offset) const
      70             :     {
      71       46125 :         return *getItemPtr<T>(offset);
      72             :     }
      73             : 
      74             :     template <class T>
      75          59 :     T* getDynamic(const size_t index)
      76             :     {
      77          59 :         return reinterpret_cast<T*>(getData() + _getOffset(index));
      78             :     }
      79             : 
      80             :     template <class T>
      81         704 :     const T* getDynamic(const size_t index) const
      82             :     {
      83         704 :         return reinterpret_cast<const T*>(getData() + _getOffset(index));
      84             :     }
      85             : 
      86         695 :     uint64_t getDynamicOffset(const size_t index) const
      87             :     {
      88         695 :         return _getOffset(index);
      89             :     }
      90             : 
      91         859 :     size_t getDynamicSize(const size_t index) const { return _getSize(index); }
      92         120 :     void check(const size_t numDynamics) const
      93             :     {
      94         332 :         for (size_t i = 0; i < numDynamics; ++i)
      95         212 :             _checkIndex(i);
      96         120 :     }
      97             : 
      98             : protected:
      99       12541 :     uint64_t& _getOffset(const size_t i)
     100             :     {
     101       12541 :         _checkIndex(i);
     102       12541 :         return getItem<uint64_t>(4 + i * 16);
     103             :     }
     104        1399 :     uint64_t _getOffset(const size_t i) const
     105             :     {
     106        1399 :         _checkIndex(i);
     107        1399 :         return getItem<uint64_t>(4 + i * 16);
     108             :     }
     109        6370 :     uint64_t& _getSize(const size_t i)
     110             :     {
     111        6370 :         _checkIndex(i);
     112        6370 :         return getItem<uint64_t>(4 + 8 + i * 16);
     113             :     }
     114         859 :     uint64_t _getSize(const size_t i) const
     115             :     {
     116         859 :         _checkIndex(i);
     117         859 :         return getItem<uint64_t>(4 + 8 + i * 16);
     118             :     }
     119             : 
     120       21381 :     void _checkIndex(const size_t i) const
     121             :     {
     122       21381 :         const uint64_t offset = getItem<uint64_t>(4 + i * 16);
     123       21381 :         const uint64_t size = getItem<uint64_t>(4 + 8 + i * 16);
     124       21381 :         if (offset + size > getSize())
     125             :             throw std::runtime_error(
     126           0 :                 "Internal allocator error: dynamic #" + std::to_string(i) +
     127           0 :                 " at " + std::to_string(offset) + " size " +
     128           0 :                 std::to_string(size) + " exceeds allocation size " +
     129           0 :                 std::to_string(getSize()));
     130       21381 :         if (offset != 0 && offset < 4 + (i + 1) * 16)
     131             :             throw std::runtime_error(
     132           0 :                 "Internal allocator error: dynamic #" + std::to_string(i) +
     133           0 :                 " at " + std::to_string(offset) + " is within static section");
     134       21381 :     }
     135             : };
     136             : }
     137             : 
     138             : #endif

Generated by: LCOV version 1.11