OSSIA
Open Scenario System for Interactive Application
buffer_pool.hpp
1 #pragma once
2 #include <ossia/detail/pod_vector.hpp>
3 #include <ossia/detail/lockfree_queue.hpp>
4 
5 namespace ossia
6 {
7 template <typename Obj_T>
8 struct object_pool
9 {
10  mpmc_queue<Obj_T> buffers;
11 
12  Obj_T acquire()
13  {
14  Obj_T b;
15  buffers.try_dequeue(b);
16  return b;
17  }
18 
19  void release(Obj_T b) { buffers.enqueue(std::move(b)); }
20 };
21 
22 // TODO categorized_object_pool with more generic user-defined categorization ?
23 
24 // given
25 // std::integer_sequence<int, 10, 100, 1000>;
26 // queues[0]: size € [0 , 9]
27 // queues[1]: size € [10, 99]
28 // queues[2]: size € [100, 999]
29 // queues[3]: size € [1000, +oo[
30 
31 template <typename Obj_T, typename Alloc, std::size_t... sz>
32 struct sized_object_pool
33 {
34  using SizeSpec = std::integer_sequence<std::size_t, sz...>;
35 
36  static const constexpr auto buckets = SizeSpec::size() + 1;
37  std::array<mpmc_queue<Obj_T>, buckets> queues;
38 
39  template <std::size_t Sz, std::size_t... Szs>
40  static constexpr int find_bucket_impl(std::size_t size, std::size_t k) noexcept
41  {
42  if(size < Sz)
43  return k;
44  else if constexpr(sizeof...(Szs) > 0)
45  return find_bucket_impl<Szs...>(size, k + 1);
46  else
47  return k + 1;
48  }
49 
50  static constexpr int find_bucket(std::size_t size) noexcept
51  {
52  return find_bucket_impl<sz...>(size, 0);
53  }
54 
55  Obj_T acquire_sized(std::size_t req_size = 1024) noexcept
56  {
57  Obj_T b;
58  if(!queues[find_bucket(req_size)].try_dequeue(b))
59  {
60  Alloc::resize(b, req_size);
61  }
62  return b;
63  }
64 
65  Obj_T acquire_reserved(std::size_t req_size = 1024) noexcept
66  {
67  Obj_T b;
68  if(!queues[find_bucket(req_size)].try_dequeue(b))
69  {
70  Alloc::reserve(b, req_size);
71  }
72  return b;
73  }
74 
75  void release(Obj_T b) noexcept
76  {
77  queues[find_bucket(Alloc::size(b))].enqueue(std::move(b));
78  }
79 
80  static sized_object_pool& instance() noexcept
81  {
82  static sized_object_pool p;
83  return p;
84  }
85 };
86 
87 template <typename T>
88 struct container_memory_manager
89 {
90  static constexpr void resize(T& t, std::size_t sz) noexcept { t.resize(sz); }
91  static constexpr void reserve(T& t, std::size_t sz) noexcept { t.reserve(sz); }
92  static constexpr std::size_t size(const T& t) noexcept { return t.size(); }
93 };
94 
95 struct buffer_pool
96 {
97  using buffer = ossia::pod_vector<char>;
98 
99  mpmc_queue<buffer> buffers;
100 
101  buffer acquire(std::size_t req_size = 1024)
102  {
103  buffer b;
104 
105  buffers.try_dequeue(b);
106  b.resize(req_size, boost::container::default_init);
107  return b;
108  }
109 
110  void release(buffer b)
111  {
112  b.clear();
113  buffers.enqueue(std::move(b));
114  }
115 
116  static buffer_pool& instance()
117  {
118  static buffer_pool p;
119  return p;
120  }
121 };
122 
123 }
Definition: git_info.h:7