Skip to content

Commit 6c57a1f

Browse files
authored
Merge pull request #385 from MrAnno/dict-list
filterx: native dict/list types
2 parents bc98567 + d709125 commit 6c57a1f

20 files changed

+1383
-1
lines changed

lib/CMakeLists.txt

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ add_subdirectory(secret-storage)
3838
add_subdirectory(logthrsource)
3939
add_subdirectory(logthrdest)
4040
add_subdirectory(signal-slot-connector)
41+
add_subdirectory(adt)
4142

4243
set(LIB_SUBDIR_HEADERS
4344
${ACK_TRACKER_HEADERS}
@@ -66,6 +67,7 @@ set(LIB_SUBDIR_HEADERS
6667
${LOGTHRDEST_HEADERS}
6768
${LOGTHRSOURCE_HEADERS}
6869
${SIGNAL_SLOT_CONNECTOR_HEADERS}
70+
${ADT_HEADERS}
6971
${CMAKE_CURRENT_BINARY_DIR}/filter/filter-expr-grammar.h
7072
${CMAKE_CURRENT_BINARY_DIR}/filterx/filterx-grammar.h
7173
${CMAKE_CURRENT_BINARY_DIR}/rewrite/rewrite-expr-grammar.h
@@ -284,6 +286,7 @@ set(LIB_SOURCES
284286
${LOGTHRDEST_SOURCES}
285287
${LOGTHRSOURCE_SOURCES}
286288
${SIGNAL_SLOT_CONNECTOR_SOURCES}
289+
${ADT_SOURCES}
287290
${PROJECT_BINARY_DIR}/lib/cfg-grammar.c
288291
${PROJECT_BINARY_DIR}/lib/block-ref-grammar.c
289292
${PROJECT_BINARY_DIR}/lib/cfg-lex.c
@@ -435,6 +438,7 @@ install(FILES ${CSV_SCANNER_HEADERS} DESTINATION include/syslog-ng/scanner/csv-s
435438
install(FILES ${LOGTHRDEST_HEADERS} DESTINATION include/syslog-ng/logthrdest)
436439
install(FILES ${LOGTHRSOURCE_HEADERS} DESTINATION include/syslog-ng/logthrsource)
437440
install(FILES ${SIGNAL_SLOT_CONNECTOR_HEADERS} DESTINATION include/syslog-ng/signal-slot-connector)
441+
install(FILES ${ADT_HEADERS} DESTINATION include/syslog-ng/adt)
438442

439443
set(TOOLS
440444
merge-grammar.py

lib/Makefile.am

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,7 @@ include lib/logthrsource/Makefile.am
2929
include lib/logthrdest/Makefile.am
3030
include lib/signal-slot-connector/Makefile.am
3131
include lib/multi-line/Makefile.am
32+
include lib/adt/Makefile.am
3233

3334
LSNG_RELEASE = $(shell echo @PACKAGE_VERSION@ | cut -d. -f1,2)
3435

@@ -307,7 +308,8 @@ lib_libsyslog_ng_la_SOURCES = \
307308
$(multiline_sources) \
308309
$(logthrsource_sources) \
309310
$(logthrdest_sources) \
310-
$(signal_slot_connector_sources)
311+
$(signal_slot_connector_sources) \
312+
$(adt_sources)
311313

312314
lib_libsyslog_ng_la_CFLAGS = \
313315
$(AM_CFLAGS) \

lib/adt/CMakeLists.txt

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
set(ADT_HEADERS
2+
adt/iord_map.h
3+
adt/ilist.h
4+
PARENT_SCOPE)
5+
6+
set(ADT_SOURCES
7+
adt/iord_map.c
8+
PARENT_SCOPE)
9+
10+
add_subdirectory(tests)

lib/adt/Makefile.am

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
adtincludedir = ${pkgincludedir}/adt
2+
3+
EXTRA_DIST += lib/adt/CMakeLists.txt
4+
5+
adtinclude_HEADERS = \
6+
lib/adt/iord_map.h \
7+
lib/adt/ilist.h
8+
9+
adt_sources = \
10+
lib/adt/iord_map.c
11+
12+
include lib/adt/tests/Makefile.am

lib/adt/ilist.h

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,86 @@
1+
/*
2+
* Copyright (c) 2024 Axoflow
3+
* Copyright (c) 2024 László Várady
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*
19+
* As an additional exemption you are allowed to compile & link against the
20+
* OpenSSL libraries as published by the OpenSSL project. See the file
21+
* COPYING for details.
22+
*
23+
*/
24+
25+
#ifndef ADT_ILIST
26+
#define ADT_ILIST
27+
28+
#include <stddef.h>
29+
#include <iv_list.h>
30+
31+
/*
32+
* Intrusive list (just a wrapper around iv_list for easier use)
33+
*/
34+
35+
typedef struct iv_list_head IList;
36+
typedef struct iv_list_head IListNode;
37+
38+
#define ilist_init(self) INIT_IV_LIST_HEAD(self)
39+
#define ilist_push_back(self, node) iv_list_add_tail(node, self)
40+
#define ilist_push_front(self, node) iv_list_add(node, self)
41+
#define ilist_splice_back(self, list) iv_list_splice_tail(list, self)
42+
#define ilist_splice_front(self, list) iv_list_splice(list, self)
43+
#define ilist_remove(node) iv_list_del(node)
44+
#define ilist_is_empty(self) iv_list_empty(self)
45+
#define ilist_foreach(self, current, next) iv_list_for_each_safe(current, next, self)
46+
#define ilist_entry(self, type, member) iv_list_entry(self, type, member)
47+
48+
static inline IList *
49+
ilist_pop_back(IList *self)
50+
{
51+
IList *e = self->prev;
52+
iv_list_del(e);
53+
return e;
54+
}
55+
56+
static inline IList *
57+
ilist_pop_front(IList *self)
58+
{
59+
IList *e = self->next;
60+
iv_list_del(e);
61+
return e;
62+
}
63+
64+
static inline void
65+
_ilist_reverse_node_links(IList *node)
66+
{
67+
IList *orig_next = node->next;
68+
node->next = node->prev;
69+
node->prev = orig_next;
70+
}
71+
72+
static inline void
73+
ilist_reverse(IList *self)
74+
{
75+
IList *current = self->next;
76+
77+
while (current != self)
78+
{
79+
_ilist_reverse_node_links(current);
80+
current = current->prev;
81+
}
82+
83+
_ilist_reverse_node_links(self);
84+
}
85+
86+
#endif

lib/adt/iord_map.c

Lines changed: 204 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,204 @@
1+
/*
2+
* Copyright (c) 2024 Axoflow
3+
* Copyright (c) 2024 László Várady
4+
*
5+
* This library is free software; you can redistribute it and/or
6+
* modify it under the terms of the GNU Lesser General Public
7+
* License as published by the Free Software Foundation; either
8+
* version 2.1 of the License, or (at your option) any later version.
9+
*
10+
* This library is distributed in the hope that it will be useful,
11+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
12+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13+
* Lesser General Public License for more details.
14+
*
15+
* You should have received a copy of the GNU Lesser General Public
16+
* License along with this library; if not, write to the Free Software
17+
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18+
*
19+
* As an additional exemption you are allowed to compile & link against the
20+
* OpenSSL libraries as published by the OpenSSL project. See the file
21+
* COPYING for details.
22+
*
23+
*/
24+
25+
#include "iord_map.h"
26+
27+
#define iord_map_node_container_of(node, offset) ((guint8 *) (node) - (intptr_t) (offset))
28+
#define iord_map_node_from_container(container, offset) ((IOrdMapNode *) ((guint8 *) (container) + (intptr_t) (offset)))
29+
30+
31+
void
32+
iord_map_init(IOrdMap *self, GHashFunc hash_func, GEqualFunc key_equal_func,
33+
guint16 key_container_offset, guint16 value_container_offset)
34+
{
35+
iord_map_init_full(self, hash_func, key_equal_func, NULL, key_container_offset, NULL, value_container_offset);
36+
}
37+
38+
void
39+
iord_map_init_full(IOrdMap *self, GHashFunc hash_func, GEqualFunc key_equal_func,
40+
GDestroyNotify key_destroy_func, guint16 key_container_offset,
41+
GDestroyNotify value_destroy_func, guint16 value_container_offset)
42+
{
43+
self->ht = g_hash_table_new_full(hash_func, key_equal_func, key_destroy_func, value_destroy_func);
44+
iord_map_node_init(&self->keys);
45+
iord_map_node_init(&self->values);
46+
self->key_destroy_func = key_destroy_func;
47+
self->key_container_offset = key_container_offset;
48+
self->value_destroy_func = value_destroy_func;
49+
self->value_container_offset = value_container_offset;
50+
}
51+
52+
void
53+
iord_map_destroy(IOrdMap *self)
54+
{
55+
g_hash_table_destroy(self->ht);
56+
}
57+
58+
IOrdMap *
59+
iord_map_new(GHashFunc hash_func, GEqualFunc key_equal_func,
60+
guint16 key_container_offset, guint16 value_container_offset)
61+
{
62+
return iord_map_new_full(hash_func, key_equal_func, NULL, key_container_offset, NULL, value_container_offset);
63+
}
64+
65+
IOrdMap *
66+
iord_map_new_full(GHashFunc hash_func, GEqualFunc key_equal_func,
67+
GDestroyNotify key_destroy_func, guint16 key_container_offset,
68+
GDestroyNotify value_destroy_func, guint16 value_container_offset)
69+
{
70+
IOrdMap *self = g_new0(IOrdMap, 1);
71+
72+
iord_map_init_full(self, hash_func, key_equal_func, key_destroy_func, key_container_offset,
73+
value_destroy_func, value_container_offset);
74+
75+
return self;
76+
}
77+
78+
void
79+
iord_map_free(IOrdMap *self)
80+
{
81+
iord_map_destroy(self);
82+
g_free(self);
83+
}
84+
85+
gboolean
86+
iord_map_contains(IOrdMap *self, gconstpointer key)
87+
{
88+
return g_hash_table_contains(self->ht, key);
89+
}
90+
91+
gboolean
92+
iord_map_foreach(IOrdMap *self, IOrdMapForeachFunc func, gpointer user_data)
93+
{
94+
for (struct iv_list_head *key = self->keys.next, *value = self->values.next;
95+
key != &self->keys;
96+
key = key->next, value = value->next)
97+
{
98+
gpointer key_container = iord_map_node_container_of(key, self->key_container_offset);
99+
gpointer value_container = iord_map_node_container_of(value, self->value_container_offset);
100+
if (!func(key_container, value_container, user_data))
101+
return FALSE;
102+
}
103+
104+
return TRUE;
105+
}
106+
107+
gboolean
108+
iord_map_insert(IOrdMap *self, gpointer key, gpointer value)
109+
{
110+
IOrdMapNode *key_node = iord_map_node_from_container(key, self->key_container_offset);
111+
g_assert(!key_node->next || iv_list_empty(key_node));
112+
113+
gpointer orig_key, old_value;
114+
if (!g_hash_table_lookup_extended(self->ht, key, &orig_key, &old_value))
115+
{
116+
iv_list_add_tail(key_node, &self->keys);
117+
goto finish;
118+
}
119+
120+
iv_list_del(iord_map_node_from_container(orig_key, self->key_container_offset));
121+
iv_list_del(iord_map_node_from_container(old_value, self->value_container_offset));
122+
123+
/* keeps the original key */
124+
iv_list_add_tail(iord_map_node_from_container(orig_key, self->key_container_offset), &self->keys);
125+
126+
finish:
127+
iv_list_add_tail(iord_map_node_from_container(value, self->value_container_offset), &self->values);
128+
return g_hash_table_insert(self->ht, key, value);
129+
}
130+
131+
gboolean
132+
iord_map_prepend(IOrdMap *self, gpointer key, gpointer value)
133+
{
134+
IOrdMapNode *key_node = iord_map_node_from_container(key, self->key_container_offset);
135+
g_assert(!key_node->next || iv_list_empty(key_node));
136+
137+
gpointer orig_key, old_value;
138+
if (!g_hash_table_lookup_extended(self->ht, key, &orig_key, &old_value))
139+
{
140+
iv_list_add(key_node, &self->keys);
141+
goto finish;
142+
}
143+
144+
iv_list_del(iord_map_node_from_container(orig_key, self->key_container_offset));
145+
iv_list_del(iord_map_node_from_container(old_value, self->value_container_offset));
146+
147+
/* keeps the original key */
148+
iv_list_add(iord_map_node_from_container(orig_key, self->key_container_offset), &self->keys);
149+
150+
finish:
151+
iv_list_add(iord_map_node_from_container(value, self->value_container_offset), &self->values);
152+
return g_hash_table_insert(self->ht, key, value);
153+
}
154+
155+
gpointer
156+
iord_map_lookup(IOrdMap *self, gconstpointer key)
157+
{
158+
return g_hash_table_lookup(self->ht, key);
159+
}
160+
161+
gboolean
162+
iord_map_remove(IOrdMap *self, gconstpointer key)
163+
{
164+
gpointer key_to_delete, value_to_delete;
165+
if (!g_hash_table_steal_extended(self->ht, key, &key_to_delete, &value_to_delete))
166+
return FALSE;
167+
168+
iv_list_del(iord_map_node_from_container(key_to_delete, self->key_container_offset));
169+
iv_list_del(iord_map_node_from_container(value_to_delete, self->value_container_offset));
170+
171+
if (self->key_destroy_func)
172+
self->key_destroy_func(key_to_delete);
173+
174+
if (self->value_destroy_func)
175+
self->value_destroy_func(value_to_delete);
176+
177+
return TRUE;
178+
}
179+
180+
void
181+
iord_map_clear(IOrdMap *self)
182+
{
183+
g_hash_table_remove_all(self->ht);
184+
iord_map_node_init(&self->keys);
185+
iord_map_node_init(&self->values);
186+
}
187+
188+
gsize
189+
iord_map_size(IOrdMap *self)
190+
{
191+
return g_hash_table_size(self->ht);
192+
}
193+
194+
IOrdMapNode *
195+
iord_map_get_keys(IOrdMap *self)
196+
{
197+
return &self->keys;
198+
}
199+
200+
IOrdMapNode *
201+
iord_map_get_values(IOrdMap *self)
202+
{
203+
return &self->values;
204+
}

0 commit comments

Comments
 (0)