-
Notifications
You must be signed in to change notification settings - Fork 0
/
DataPoolApp.cpp
172 lines (136 loc) · 4.58 KB
/
DataPoolApp.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
#include "IndexHolder.h"
#include "MutexIndexer.h"
#include "ConcurrentIndexer.h"
#include <Pool.h>
#include <string>
#include <iostream>
#include <array>
#include <algorithm>
#include <iterator>
#include <memory>
#include <vector>
template<size_t BufferSize>
class StaticBuffer {
private:
std::array<char, BufferSize> buffer{};
size_t position{0};
public:
StaticBuffer() = default;
StaticBuffer(const StaticBuffer &) = delete;
auto operator=(const StaticBuffer &) -> StaticBuffer & = delete;
auto operator=(StaticBuffer &&) -> StaticBuffer & = delete;
StaticBuffer(StaticBuffer &&) = delete;
auto Add(char cData) -> void {
this->buffer.at(this->position) = cData;
this->position++;
}
auto Get(size_t pos) const -> char {
return this->buffer.at(pos);
}
auto Size() const -> size_t {
return this->position;
}
auto Reset() -> void {
// here we would reset values of StaticBufferPool::buffer as needed. I'll chose to set all values to zero
// and reset the position
std::fill(this->buffer.begin(), this->buffer.end(), 0);
this->position = 0;
}
~StaticBuffer() = default;
};
class DynamicBuffer {
private:
std::vector<char> buffer;
public:
DynamicBuffer() {
const size_t dynamicBufferSize = 64;
std::fill_n(std::back_inserter(this->buffer), dynamicBufferSize, 0);
}
DynamicBuffer(const DynamicBuffer &) = default;
DynamicBuffer(DynamicBuffer &&) = default;
auto operator=(const DynamicBuffer &) -> DynamicBuffer & = default;
auto operator=(DynamicBuffer &&) -> DynamicBuffer & = default;
~DynamicBuffer() = default;
};
/**
* Simple example using a custom pooled buffer, backed by an std::array.
*/
auto selectEvenNumbersStaticPool(const std::vector<char>& numbers) -> void {
// number of items in the pool
const size_t poolSize = 8;
// length of the buffer each item in the pool will hold
const size_t bufferSize = 64;
// StaticBuffer is not copy or move constructible and contains an std::array,
// forcing us to use use a dxpool::StaticPool with compile time size
dxpool::StaticPool<StaticBuffer<bufferSize>, poolSize, dxpool::MutexIndexer> pool;
auto item = pool.Take();
if(!item.Empty()) {
// do something useful with the buffer
StaticBuffer<bufferSize>* buffer = item.Get();
for(const auto cData: numbers) {
if (cData % 2 == 0) {
buffer->Add(cData);
}
}
for(size_t pos = 0 ; pos < buffer->Size() ; pos++) {
std::cout << buffer->Get(pos) << " ";
}
std::cout << std::endl;
}
// item will be returned to the pool here via RAII
}
/**
* Simple example using a custom pooled buffer, backed by an std::vector.
*/
auto exampleRuntimePool() -> void {
// number of items in the pool
size_t poolSize = 2;
// DynamicBuffer is move constructible so it can be used wither with
// a dxpool::StaticPool or dxpool::RuntimePool where poolSize can be determined at run time
dxpool::RuntimePool<DynamicBuffer, dxpool::MutexIndexer> pool(poolSize);
auto item = pool.Take();
if(!item.Empty()) {
// do something useful with the buffer
DynamicBuffer* buffer = item.Get();
(void)buffer;
}
// item will be returned to the pool here via RAII
}
/**
* Example using a type without requiring a wrapper implementation to reset its state
*/
auto exampleCustomReseter() -> void {
auto stringReseter = [](std::string* value) {
value->assign("");
};
dxpool::RuntimePool<std::string> pool(1, stringReseter);
{
auto item = pool.Take();
if(!item.Empty()) {
std::string* value = item.Get();
value->assign("hello");
std::cout << "string item before reset is: '" << *value << "'" << std::endl;
}
// item is returnd to the pool and reset here
}
auto item = pool.Take();
std::cout << "string item after reset is: '" << *item.Get() << "'" << std::endl;
}
/**
* Example using a type without reseter and with a concurrent indexer
*/
auto exampleNoReseterConcurrentIndexer() -> void {
// pool of ints without a custom reseter. It will use a no-op reseter
dxpool::StaticPool<int, 1, dxpool::ConcurrentIndexer> pool;
auto item = pool.Take();
if(!item.Empty()) {
// act on item
}
}
auto main() -> int {
selectEvenNumbersStaticPool({'a','b','c','d'});
exampleRuntimePool();
exampleCustomReseter();
exampleNoReseterConcurrentIndexer();
return 0;
}