Skip to content

Commit c16607d

Browse files
AdamZvarasedmicha
authored andcommitted
Modifier: add optimization
1 parent 09410c4 commit c16607d

File tree

3 files changed

+123
-60
lines changed

3 files changed

+123
-60
lines changed

src/core/modifier.c

Lines changed: 46 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -957,9 +957,9 @@ mgr_store_template(ipx_modifier_t *mod, struct fds_template *tmplt, fds_tgarbage
957957
* \brief Add template to mapper, print error line if failed
958958
*/
959959
static inline void
960-
mapper_add_template(ipx_modifier_t *mod, const struct fds_template *tmplt, uint16_t original_id)
960+
mapper_add_template(ipx_modifier_t *mod, const struct fds_template *tmplt, struct modified_tmplt_id *item, uint16_t original_id)
961961
{
962-
if (ipx_mapper_add(mod->curr_ctx->mapper, tmplt, original_id) != IPX_OK) {
962+
if (ipx_mapper_add(mod->curr_ctx->mapper, tmplt, item, original_id) != IPX_OK) {
963963
// Could not add mapping
964964
MODIFIER_WARNING(mod, "Could not add mapping for template ID %u (ODID: %d)",
965965
original_id, mod->curr_ctx->odid);
@@ -1006,8 +1006,8 @@ aux_template_store_garbage_destroy(struct aux_template_store_garbage *gb)
10061006
* \param[out] garbage Potential garbage from modifier context
10071007
* \return Pointer to stored template or NULL if error occurred
10081008
*/
1009-
static const struct fds_template *
1010-
template_store(ipx_modifier_t *mod, struct fds_template *tmplt, uint16_t original_id, ipx_msg_garbage_t **garbage)
1009+
static struct fds_template *
1010+
template_store(ipx_modifier_t *mod, struct fds_template *tmplt, uint16_t original_id, ipx_msg_garbage_t **garbage, struct modified_tmplt_id *item)
10111011
{
10121012
int rc;
10131013
fds_tgarbage_t *mapper_garbage = NULL;
@@ -1029,7 +1029,9 @@ template_store(ipx_modifier_t *mod, struct fds_template *tmplt, uint16_t origina
10291029

10301030
if (mgr_tmplt) {
10311031
// Template exists in manager, add mapping
1032-
mapper_add_template(mod, mgr_tmplt, original_id);
1032+
mapper_add_template(mod, mgr_tmplt, item, original_id);
1033+
// Destroy modified template
1034+
fds_template_destroy(tmplt);
10331035
return mgr_tmplt;
10341036
}
10351037

@@ -1041,10 +1043,12 @@ template_store(ipx_modifier_t *mod, struct fds_template *tmplt, uint16_t origina
10411043
}
10421044

10431045
// Add new mapping
1044-
mapper_add_template(mod, tmplt, original_id);
1046+
mapper_add_template(mod, tmplt, item, original_id);
10451047

10461048
// If any garbage was generated, create garbage message from it
10471049
if (mapper_garbage || context_garbage) {
1050+
// Clear mapper
1051+
ipx_mapper_clear(mod->curr_ctx->mapper);
10481052
struct aux_template_store_garbage *gb = malloc(sizeof(*gb));
10491053
if (gb == NULL) {
10501054
MODIFIER_ERROR(mod, "Memory allocation failed (%s:%d)", __FILE__, __LINE__);
@@ -1119,6 +1123,26 @@ fields_update(struct fds_drec *rec, ipx_modifier_t *mod, struct ipx_modifier_out
11191123
return IPX_OK;
11201124
}
11211125

1126+
static inline void
1127+
output_buffer2id(const struct ipx_modifier_output *output, size_t fields_cnt, struct modified_tmplt_id *id)
1128+
{
1129+
uint8_t appended_fields[fields_cnt];
1130+
1131+
/** Convert fields to array, which will be stored in modified_tmplt_id*/
1132+
for (uint16_t i = 0; i < fields_cnt; ++i) {
1133+
if (output[i].length >= 0) {
1134+
appended_fields[i] = 1;
1135+
} else if (output[i].length == IPX_MODIFIER_SKIP) {
1136+
appended_fields[i] = 0;
1137+
} else {
1138+
appended_fields[i] = -1;
1139+
}
1140+
}
1141+
1142+
memcpy(id->appended_fields, appended_fields, fields_cnt);
1143+
}
1144+
1145+
11221146
struct fds_drec *
11231147
ipx_modifier_modify(ipx_modifier_t *mod, const struct fds_drec *rec, ipx_msg_garbage_t **garbage)
11241148
{
@@ -1132,6 +1156,7 @@ ipx_modifier_modify(ipx_modifier_t *mod, const struct fds_drec *rec, ipx_msg_gar
11321156
return NULL;
11331157
}
11341158

1159+
struct fds_template *new_tmplt = NULL;
11351160
*garbage = NULL;
11361161

11371162
// Create filter array
@@ -1155,36 +1180,41 @@ ipx_modifier_modify(ipx_modifier_t *mod, const struct fds_drec *rec, ipx_msg_gar
11551180
}
11561181
}
11571182

1158-
// Update template based on modified configuration
1159-
struct fds_template *new_tmplt = template_update(rec->tmplt, mod, buffers, filter);
1160-
if (!new_tmplt) {
1161-
MODIFIER_ERROR(mod, "Failed to update template (%s:%d)", __FILE__, __LINE__);
1162-
return NULL;
1163-
}
1183+
// Create array which will be used to identify modified template
1184+
struct modified_tmplt_id mod_identifier = {0};
1185+
output_buffer2id(buffers, mod->fields_cnt, &mod_identifier);
1186+
mod_identifier.data = rec->tmplt->raw.data;
1187+
mod_identifier.length = rec->tmplt->raw.length;
11641188

11651189
// Try to search for modified template in modifier mapper
1166-
const struct fds_template *map_tmplt = ipx_mapper_lookup(mod->curr_ctx->mapper, new_tmplt, rec->tmplt->id);
1190+
const struct fds_template *map_tmplt = ipx_mapper_lookup(mod->curr_ctx->mapper, &mod_identifier, rec->tmplt->id);
11671191
if (map_tmplt) {
11681192
// Mapping found, free modified template and use template found in mapper
1169-
fds_template_destroy(new_tmplt);
11701193
new_tmplt = (struct fds_template *) map_tmplt;
11711194
} else {
11721195
// Mapping not found, need to store modified template in manager
1173-
const struct fds_template *stored_tmplt = template_store(mod, new_tmplt, rec->tmplt->id, garbage);
1196+
new_tmplt = template_update(rec->tmplt, mod, buffers, filter);
1197+
if (!new_tmplt) {
1198+
MODIFIER_ERROR(mod, "Failed to update template (%s:%d)", __FILE__, __LINE__);
1199+
return NULL;
1200+
}
1201+
1202+
struct fds_template *stored_tmplt = template_store(mod, new_tmplt, rec->tmplt->id, garbage, &mod_identifier);
11741203

11751204
if (!stored_tmplt) {
11761205
// Error message has been generated
11771206
fds_template_destroy(new_tmplt);
11781207
return NULL;
11791208
}
1209+
1210+
new_tmplt = stored_tmplt;
11801211
}
11811212

11821213
// Fetch current snapshot
11831214
const fds_tsnapshot_t *snap;
11841215
get_current_snapshot(mod, &snap);
11851216
if (!snap) {
11861217
// Error message has been generated
1187-
// DO NOT free modified template as it is stored in modifier
11881218
return NULL;
11891219
}
11901220

@@ -1201,7 +1231,6 @@ ipx_modifier_modify(ipx_modifier_t *mod, const struct fds_drec *rec, ipx_msg_gar
12011231
if (fields_update(new_rec, mod, buffers, filter) != IPX_OK) {
12021232
MODIFIER_ERROR(mod, "Failed to update fields in record (%s:%d)", __FILE__, __LINE__);
12031233
free(new_rec);
1204-
// DO NOT free modified template, as it is stored in modifier
12051234
return NULL;
12061235
}
12071236

src/core/template_mapper.c

Lines changed: 63 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@
3131

3232
/** \brief Template mapper field */
3333
struct mapper_field {
34+
/** Data used by mapper callbacks */
35+
struct modified_tmplt_id ident;
3436
/** Pointer to modified template */
3537
const struct fds_template *modified_tmplt;
3638
/** Next item in linked list */
@@ -62,9 +64,10 @@ struct template_mapper {
6264
*
6365
* \param[in] field Pointer to mapper field
6466
*/
65-
void
67+
static inline void
6668
mapper_field_destroy(struct mapper_field *field)
6769
{
70+
free(field->ident.data);
6871
free(field);
6972
}
7073

@@ -79,53 +82,57 @@ ipx_mapper_create()
7982
return map;
8083
}
8184

82-
void
83-
ipx_mapper_clear(struct template_mapper *map)
85+
size_t
86+
ipx_mapper_get_tmplt_count(ipx_template_mapper_t *map)
8487
{
88+
return map->template_cnt;
89+
}
90+
91+
typedef void (*mapper_l1_cb)(void *ptr);
92+
93+
static void
94+
mapper_item_cleanup(struct template_mapper *map, mapper_l1_cb l1_cb)
95+
{
96+
// Go through all L1 tables
8597
for (size_t i = 0; i < IPX_MAPPER_L1_RANGE; i++) {
8698
if (map->l1_table[i] == NULL) {
8799
continue;
88100
}
89101

102+
// Go through all L2 tables
90103
for (size_t j = 0; j < IPX_MAPPER_L2_RANGE; j++) {
91-
struct mapper_field *field = map->l1_table[i]->l2_table[j].fields;
104+
struct mapper_field *orig_field = map->l1_table[i]->l2_table[j].fields;
105+
struct mapper_field *field = orig_field;
92106

107+
// Go through all fields in current L2 table
93108
while (field != NULL) {
94109
struct mapper_field *next = field->next;
95110
mapper_field_destroy(field);
96111
field = next;
97112
}
98-
map->l1_table[i]->l2_table[j].fields = NULL;
113+
114+
orig_field = NULL;
115+
}
116+
117+
// Apply callback to L1 table
118+
if (l1_cb != NULL) {
119+
l1_cb(map->l1_table[i]);
99120
}
121+
100122
}
101-
map->template_cnt = 0;
102123
}
103124

104-
size_t
105-
ipx_mapper_get_tmplt_count(ipx_template_mapper_t *map)
125+
void
126+
ipx_mapper_clear(struct template_mapper *map)
106127
{
107-
return map->template_cnt;
128+
mapper_item_cleanup(map, NULL);
129+
map->template_cnt = 0;
108130
}
109131

110132
void
111133
ipx_mapper_destroy(struct template_mapper *map)
112134
{
113-
for (size_t i = 0; i < IPX_MAPPER_L1_RANGE; i++) {
114-
if (map->l1_table[i] == NULL) {
115-
continue;
116-
}
117-
118-
for (size_t j = 0; j < IPX_MAPPER_L2_RANGE; j++) {
119-
struct mapper_field *field = map->l1_table[i]->l2_table[j].fields;
120-
121-
while (field != NULL) {
122-
struct mapper_field *next = field->next;
123-
mapper_field_destroy(field);
124-
field = next;
125-
}
126-
}
127-
free(map->l1_table[i]);
128-
}
135+
mapper_item_cleanup(map, free);
129136
free(map);
130137
}
131138

@@ -210,15 +217,26 @@ mapper_store_field(struct template_mapper *map, uint16_t original_id, struct map
210217
}
211218

212219
int
213-
ipx_mapper_add(ipx_template_mapper_t *map, const struct fds_template *modified_tmplt, uint16_t original_id)
220+
ipx_mapper_add(ipx_template_mapper_t *map, const struct fds_template *modified_tmplt, struct modified_tmplt_id *item, uint16_t original_id)
214221
{
215222
// Create new field
216223
struct mapper_field *new_field = malloc(sizeof(*new_field));
217224
if (new_field == NULL) {
218225
return IPX_ERR_NOMEM;
219226
}
220227

221-
// Store data from identifier to field
228+
new_field->ident.data = malloc(item->length);
229+
if (new_field->ident.data == NULL) {
230+
free(new_field);
231+
return IPX_ERR_NOMEM;
232+
}
233+
234+
235+
new_field->ident.length = item->length;
236+
memcpy(new_field->ident.data, item->data, item->length);
237+
memcpy(new_field->ident.appended_fields, item->appended_fields, APPENDED_FIELDS_DEF_CNT * sizeof(uint8_t));
238+
239+
// Store modifed template in new field
222240
new_field->modified_tmplt = modified_tmplt;
223241

224242
// Store field in mapper
@@ -231,26 +249,30 @@ ipx_mapper_add(ipx_template_mapper_t *map, const struct fds_template *modified_t
231249
return IPX_OK;
232250
}
233251

234-
/**
235-
* \brief Check if identifier describes given field
236-
*
237-
* \param[in] field Field to check
238-
* \param[in] id Identifier to check
239-
* \return IPX_OK if identifier describes given field, IPX_ERR_NOTFOUND otherwise
240-
*/
252+
241253
static inline int
242-
templates_cmp(const struct fds_template *t1, const struct fds_template *t2)
254+
item_cmp(const struct modified_tmplt_id *item1, const struct modified_tmplt_id *item2)
243255
{
244-
if (t1->raw.length != t2->raw.length) {
245-
return (t1->raw.length > t2->raw.length) ? 1 : -1;
256+
// Compare original templates
257+
if (item1->length != item2->length) {
258+
return -1;
246259
}
247260

248261
// Compare raw templates except template ID
249-
return memcmp(t1->raw.data+2, t2->raw.data+2, t1->raw.length-2);
262+
if (memcmp(item1->data+2, item2->data+2, item1->length-2)) {
263+
return -1;
264+
}
265+
266+
// Compare fields
267+
if (memcmp(item1->appended_fields, item2->appended_fields, APPENDED_FIELDS_DEF_CNT)) {
268+
return -1;
269+
}
270+
271+
return IPX_OK;
250272
}
251273

252274
const struct fds_template *
253-
ipx_mapper_lookup(ipx_template_mapper_t *map, const struct fds_template *tmplt, uint16_t original_id)
275+
ipx_mapper_lookup(ipx_template_mapper_t *map, const struct modified_tmplt_id *item, uint16_t original_id)
254276
{
255277
// Get index of L1 table
256278
size_t l1_idx = mapper_get_l1_idx(original_id);
@@ -266,9 +288,10 @@ ipx_mapper_lookup(ipx_template_mapper_t *map, const struct fds_template *tmplt,
266288

267289
struct mapper_field *field = l2_table->fields;
268290
while (field != NULL) {
269-
if (templates_cmp(field->modified_tmplt, tmplt) == IPX_OK) {
291+
if (item_cmp(&field->ident, item) == IPX_OK) {
270292
return field->modified_tmplt;
271293
}
294+
272295
field = field->next;
273296
}
274297
return NULL;

src/core/template_mapper.h

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,20 @@
1111
#include <ipfixcol2.h>
1212
#include <inttypes.h>
1313

14-
/** External definitions of items in mapper */
14+
#define APPENDED_FIELDS_DEF_CNT 32
15+
16+
/** External definitions of items in mapper */
1517
typedef struct template_mapper ipx_template_mapper_t;
1618

19+
struct modified_tmplt_id {
20+
/** Original template info */
21+
uint8_t *data; /**< Original template data */
22+
uint16_t length; /**< Original template size */
23+
24+
/** Array of new fields to append to original template */
25+
int8_t appended_fields[APPENDED_FIELDS_DEF_CNT];
26+
};
27+
1728
/**
1829
* \brief Create new instance of template mapper
1930
*
@@ -56,7 +67,7 @@ ipx_mapper_destroy(ipx_template_mapper_t *map);
5667
* \return #IPX_OK on success, #IPX_ERR_NOMEM on memory allocation error
5768
*/
5869
IPX_API int
59-
ipx_mapper_add(ipx_template_mapper_t *map, const struct fds_template *modified_tmplt, uint16_t original_id);
70+
ipx_mapper_add(ipx_template_mapper_t *map, const struct fds_template *modified_tmplt, struct modified_tmplt_id *item, uint16_t original_id);
6071

6172
/**
6273
* \brief Look for modified template in template mapper
@@ -67,6 +78,6 @@ ipx_mapper_add(ipx_template_mapper_t *map, const struct fds_template *modified_t
6778
* \return Pointer to mapping or NULL if not found
6879
*/
6980
IPX_API const struct fds_template *
70-
ipx_mapper_lookup(ipx_template_mapper_t *map, const struct fds_template *tmplt, uint16_t original_id);
81+
ipx_mapper_lookup(ipx_template_mapper_t *map, const struct modified_tmplt_id *item, uint16_t original_id);
7182

7283
#endif

0 commit comments

Comments
 (0)