IPPL API Reference
Independent Parallel Particle Layer C++ API
Loading...
Searching...
No Matches
BufferHandler.hpp
1#ifndef IPPL_BUFFER_HANDLER_HPP
2#define IPPL_BUFFER_HANDLER_HPP
3
4namespace ippl {
5
6 template <typename MemorySpace>
7 DefaultBufferHandler<MemorySpace>::~DefaultBufferHandler() {}
8
9 template <typename MemorySpace>
10 typename DefaultBufferHandler<MemorySpace>::buffer_type
11 DefaultBufferHandler<MemorySpace>::getBuffer(size_type size, double overallocation) {
12 size_type requiredSize = static_cast<size_type>(size * overallocation);
13
14 auto freeBuffer = findFreeBuffer(requiredSize);
15 if (freeBuffer != nullptr) {
16 return getFreeBuffer(freeBuffer);
17 }
18
19 if (!free_buffers.empty()) {
20 return reallocateLargestFreeBuffer(requiredSize);
21 }
22
23 return allocateNewBuffer(requiredSize);
24 }
25
26 template <typename MemorySpace>
28 if (isBufferUsed(buffer)) {
29 releaseUsedBuffer(buffer);
30 }
31 }
32
33 template <typename MemorySpace>
35 free_buffers.insert(used_buffers.begin(), used_buffers.end());
36 used_buffers.clear();
37
38 freeSize_m += usedSize_m;
39 usedSize_m = 0;
40 }
41
42 template <typename MemorySpace>
44 freeSize_m = 0;
45 usedSize_m = 0;
46
47 used_buffers.clear();
48 free_buffers.clear();
49 }
50
51 template <typename MemorySpace>
52 typename DefaultBufferHandler<MemorySpace>::size_type
54 return usedSize_m;
55 }
56
57 template <typename MemorySpace>
58 typename DefaultBufferHandler<MemorySpace>::size_type
60 return freeSize_m;
61 }
62
63 template <typename MemorySpace>
65 const buffer_type& rhs) {
66 if (lhs->getBufferSize() != rhs->getBufferSize()) {
67 return lhs->getBufferSize() < rhs->getBufferSize();
68 }
69
70 // Use memory address as a tie-breaker to enforce total ordering of buffers.
71 return lhs < rhs;
72 }
73
74 template <typename MemorySpace>
75 bool DefaultBufferHandler<MemorySpace>::isBufferUsed(buffer_type buffer) const {
76 return used_buffers.find(buffer) != used_buffers.end();
77 }
78
79 template <typename MemorySpace>
80 void DefaultBufferHandler<MemorySpace>::releaseUsedBuffer(buffer_type buffer) {
81 auto it = used_buffers.find(buffer);
82
83 usedSize_m -= buffer->getBufferSize();
84 freeSize_m += buffer->getBufferSize();
85
86 used_buffers.erase(it);
87 free_buffers.insert(buffer);
88 }
89
90 template <typename MemorySpace>
91 typename DefaultBufferHandler<MemorySpace>::buffer_type
92 DefaultBufferHandler<MemorySpace>::findFreeBuffer(size_type requiredSize) {
93 auto it = findSmallestSufficientBuffer(requiredSize);
94 if (it != free_buffers.end()) {
95 return *it;
96 }
97 return nullptr;
98 }
99
100 template <typename MemorySpace>
101 typename DefaultBufferHandler<MemorySpace>::buffer_set_type::iterator
102 DefaultBufferHandler<MemorySpace>::findSmallestSufficientBuffer(size_type requiredSize) {
103 return std::find_if(free_buffers.begin(), free_buffers.end(),
104 [requiredSize](const buffer_type& buffer) {
105 return buffer->getBufferSize() >= requiredSize;
106 });
107 }
108
109 template <typename MemorySpace>
110 typename DefaultBufferHandler<MemorySpace>::buffer_type
111 DefaultBufferHandler<MemorySpace>::getFreeBuffer(buffer_type buffer) {
112 freeSize_m -= buffer->getBufferSize();
113 usedSize_m += buffer->getBufferSize();
114
115 free_buffers.erase(buffer);
116 used_buffers.insert(buffer);
117 return buffer;
118 }
119
120 template <typename MemorySpace>
121 typename DefaultBufferHandler<MemorySpace>::buffer_type
122 DefaultBufferHandler<MemorySpace>::reallocateLargestFreeBuffer(size_type requiredSize) {
123 auto largest_it = std::prev(free_buffers.end());
124 buffer_type buffer = *largest_it;
125
126 freeSize_m -= buffer->getBufferSize();
127 usedSize_m += requiredSize;
128
129 free_buffers.erase(buffer);
130 buffer->reallocBuffer(requiredSize);
131
132 used_buffers.insert(buffer);
133 return buffer;
134 }
135
136 template <typename MemorySpace>
137 typename DefaultBufferHandler<MemorySpace>::buffer_type
138 DefaultBufferHandler<MemorySpace>::allocateNewBuffer(size_type requiredSize) {
139 buffer_type newBuffer = std::make_shared<archive_type>(requiredSize);
140
141 usedSize_m += newBuffer->getBufferSize();
142 used_buffers.insert(newBuffer);
143 return newBuffer;
144 }
145
146} // namespace ippl
147
148#endif
Concrete implementation of BufferHandler for managing memory buffers.
Definition BufferHandler.h:95
size_type getUsedSize() const override
Gets the size of all buffers in use.
Definition BufferHandler.hpp:53
void deleteAllBuffers() override
Deletes all buffers.
Definition BufferHandler.hpp:43
void freeBuffer(buffer_type buffer) override
Frees a specified buffer.
Definition BufferHandler.hpp:27
buffer_type getBuffer(size_type size, double overallocation) override
Acquires a buffer of at least the specified size.
Definition BufferHandler.hpp:11
void freeAllBuffers() override
Frees all currently used buffers.
Definition BufferHandler.hpp:34
size_type getFreeSize() const override
Gets the size of all free buffers.
Definition BufferHandler.hpp:59
Definition Archive.h:20