Skip to content

Commit 6108697

Browse files
author
Pavel Siska
committed
flowRecordBuilder
1 parent 358dbd4 commit 6108697

File tree

1 file changed

+157
-0
lines changed

1 file changed

+157
-0
lines changed
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
#pragma once
2+
3+
#include "flowKey.hpp"
4+
#include "flowRecord.hpp"
5+
#include "ipAddress.hpp"
6+
#include "processPluginBuilder.hpp"
7+
8+
#include <cstddef>
9+
#include <memory>
10+
#include <mutex>
11+
#include <thread>
12+
#include <type_traits>
13+
#include <vector>
14+
15+
namespace ipxp {
16+
17+
static std::size_t calculatePluginTableSize(const std::vector<ProcessPluginEntry>& plugins) noexcept
18+
{
19+
return sizeof(FlowRecordPluginTable) + ((plugins.size() - 1) * sizeof(PluginLayoutItem));
20+
}
21+
22+
class FlowRecordBuilder {
23+
public:
24+
FlowRecordBuilder(
25+
const std::vector<ProcessPluginEntry>& plugins,
26+
const FlowKeyLayout& flowKeyLayout)
27+
: m_processPluginEntries(plugins)
28+
, m_flowKeyLayout(flowKeyLayout)
29+
{
30+
prepareLayout();
31+
}
32+
33+
std::size_t getTotalBufferSize() const { return m_totalBufferSize; }
34+
std::size_t getMaxAlignment() const { return m_maxAlignment; }
35+
FlowRecordLayout getLayout() const { return m_layout; }
36+
37+
void printLayoutInfo() const
38+
{
39+
std::cout << "FlowKey:\n";
40+
std::cout << " Size: " << m_flowKeyLayout.size << " bytes\n";
41+
std::cout << " Alignment: " << m_flowKeyLayout.alignment << " bytes\n";
42+
std::cout << " Offset: " << m_layout.flowKeyOffset << "\n\n";
43+
44+
std::cout << "Plugin Table:\n";
45+
std::cout << " Offset: " << m_layout.pluginTableOffset << "\n";
46+
std::cout << " Size: " << calculatePluginTableSize(m_processPluginEntries)
47+
<< " bytes\n";
48+
std::cout << " Count: " << m_processPluginEntries.size() << "\n\n";
49+
50+
std::cout << "Plugins (" << m_processPluginEntries.size() << "):\n";
51+
for (std::size_t i = 0; i < m_pluginLayouts.size(); ++i) {
52+
const auto& layout = m_pluginLayouts[i];
53+
if (layout.offset == std::numeric_limits<std::size_t>::max()) {
54+
std::cout << " Plugin " << i << ": disabled\n";
55+
} else {
56+
const auto& pluginEntry = m_processPluginEntries[i];
57+
std::cout << " Plugin " << i << ": " << pluginEntry.name << "\n"; // přidáno jméno
58+
std::cout << " Offset: " << layout.offset << "\n";
59+
std::cout << " Context Size: " << pluginEntry.contextSize << " bytes\n";
60+
std::cout << " Context Alignment: " << pluginEntry.contextAlignment
61+
<< " bytes\n";
62+
}
63+
}
64+
65+
std::cout << "\nTotal FlowRecord size: " << m_totalBufferSize << " bytes\n";
66+
std::cout << "Max alignment: " << m_maxAlignment << " bytes\n";
67+
}
68+
69+
FlowRecordUniquePtr build()
70+
{
71+
// Alokace zarovnané paměti
72+
void* rawMem = ::operator new(m_totalBufferSize, std::align_val_t(m_maxAlignment));
73+
74+
// Konstrukce FlowRecord přímo v alokované paměti (placement new)
75+
FlowRecord* recordPtr
76+
= std::construct_at(static_cast<FlowRecord*>(rawMem), m_pluginsAvailable);
77+
78+
recordPtr->m_layout = m_layout;
79+
80+
// Inicializace pluginové tabulky
81+
FlowRecordPluginTable* pluginTable = reinterpret_cast<FlowRecordPluginTable*>(
82+
reinterpret_cast<std::byte*>(rawMem) + m_layout.pluginTableOffset);
83+
pluginTable->pluginCount = m_pluginLayouts.size();
84+
for (std::size_t i = 0; i < m_pluginLayouts.size(); ++i) {
85+
pluginTable->pluginDataLayouts[i] = m_pluginLayouts[i];
86+
}
87+
88+
return FlowRecordUniquePtr(recordPtr, FlowRecordDeleter {m_maxAlignment});
89+
}
90+
91+
private:
92+
void prepareLayout()
93+
{
94+
constexpr std::size_t baseSize = sizeof(FlowRecord);
95+
m_maxAlignment = alignof(FlowRecord);
96+
97+
std::size_t flowKeyOffset = alignUp(baseSize, m_flowKeyLayout.alignment);
98+
99+
std::size_t pluginTableOffset
100+
= alignUp(flowKeyOffset + m_flowKeyLayout.size, alignof(FlowRecordPluginTable));
101+
102+
std::size_t pluginTableSize = calculatePluginTableSize(m_processPluginEntries);
103+
104+
std::size_t currentOffset = pluginTableOffset + pluginTableSize;
105+
106+
m_maxAlignment = std::max(m_maxAlignment, m_flowKeyLayout.alignment);
107+
m_maxAlignment = std::max(m_maxAlignment, alignof(FlowRecordPluginTable));
108+
109+
m_pluginLayouts.clear();
110+
m_pluginsAvailable.reset();
111+
112+
for (std::size_t pluginID = 0; pluginID < m_processPluginEntries.size(); ++pluginID) {
113+
const auto& pluginEntry = m_processPluginEntries[pluginID];
114+
if (!pluginEntry.enabled) {
115+
m_pluginLayouts.push_back({std::numeric_limits<std::size_t>::max()});
116+
continue;
117+
}
118+
119+
std::size_t alignment = pluginEntry.contextAlignment;
120+
if (alignment > 1) {
121+
std::size_t mod = currentOffset % alignment;
122+
if (mod != 0) {
123+
currentOffset += alignment - mod;
124+
}
125+
}
126+
127+
m_pluginLayouts.push_back({currentOffset});
128+
m_pluginsAvailable.set(pluginID);
129+
130+
currentOffset += pluginEntry.contextSize;
131+
m_maxAlignment = std::max(m_maxAlignment, alignment);
132+
}
133+
134+
m_totalBufferSize = currentOffset;
135+
136+
m_layout.flowKeyOffset = flowKeyOffset;
137+
m_layout.pluginTableOffset = pluginTableOffset;
138+
}
139+
140+
static std::size_t alignUp(std::size_t value, std::size_t alignment)
141+
{
142+
return (value + alignment - 1) & ~(alignment - 1);
143+
}
144+
145+
private:
146+
std::vector<ProcessPluginEntry> m_processPluginEntries;
147+
FlowKeyLayout m_flowKeyLayout;
148+
149+
std::vector<PluginLayoutItem> m_pluginLayouts;
150+
PluginsBitset m_pluginsAvailable = {};
151+
152+
std::size_t m_totalBufferSize = 0;
153+
std::size_t m_maxAlignment = 0;
154+
FlowRecordLayout m_layout;
155+
};
156+
157+
} // namespace ipxp

0 commit comments

Comments
 (0)