LCOV - code coverage report
Current view: top level - core/core - SPMemory.h (source / functions) Hit Total Coverage
Test: coverage.info Lines: 112 120 93.3 %
Date: 2024-05-12 00:16:13 Functions: 269 409 65.8 %

          Line data    Source code
       1             : /**
       2             : Copyright (c) 2019-2022 Roman Katuntsev <sbkarr@stappler.org>
       3             : Copyright (c) 2023 Stappler LLC <admin@stappler.dev>
       4             : 
       5             : Permission is hereby granted, free of charge, to any person obtaining a copy
       6             : of this software and associated documentation files (the "Software"), to deal
       7             : in the Software without restriction, including without limitation the rights
       8             : to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
       9             : copies of the Software, and to permit persons to whom the Software is
      10             : furnished to do so, subject to the following conditions:
      11             : 
      12             : The above copyright notice and this permission notice shall be included in
      13             : all copies or substantial portions of the Software.
      14             : 
      15             : THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      16             : IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      17             : FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      18             : AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      19             : LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      20             : OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      21             : THE SOFTWARE.
      22             : **/
      23             : 
      24             : #ifndef STAPPLER_CORE_SPMEMORY_H_
      25             : #define STAPPLER_CORE_SPMEMORY_H_
      26             : 
      27             : #include "SPMemInterface.h"
      28             : #include "SPSpanView.h"
      29             : #include "SPString.h"
      30             : #include "SPStringView.h"
      31             : #include "SPTime.h"
      32             : 
      33             : #ifdef MODULE_STAPPLER_DATA
      34             : #include "SPData.h"
      35             : #endif
      36             : 
      37             : namespace STAPPLER_VERSIONIZED stappler {
      38             : 
      39             : template <typename T>
      40             : class VectorAdapter {
      41             : public:
      42      141662 :         size_t size() const { return size_fn(target); }
      43     9176743 :         T & back() const { return back_fn(target); }
      44             :         T & front() const { return front_fn(target); }
      45     9177134 :         bool empty() const { return empty_fn(target); }
      46      286381 :         T & at(size_t pos) const { return at_fn(target, pos); }
      47    43460265 :         T & emplace_back(T &&v) const { return emplace_back_fn(target, move(v)); }
      48             : 
      49         383 :         T *begin() const { return begin_fn(target); }
      50         383 :         T *end() const { return end_fn(target); }
      51             : 
      52     1083762 :         void clear() const { clear_fn(target); }
      53     1084012 :         void reserve(size_t count) const { reserve_fn(target, count); }
      54           0 :         void resize(size_t count) const { resize_fn(target, count); }
      55             : 
      56         325 :         explicit operator bool () const { return target != nullptr; }
      57             : 
      58       53617 :         VectorAdapter() = default;
      59             : 
      60             :         VectorAdapter(memory::StandartInterface::VectorType<T> &vec);
      61             :         VectorAdapter(memory::PoolInterface::VectorType<T> &vec);
      62             : 
      63             : public:
      64             :         void *target = nullptr;
      65             :         size_t (*size_fn) (void *) = nullptr;
      66             :         T & (*back_fn) (void *) = nullptr;
      67             :         T & (*front_fn) (void *) = nullptr;
      68             :         bool (*empty_fn) (void *) = nullptr;
      69             :         T & (*at_fn) (void *, size_t) = nullptr;
      70             :         T & (*emplace_back_fn) (void *, T&&) = nullptr;
      71             :         T * (*begin_fn) (void *) = nullptr;
      72             :         T * (*end_fn) (void *) = nullptr;
      73             :         void (*clear_fn) (void *) = nullptr;
      74             :         void (*reserve_fn) (void *, size_t) = nullptr;
      75             :         void (*resize_fn) (void *, size_t) = nullptr;
      76             : };
      77             : 
      78             : }
      79             : 
      80             : namespace STAPPLER_VERSIONIZED stappler::mem_pool {
      81             : 
      82             : namespace pool = memory::pool;
      83             : namespace allocator = memory::allocator;
      84             : 
      85             : using CharGroupId = stappler::CharGroupId;
      86             : 
      87             : using memory::allocator_t;
      88             : using memory::pool_t;
      89             : 
      90             : using stappler::Time;
      91             : using stappler::TimeInterval;
      92             : 
      93             : using stappler::StringView;
      94             : using stappler::StringViewUtf8;
      95             : using stappler::WideStringView;
      96             : using stappler::BytesView;
      97             : using stappler::SpanView;
      98             : 
      99             : using AllocBase = stappler::memory::AllocPool;
     100             : 
     101             : using String = stappler::memory::string;
     102             : using WideString = stappler::memory::u16string;
     103             : using Bytes = stappler::memory::vector<uint8_t>;
     104             : 
     105             : using StringStream = stappler::memory::ostringstream;
     106             : using OutputStream = std::ostream;
     107             : 
     108             : template <typename T>
     109             : using Vector = stappler::memory::vector<T>;
     110             : 
     111             : template <typename K, typename V, typename Compare = std::less<void>>
     112             : using Map = stappler::memory::map<K, V, Compare>;
     113             : 
     114             : template <typename T, typename Compare = std::less<void>>
     115             : using Set = stappler::memory::set<T, Compare>;
     116             : 
     117             : template <typename T>
     118             : using Function = stappler::memory::function<T>;
     119             : 
     120             : using stappler::Callback;
     121             : 
     122             : using stappler::Pair;
     123             : 
     124             : template <typename T, typename V, typename Compare = std::less<void>>
     125             : using dict = stappler::memory::dict<T, V, Compare>;
     126             : 
     127             : using Mutex = std::mutex;
     128             : 
     129             : using stappler::makeSpanView;
     130             : 
     131             : template <typename Callback>
     132       27006 : inline auto perform(const Callback &cb, memory::pool_t *p) {
     133             :         struct Context {
     134       27006 :                 Context(memory::pool_t *pool) : _pool(pool) {
     135       27006 :                         memory::pool::push(_pool);
     136       27006 :                 }
     137       27006 :                 ~Context() {
     138       27006 :                         memory::pool::pop();
     139       27006 :                 }
     140             : 
     141             :                 memory::pool_t *_pool = nullptr;
     142       27006 :         } holder(p);
     143       54012 :         return cb();
     144       27006 : }
     145             : 
     146             : template <typename Callback>
     147       19849 : inline auto perform(const Callback &cb, memory::pool_t *p, uint32_t tag, void *ptr) {
     148             :         struct Context {
     149       19849 :                 Context(memory::pool_t *pool, uint32_t t, void *p) : _pool(pool) {
     150       19849 :                         memory::pool::push(_pool, t, p);
     151       19849 :                 }
     152       19849 :                 ~Context() {
     153       19849 :                         memory::pool::pop();
     154       19849 :                 }
     155             : 
     156             :                 memory::pool_t *_pool = nullptr;
     157       19849 :         } holder(p, tag, ptr);
     158       39698 :         return cb();
     159       19849 : }
     160             : 
     161             : template <typename Callback>
     162         105 : inline auto perform_temporary(const Callback &cb, memory::pool_t *p = nullptr) {
     163             :         struct Context {
     164         105 :                 Context(memory::pool_t *pool)
     165         105 :                 : _pool(pool ? memory::pool::create(pool) :  memory::pool::create(memory::pool::acquire())) {
     166         105 :                         memory::pool::push(_pool);
     167         105 :                 }
     168         105 :                 ~Context() {
     169         105 :                         memory::pool::pop();
     170         105 :                         memory::pool::destroy(_pool);
     171         105 :                 }
     172             : 
     173             :                 memory::pool_t *_pool = nullptr;
     174         105 :         } holder(p);
     175         210 :         return cb();
     176         105 : }
     177             : 
     178             : template <typename T>
     179       13225 : inline bool emplace_ordered(Vector<T> &vec, T val) {
     180       13225 :         auto lb = std::lower_bound(vec.begin(), vec.end(), val);
     181       13225 :         if (lb == vec.end()) {
     182       12624 :                 vec.emplace_back(val);
     183       12624 :                 return true;
     184         601 :         } else if (*lb != val) {
     185         526 :                 vec.emplace(lb, val);
     186         526 :                 return true;
     187             :         }
     188          75 :         return false;
     189             : }
     190             : 
     191             : template <typename T>
     192             : inline bool exists_ordered(Vector<T> &vec, const T & val) {
     193             :         auto lb = std::lower_bound(vec.begin(), vec.end(), val);
     194             :         if (lb == vec.end() || *lb != val) {
     195             :                 return false;
     196             :         }
     197             :         return true;
     198             : }
     199             : 
     200             : }
     201             : 
     202             : 
     203             : namespace STAPPLER_VERSIONIZED stappler::mem_std {
     204             : 
     205             : namespace pool = memory::pool;
     206             : namespace allocator = memory::allocator;
     207             : 
     208             : using memory::allocator_t;
     209             : using memory::pool_t;
     210             : 
     211             : using stappler::Time;
     212             : using stappler::TimeInterval;
     213             : 
     214             : using stappler::StringView;
     215             : using stappler::StringViewUtf8;
     216             : using stappler::WideStringView;
     217             : using stappler::BytesView;
     218             : using stappler::SpanView;
     219             : 
     220             : using AllocBase = stappler::memory::AllocBase;
     221             : 
     222             : using String = std::string;
     223             : using WideString = std::u16string;
     224             : using Bytes = std::vector<uint8_t>;
     225             : 
     226             : using StringStream = std::stringstream;
     227             : using OutputStream = std::ostream;
     228             : 
     229             : template <typename T>
     230             : using Vector = std::vector<T>;
     231             : 
     232             : template <typename K, typename V, typename Compare = std::less<void>>
     233             : using Map = std::map<K, V, Compare>;
     234             : 
     235             : template <typename T, typename Compare = std::less<void>>
     236             : using Set = std::set<T, Compare>;
     237             : 
     238             : template <typename T, typename V>
     239             : using HashMap = std::unordered_map<T, V, std::hash<T>, std::equal_to<T>>;
     240             : 
     241             : template <typename T>
     242             : using HashSet = std::unordered_set<T, std::hash<T>, std::equal_to<T>, std::allocator<T>>;
     243             : 
     244             : template <typename T>
     245             : using Function = std::function<T>;
     246             : 
     247             : using stappler::Callback;
     248             : 
     249             : using stappler::Pair;
     250             : 
     251             : using Mutex = std::mutex;
     252             : 
     253             : using stappler::makeSpanView;
     254             : 
     255             : template <typename Callback>
     256        1952 : inline auto perform(const Callback &cb, memory::pool_t *p) {
     257             :         struct Context {
     258        1952 :                 Context(memory::pool_t *pool) : _pool(pool) {
     259        1952 :                         memory::pool::push(_pool);
     260        1952 :                 }
     261        1952 :                 ~Context() {
     262        1952 :                         memory::pool::pop();
     263        1952 :                 }
     264             : 
     265             :                 memory::pool_t *_pool = nullptr;
     266        1952 :         } holder(p);
     267        3904 :         return cb();
     268        1952 : }
     269             : 
     270             : template <typename Callback>
     271             : inline auto perform_temporary(const Callback &cb, memory::pool_t *p = nullptr) {
     272             :         struct Context {
     273             :                 Context(memory::pool_t *pool)
     274             :                 : _pool(pool ? memory::pool::create(pool) :  memory::pool::create(memory::pool::acquire())) {
     275             :                         memory::pool::push(_pool);
     276             :                 }
     277             :                 ~Context() {
     278             :                         memory::pool::pop();
     279             :                         memory::pool::destroy(_pool);
     280             :                 }
     281             : 
     282             :                 memory::pool_t *_pool = nullptr;
     283             :         } holder(p);
     284             :         return cb();
     285             : }
     286             : 
     287             : template <typename T>
     288     1709180 : inline bool emplace_ordered(Vector<T> &vec, T val) {
     289     1709180 :         auto lb = std::lower_bound(vec.begin(), vec.end(), val);
     290     1709180 :         if (lb == vec.end()) {
     291      241683 :                 vec.emplace_back(val);
     292      241683 :                 return true;
     293     1467497 :         } else if (*lb != val) {
     294      352171 :                 vec.emplace(lb, val);
     295      352171 :                 return true;
     296             :         }
     297     1115326 :         return false;
     298             : }
     299             : 
     300             : template <typename T>
     301             : inline bool exists_ordered(Vector<T> &vec, const T & val) {
     302             :         auto lb = std::lower_bound(vec.begin(), vec.end(), val);
     303             :         if (lb == vec.end() || *lb != val) {
     304             :                 return false;
     305             :         }
     306             :         return true;
     307             : }
     308             : 
     309             : }
     310             : 
     311             : 
     312             : #ifdef MODULE_STAPPLER_DATA
     313             : 
     314             : namespace STAPPLER_VERSIONIZED stappler::mem_pool {
     315             : 
     316             : using Value = stappler::data::ValueTemplate<stappler::memory::PoolInterface>;
     317             : using Array = Value::ArrayType;
     318             : using Dictionary = Value::DictionaryType;
     319             : using EncodeFormat = stappler::data::EncodeFormat;
     320             : 
     321             : inline bool emplace_ordered(Vector<Value> &vec, const Value &val) {
     322             :         auto lb = std::lower_bound(vec.begin(), vec.end(), val, [&] (const Value &l, const Value &r) {
     323             :                 return l.getInteger() < r.getInteger();
     324             :         });
     325             :         if (lb == vec.end()) {
     326             :                 vec.emplace_back(val);
     327             :                 return true;
     328             :         } else if (*lb != val) {
     329             :                 vec.emplace(lb, val);
     330             :                 return true;
     331             :         }
     332             :         return false;
     333             : }
     334             : 
     335             : }
     336             : 
     337             : 
     338             : namespace STAPPLER_VERSIONIZED stappler::mem_std {
     339             : 
     340             : using Value = data::ValueTemplate<stappler::memory::StandartInterface>;
     341             : using Array = Value::ArrayType;
     342             : using Dictionary = Value::DictionaryType;
     343             : using EncodeFormat = stappler::data::EncodeFormat;
     344             : 
     345             : inline bool emplace_ordered(Vector<Value> &vec, const Value &val) {
     346             :         auto lb = std::lower_bound(vec.begin(), vec.end(), val, [&] (const Value &l, const Value &r) {
     347             :                 return l.getInteger() < r.getInteger();
     348             :         });
     349             :         if (lb == vec.end()) {
     350             :                 vec.emplace_back(val);
     351             :                 return true;
     352             :         } else if (*lb != val) {
     353             :                 vec.emplace(lb, val);
     354             :                 return true;
     355             :         }
     356             :         return false;
     357             : }
     358             : 
     359             : }
     360             : 
     361             : namespace STAPPLER_VERSIONIZED stappler {
     362             : 
     363             : template <typename T>
     364     1148123 : VectorAdapter<T>::VectorAdapter(memory::StandartInterface::VectorType<T> &vec)
     365     1289735 : : target(&vec), size_fn([] (void *target) {
     366      141612 :         return ((mem_std::Vector<T> *)target)->size();
     367    10323866 : }), back_fn([] (void *target) -> T & {
     368     9175743 :         return ((mem_std::Vector<T> *)target)->back();
     369     1148123 : }), front_fn([] (void *target) -> T & {
     370           0 :         return ((mem_std::Vector<T> *)target)->front();
     371    10324257 : }), empty_fn([] (void *target) {
     372     9176134 :         return ((mem_std::Vector<T> *)target)->empty();
     373     1434504 : }), at_fn([] (void *target, size_t pos) -> T & {
     374      286381 :         return ((mem_std::Vector<T> *)target)->at(pos);
     375    44597263 : }), emplace_back_fn([] (void *target, T &&v) -> T & {
     376    43449140 :         return ((mem_std::Vector<T> *)target)->emplace_back(move(v));
     377     1148506 : }), begin_fn([] (void *target) -> T * {
     378         383 :         return &*((mem_std::Vector<T> *)target)->begin();
     379     1148506 : }), end_fn([] (void *target) -> T * {
     380         383 :         return &*((mem_std::Vector<T> *)target)->end();
     381     3315447 : }), clear_fn([] (void *target) {
     382     1083662 :         ((mem_std::Vector<T> *)target)->clear();
     383     3313247 : }), reserve_fn([] (void *target, size_t s) {
     384     1082562 :         ((mem_std::Vector<T> *)target)->reserve(s);
     385     1148123 : }), resize_fn([] (void *target, size_t s) {
     386           0 :         ((mem_std::Vector<T> *)target)->resize(s);
     387     1148123 : }) { }
     388             : 
     389             : template <typename T>
     390        1800 : VectorAdapter<T>::VectorAdapter(memory::PoolInterface::VectorType<T> &vec)
     391        1850 : : target(&vec), size_fn([] (void *target) {
     392          50 :         return ((mem_pool::Vector<T> *)target)->size();
     393        2800 : }), back_fn([] (void *target) -> T & {
     394        1000 :         return ((mem_pool::Vector<T> *)target)->back();
     395        1800 : }), front_fn([] (void *target) -> T & {
     396           0 :         return ((mem_pool::Vector<T> *)target)->front();
     397        2800 : }), empty_fn([] (void *target) {
     398        1000 :         return ((mem_pool::Vector<T> *)target)->empty();
     399        1800 : }), at_fn([] (void *target, size_t pos) -> T & {
     400           0 :         return ((mem_pool::Vector<T> *)target)->at(pos);
     401       12925 : }), emplace_back_fn([] (void *target, T &&v) -> T & {
     402       11125 :         return ((mem_pool::Vector<T> *)target)->emplace_back(move(v));
     403        1800 : }), begin_fn([] (void *target) -> T * {
     404           0 :         return &*((mem_pool::Vector<T> *)target)->begin();
     405        1800 : }), end_fn([] (void *target) -> T * {
     406           0 :         return &*((mem_pool::Vector<T> *)target)->end();
     407        2000 : }), clear_fn([] (void *target) {
     408         100 :         ((mem_pool::Vector<T> *)target)->clear();
     409        4700 : }), reserve_fn([] (void *target, size_t s) {
     410        1450 :         ((mem_pool::Vector<T> *)target)->reserve(s);
     411        1800 : }), resize_fn([] (void *target, size_t s) {
     412           0 :         ((mem_pool::Vector<T> *)target)->resize(s);
     413        1800 : }) { }
     414             : 
     415             : }
     416             : 
     417             : #endif
     418             : 
     419             : #endif /* STAPPLER_CORE_SPMEMORY_H_ */

Generated by: LCOV version 1.14