Skip to content

Commit a092af2

Browse files
Lukas HutakLukas955
authored andcommitted
fdsdump: storageSorted: define component
1 parent b413b11 commit a092af2

File tree

2 files changed

+121
-0
lines changed

2 files changed

+121
-0
lines changed
Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
2+
#include <cassert>
3+
#include <iterator>
4+
5+
#include "storageSorted.hpp"
6+
7+
StorageSorted::StorageSorted(StorageSorter sorter, size_t capacity)
8+
: m_sorter{sorter}, m_records{m_sorter}, m_capacity{capacity}
9+
{
10+
}
11+
12+
void
13+
StorageSorted::insert(struct Flow *flow)
14+
{
15+
const enum Direction dir_backup = flow->dir;
16+
17+
if ((dir_backup & DIRECTION_FWD) != 0) {
18+
flow->dir = DIRECTION_FWD;
19+
insert_single_direction(flow);
20+
}
21+
22+
if ((dir_backup & DIRECTION_REV) != 0) {
23+
flow->dir = DIRECTION_REV;
24+
insert_single_direction(flow);
25+
}
26+
27+
flow->dir = dir_backup;
28+
}
29+
30+
void
31+
StorageSorted::insert_single_direction(struct Flow *flow)
32+
{
33+
// Exactly single direction must be specified
34+
assert(flow->dir == DIRECTION_FWD || flow->dir == DIRECTION_REV);
35+
36+
if (m_capacity == 0 || m_records.size() < m_capacity) {
37+
insert_storage_record(flow);
38+
return;
39+
}
40+
41+
const auto last_iter = std::prev(m_records.end());
42+
const Flow &last_rec = last_iter->get_flow_const();
43+
44+
if (!m_sorter(*flow, last_rec)) {
45+
// Don't insert the record as it should be placed after the last one
46+
return;
47+
}
48+
49+
m_records.erase(last_iter);
50+
insert_storage_record(flow);
51+
}
52+
53+
void
54+
StorageSorted::insert_storage_record(struct Flow *flow)
55+
{
56+
shared_tsnapshot snapshot{
57+
fds_tsnapshot_deep_copy(flow->rec.snap),
58+
&fds_tsnapshot_destroy};
59+
60+
if (!snapshot) {
61+
throw std::runtime_error("fds_tsnapshot_deep_copy() has failed");
62+
}
63+
64+
m_records.emplace(flow->rec, flow->dir, snapshot);
65+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
2+
#pragma once
3+
4+
#include <set>
5+
6+
#include "storageRecord.hpp"
7+
#include "storageSorter.hpp"
8+
9+
/**
10+
* @brief Sorted storage of flow records
11+
*/
12+
class StorageSorted {
13+
public:
14+
using Storage = std::multiset<StorageRecord, StorageSorter>;
15+
16+
/**
17+
* @brief Create a storage for Flow Data records where the records are
18+
* sorted based on the @p sorter.
19+
*
20+
* @param[in] sorter Sorter of Flow Record
21+
* @param[in] capacity Maximal capacity of the storage. If zero, the
22+
* storage capacity is not limited.
23+
*/
24+
StorageSorted(StorageSorter sorter, size_t capacity = 0);
25+
26+
/**
27+
* @brief Insert a Flow Data record to the storage and place it based
28+
* on the order given by the sorter.
29+
*
30+
* If the capacity has been reached and the new record would be placed
31+
* (based on the sorter) after the last record in the storage, no action
32+
* is performed.
33+
*
34+
* @param[in] flow Flow Data record to be stored
35+
*/
36+
void insert(struct Flow *flow);
37+
38+
/**
39+
* @brief Get an iterator to the first element of the storage.
40+
* @return Constant iterator
41+
*/
42+
Storage::iterator begin() const { return m_records.begin(); };
43+
/**
44+
* @brief Get an iterator to the element following the last element the storage.
45+
* @return Constant iterator
46+
*/
47+
Storage::iterator end() const { return m_records.end(); };
48+
49+
private:
50+
StorageSorter m_sorter;
51+
Storage m_records;
52+
size_t m_capacity;
53+
54+
void insert_single_direction(struct Flow *flow);
55+
void insert_storage_record(struct Flow *flow);
56+
};

0 commit comments

Comments
 (0)