NewMadeleine

Documentation

« back to PM2 home.
nm_tags.h
Go to the documentation of this file.
1/*
2 * NewMadeleine
3 * Copyright (C) 2006-2023 (see AUTHORS file)
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation; either version 2 of the License, or (at
8 * your option) any later version.
9 *
10 * This program is distributed in the hope that it will be useful, but
11 * WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * General Public License for more details.
14 */
15
16#ifndef NM_TAGS_H
17#define NM_TAGS_H
18
24#define NM_TAGS_PREALLOC 255
25
26/* ** Tag-indexed containers- Warning: black-magic here! */
27
28
30static inline int nm_core_tag_eq(const nm_core_tag_t tag1, const nm_core_tag_t tag2)
31{
32 return ((tag1.hashcode == tag2.hashcode) && (tag1.tag == tag2.tag));
33}
35static inline int nm_core_tag_match(nm_core_tag_t recv_tag, nm_core_tag_t lookup_tag, nm_core_tag_t mask)
36{
37 assert((lookup_tag.tag & mask.tag) == lookup_tag.tag);
38 return ( ((recv_tag.hashcode & mask.hashcode) == lookup_tag.hashcode) &&
39 ((recv_tag.tag & mask.tag) == lookup_tag.tag) );
40}
41
42static inline uint32_t nm_core_tag_hash(const nm_core_tag_t*p_tag)
43{
44 const uint32_t hash = p_tag->tag + p_tag->hashcode;
45 return hash;
46}
48static inline int nm_core_tag_heq(const nm_core_tag_t*p_tag1, const nm_core_tag_t*p_tag2)
49{
50 return ((p_tag1->hashcode == p_tag2->hashcode) && (p_tag1->tag == p_tag2->tag));
51}
52
55
57#define NM_TAG_TABLE_TYPE(NAME, ENTRY_TYPE) \
58 struct NAME##_entry_s \
59 { \
60 ENTRY_TYPE _data; \
61 nm_core_tag_t _tag; \
62 }; \
63 NM_ALLOCATOR_TYPE(NAME##_entry, struct NAME##_entry_s); \
64 PUK_HASHTABLE_TYPE(NAME, nm_core_tag_t*, struct NAME##_entry_s*, &nm_core_tag_hash, &nm_core_tag_heq, NULL); \
65 struct NAME##_table_s \
66 { \
67 struct NAME##_hashtable_s _h; \
68 struct NAME##_entry_allocator_s _allocator; \
69 }; \
70 static inline void NAME##_table_init(struct NAME##_table_s*t) \
71 { \
72 NAME##_hashtable_init(&t->_h); \
73 NAME##_entry_allocator_init(&t->_allocator, NM_TAGS_PREALLOC); \
74 } \
75 static inline void NAME##_table_destroy(struct NAME##_table_s*t) \
76 { \
77 NAME##_hashtable_enumerator_t e = NAME##_hashtable_enumerator_new(&t->_h); \
78 struct NAME##_entry_s*entry = NAME##_hashtable_enumerator_next_data(e); \
79 while(entry) \
80 { \
81 NAME##_dtor(&entry->_data); \
82 NAME##_entry_free(&t->_allocator, entry); \
83 entry = NAME##_hashtable_enumerator_next_data(e); \
84 } \
85 NAME##_hashtable_enumerator_delete(e); \
86 NAME##_hashtable_destroy(&t->_h); \
87 NAME##_entry_allocator_destroy(&t->_allocator); \
88 } \
89 static inline ENTRY_TYPE* NAME##_get(struct NAME##_table_s*t, nm_core_tag_t tag) \
90 { \
91 assert(t != NULL); \
92 struct NAME##_entry_s*entry = NAME##_hashtable_lookup(&t->_h, &tag); \
93 if(entry == NULL) \
94 { \
95 entry = NAME##_entry_malloc(&t->_allocator); \
96 NAME##_ctor(&entry->_data, tag); \
97 entry->_tag = tag; \
98 NAME##_hashtable_insert(&t->_h, &entry->_tag, entry); \
99 } \
100 return &entry->_data; \
101 } \
102 static inline void NAME##_delete(struct NAME##_table_s*t, ENTRY_TYPE*_e) \
103 { \
104 struct NAME##_entry_s*entry = (void*)_e; \
105 NAME##_hashtable_remove(&t->_h, &entry->_tag); \
106 NAME##_dtor(&entry->_data); \
107 NAME##_entry_free(&t->_allocator, entry); \
108 } \
109 /* get a vector of all tags in the table */ \
110 static inline nm_core_tag_vect_t NAME##_get_tags(struct NAME##_table_s*t) \
111 { \
112 nm_core_tag_vect_t v = nm_core_tag_vect_new(); \
113 NAME##_hashtable_enumerator_t e = NAME##_hashtable_enumerator_new(&t->_h); \
114 struct NAME##_entry_s*entry = NAME##_hashtable_enumerator_next_data(e); \
115 while(entry) \
116 { \
117 nm_core_tag_vect_push_back(v, entry->_tag); \
118 entry = NAME##_hashtable_enumerator_next_data(e); \
119 } \
120 NAME##_hashtable_enumerator_delete(e); \
121 return v; \
122 }
123
126{
127 struct nm_req_list_s unpacks;
128 struct nm_unexpected_wildcard_list_s unexpected;
129};
130__PUK_SYM_INTERNAL void nm_unexpected_wildcard_clean(struct nm_unexpected_wildcard_list_s*p_unexpected);
132{
133 nm_req_list_init(&p_wildcard->unpacks);
134 nm_unexpected_wildcard_list_init(&p_wildcard->unexpected);
135}
136static inline void nm_matching_wildcard_dtor(struct nm_matching_wildcard_s*p_wildcard)
137{
139}
140NM_TAG_TABLE_TYPE(nm_matching_wildcard, struct nm_matching_wildcard_s)
142static inline struct nm_matching_wildcard_s*nm_matching_wildcard_bytag(struct nm_core*p_core, nm_core_tag_t core_tag);
143
146{
147 struct nm_req_list_s unpacks;
148 struct nm_unexpected_tag_list_s unexpected;
149};
150static inline void nm_matching_tag_ctor(struct nm_matching_tag_s*p_matching_tag, nm_core_tag_t tag __attribute__((unused)))
151{
152 nm_req_list_init(&p_matching_tag->unpacks);
153 nm_unexpected_tag_list_init(&p_matching_tag->unexpected);
154}
155static inline void nm_matching_tag_dtor(struct nm_matching_tag_s*p_matching_tag __attribute__((unused)))
156{
157}
158NM_TAG_TABLE_TYPE(nm_matching_tag, struct nm_matching_tag_s)
159
160#endif /* NM_TAGS_H */
struct nm_core_event_s __attribute__
Definition nm_data.h:538
nm_tag_t tag
the user-supplied tag
assert(p_data->ops.p_traversal !=NULL)
static int nm_core_tag_heq(const nm_core_tag_t *p_tag1, const nm_core_tag_t *p_tag2)
checks whether tags are equal, for hashtables.
Definition nm_tags.h:48
PUK_VECT_TYPE(nm_core_tag, nm_core_tag_t)
vector of tags, for *_get_tags() functions
static int nm_core_tag_match(nm_core_tag_t recv_tag, nm_core_tag_t lookup_tag, nm_core_tag_t mask)
checks whether matching applies on tags- (recv_tag & mask) == lookup_tag
Definition nm_tags.h:35
static void nm_matching_tag_dtor(struct nm_matching_tag_s *p_matching_tag __attribute__((unused)))
Definition nm_tags.h:155
static int nm_core_tag_eq(const nm_core_tag_t tag1, const nm_core_tag_t tag2)
checks whether tags are equal.
Definition nm_tags.h:30
static uint32_t nm_core_tag_hash(const nm_core_tag_t *p_tag)
Definition nm_tags.h:42
static void nm_matching_wildcard_ctor(struct nm_matching_wildcard_s *p_wildcard, nm_core_tag_t tag __attribute__((unused)))
Definition nm_tags.h:131
#define NM_TAG_TABLE_TYPE(NAME, ENTRY_TYPE)
macro to generate tables indexed by tags
Definition nm_tags.h:57
static void nm_matching_wildcard_dtor(struct nm_matching_wildcard_s *p_wildcard)
Definition nm_tags.h:136
static struct nm_matching_wildcard_s * nm_matching_wildcard_bytag(struct nm_core *p_core, nm_core_tag_t core_tag)
get the wildcard structure from a full tag, using only its hashcode
__PUK_SYM_INTERNAL void nm_unexpected_wildcard_clean(struct nm_unexpected_wildcard_list_s *p_unexpected)
static void nm_matching_tag_ctor(struct nm_matching_tag_s *p_matching_tag, nm_core_tag_t tag __attribute__((unused)))
Definition nm_tags.h:150
An internal tag.
nm_tag_t tag
the user-supplied tag
nm_session_hash_t hashcode
the session hashcode
Core NewMadeleine structure.
Definition nm_core.h:43
struct to store matching info for any-source requests of a given tag
Definition nm_tags.h:146
struct nm_req_list_s unpacks
Definition nm_tags.h:147
struct nm_unexpected_tag_list_s unexpected
Definition nm_tags.h:148
struct to store matching info for wildcard requests, one per session
Definition nm_tags.h:126
struct nm_req_list_s unpacks
list of wildcards unpacks; non-wildcard unpacks are in nm_gtag_s
Definition nm_tags.h:127
struct nm_unexpected_wildcard_list_s unexpected
global list of unexpected chunks
Definition nm_tags.h:128