• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * libwebsockets - small server side websockets and web server implementation
3  *
4  * Copyright (C) 2010 - 2021 Andy Green <andy@warmcat.com>
5  *
6  * Permission is hereby granted, free of charge, to any person obtaining a copy
7  * of this software and associated documentation files (the "Software"), to
8  * deal in the Software without restriction, including without limitation the
9  * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
10  * sell copies of the Software, and to permit persons to whom the Software is
11  * furnished to do so, subject to the following conditions:
12  *
13  * The above copyright notice and this permission notice shall be included in
14  * all copies or substantial portions of the Software.
15  *
16  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
21  * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
22  * IN THE SOFTWARE.
23  */
24 
25 /** \defgroup lws_map generic map apis
26  * ##Generic map structures and apis
27  * \ingroup lwsapi
28  *
29  * lws_map
30  *
31  * Discrete owner object represents the whole map, created with key-specific
32  * ops for hashing the key to a uint32_t and comparing two keys.  Owns a list
33  * of hash tables whose size / modulo it set at creation time.
34  *
35  * Items in the map are contained in a lws_map_item_t that is indexed in a
36  * hash table.
37  *
38  * It's difficult to make a single compact map abstraction that fits all cases,
39  * this is useful to the extent you have the memory to trade off the number of
40  * hashtables needed for the amount of items and the lookup latency limit for
41  * your application, typically for hundreds or low thousands of items.
42  */
43 //@{
44 
45 typedef struct lws_map lws_map_t;
46 typedef struct lws_map_item lws_map_item_t;
47 
48 typedef void * lws_map_key_t;
49 typedef void * lws_map_value_t;
50 typedef uint32_t lws_map_hash_t;
51 
52 typedef lws_map_hash_t (*lws_map_hash_from_key_t)(const lws_map_key_t key,
53 						  size_t kl);
54 typedef int (*lws_map_compare_key_t)(const lws_map_key_t key1, size_t kl1,
55 				     const lws_map_value_t key2, size_t kl2);
56 typedef void * (*lws_map_alloc_t)(struct lws_map *mo, size_t x);
57 typedef void (*lws_map_free_t)(void *);
58 
59 /*
60  * Creation parameters for the map, copied into the map owner
61  */
62 
63 typedef struct lws_map_info {
64 	lws_map_hash_from_key_t		_hash;
65 	lws_map_compare_key_t		_compare;
66 	lws_map_alloc_t			_alloc;	/* NULL = lws_malloc */
67 	lws_map_free_t			_free;	/* NULL = lws_free */
68 
69 	void				*opaque;
70 	/**< &lwsac if using lwsac allocator */
71 	void				*aux;
72 	/**< chunk size if using lwsac allocator */
73 	/**< this can be used by the alloc handler, eg for lws_ac */
74 	size_t				modulo;
75 	/**< number of hashed owner lists to create */
76 } lws_map_info_t;
77 
78 LWS_VISIBLE LWS_EXTERN const void *
79 lws_map_item_key(lws_map_item_t *_item);
80 LWS_VISIBLE LWS_EXTERN const void *
81 lws_map_item_value(lws_map_item_t *_item);
82 LWS_VISIBLE LWS_EXTERN size_t
83 lws_map_item_key_len(lws_map_item_t *_item);
84 LWS_VISIBLE LWS_EXTERN size_t
85 lws_map_item_value_len(lws_map_item_t *_item);
86 
87 /*
88  * Helpers for C string keys case
89  */
90 
91 #define lws_map_item_create_ks(_map, _str, _v, _vl) \
92 		lws_map_item_create(_map, (const lws_map_key_t)_str, \
93 				    strlen(_str), (const lws_map_value_t)_v, \
94 						    _vl)
95 #define lws_map_item_lookup_ks(_map, _str) \
96 		lws_map_item_lookup(_map, (const lws_map_key_t)_str, strlen(_str))
97 
98 /**
99  * lws_map_create() - create a map object and hashtables on heap
100  *
101  * \param info: description of map to create
102  *
103  * Creates a map object on heap, using lws_malloc().
104  *
105  * \p info may be all zeros inside, if so, modulo defaults to 8, and the
106  * operation callbacks default to using lws_malloc() / _free() for item alloc,
107  * a default xor / shift based hash and simple linear memory key compare.
108  *
109  * For less typical use-cases, the provided \p info members can be tuned to
110  * control how the allocation of mapped items is done, lws provides two exports
111  * lws_map_alloc_lwsac() and lws_map_free_lwsac() that can be used for _alloc
112  * and _free to have items allocated inside an lwsac.
113  *
114  * The map itself is created on the heap directly, the info._alloc() op is only
115  * used when creating items.
116  *
117  * keys have individual memory sizes and do not need to all be the same length.
118  */
119 LWS_VISIBLE LWS_EXTERN lws_map_t *
120 lws_map_create(const lws_map_info_t *info);
121 
122 /*
123  * helpers that can be used for info._alloc and info._free if using lwsac
124  * allocation for items, set info.opaque to point to the lwsac pointer, and
125  * aux to (void *)chunksize, or leave zero / NULL for the default
126  */
127 
128 LWS_VISIBLE LWS_EXTERN void *
129 lws_map_alloc_lwsac(struct lws_map *map, size_t x);
130 
131 LWS_VISIBLE LWS_EXTERN void
132 lws_map_free_lwsac(void *v);
133 
134 /**
135  * lws_map_destroy() - deallocate all items and free map
136  *
137  * \param pmap: pointer to pointer map object to deallocate
138  *
139  * Frees all items in the map, using info._free(), and then frees the map
140  * from heap directly.  \p *pmap is set to NULL.
141  */
142 LWS_VISIBLE LWS_EXTERN void
143 lws_map_destroy(lws_map_t **pmap);
144 
145 /**
146  * lws_map_item_create() - allocate and map an item into an existing map
147  *
148  * \param map: the map to add items into
149  * \param key: the key, may be any kind of object
150  * \param keylen: the length of the key in bytes
151  * \param value: the value, may be any kind of object
152  * \param valuelen: the length of value
153  *
154  * Allocates space for the item, key and value using the map allocator, and
155  * if non-NULL, copies the key and value into the item.
156  *
157  * If an item with the same key exists, it is removed and destroyed before
158  * creating and adding the new one.
159  */
160 
161 LWS_VISIBLE LWS_EXTERN lws_map_item_t *
162 lws_map_item_create(lws_map_t *map,
163 		    const lws_map_key_t key, size_t keylen,
164 		    const lws_map_value_t value, size_t valuelen);
165 
166 /**
167  * lws_map_item_destroy() - remove item from map and free
168  *
169  * \param item: the item in the map to remove and free
170  */
171 LWS_VISIBLE LWS_EXTERN void
172 lws_map_item_destroy(lws_map_item_t *item);
173 
174 /**
175  * lws_map_item_lookup() - look for a item with the given key in the map
176  *
177  * \param map: the map
178  * \param key: the key to look for
179  * \param keylen: the length of the key to look for
180  *
181  * Searches for the key in the map, using the map's key hash and key compare
182  * functions.
183  */
184 
185 LWS_VISIBLE LWS_EXTERN lws_map_item_t *
186 lws_map_item_lookup(lws_map_t *map, const lws_map_key_t key, size_t keylen);
187 
188 //@}
189