2 #ifndef __G_BSEARCH_ARRAY_H__
3 #define __G_BSEARCH_ARRAY_H__
17 #define G_BSEARCH_ARRAY_CMP(v1,v2) ((v1) > (v2) ? +1 : (v1) == (v2) ? 0 : -1)
21 typedef gint (*GBSearchCompareFunc) (gconstpointer bsearch_node1,
22 gconstpointer bsearch_node2);
25 G_BSEARCH_ARRAY_ALIGN_POWER2 = 1 << 0,
26 G_BSEARCH_ARRAY_AUTO_SHRINK = 1 << 1
34 GBSearchCompareFunc cmp_nodes;
41 gpointer alignment_dummy1;
42 glong alignment_dummy2;
43 gdouble alignment_dummy3;
49 static inline gpointer g_bsearch_array_get_nth (
GBSearchArray *barray,
52 static inline guint g_bsearch_array_get_index (
GBSearchArray *barray,
54 gconstpointer node_in_array);
60 gconstpointer node_in_array);
68 gconstpointer key_node);
74 gconstpointer key_node);
75 static inline void g_bsearch_array_free (
GBSearchArray *barray,
77 #define g_bsearch_array_get_n_nodes(barray) (((GBSearchArray*) (barray))->n_nodes)
82 #define g_bsearch_array_lookup(barray, bconfig, key_node) \
83 g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 0)
91 #define g_bsearch_array_lookup_sibling(barray, bconfig, key_node) \
92 g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 1)
99 #define g_bsearch_array_lookup_insertion(barray, bconfig, key_node) \
100 g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 2)
105 #ifdef DISABLE_MEM_POOLS
106 #define G_BSEARCH_UPPER_POWER2(n) (n)
108 #define G_BSEARCH_UPPER_POWER2(n) ((n) ? 1 << g_bit_storage ((n) - 1) : 0)
110 #define G_BSEARCH_ARRAY_NODES(barray) (((guint8*) (barray)) + sizeof (GBSearchArray))
117 g_return_val_if_fail (bconfig != NULL, NULL);
120 if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
121 size = G_BSEARCH_UPPER_POWER2 (size);
127 static inline gpointer
130 gconstpointer key_node,
131 const guint sibling_or_after);
132 static inline gpointer
135 gconstpointer key_node,
136 const guint sibling_or_after)
138 GBSearchCompareFunc cmp_nodes = bconfig->cmp_nodes;
139 guint8 *check = NULL, *nodes = G_BSEARCH_ARRAY_NODES (barray);
140 guint n_nodes = barray->n_nodes, offs = 0;
141 guint sizeof_node = bconfig->sizeof_node;
144 while (offs < n_nodes)
146 guint i = (offs + n_nodes) >> 1;
148 check = nodes + i * sizeof_node;
149 cmp = cmp_nodes (key_node, check);
151 return sibling_or_after > 1 ? NULL : check;
159 return G_LIKELY (!sibling_or_after) ? NULL : (sibling_or_after > 1 && cmp > 0) ? check + sizeof_node : check;
161 static inline gpointer
164 return (G_LIKELY (nth < barray->n_nodes) ?
165 G_BSEARCH_ARRAY_NODES (barray) + nth * bconfig->sizeof_node :
171 gconstpointer node_in_array)
173 guint
distance = ((guint8*) node_in_array) - G_BSEARCH_ARRAY_NODES (barray);
175 g_return_val_if_fail (node_in_array != NULL, barray->n_nodes);
177 distance /= bconfig->sizeof_node;
179 return MIN (distance, barray->n_nodes + 1);
186 guint old_size = barray->n_nodes * bconfig->sizeof_node;
187 guint new_size = old_size + bconfig->sizeof_node;
190 g_return_val_if_fail (index <= barray->n_nodes, NULL);
192 if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2))
194 new_size = G_BSEARCH_UPPER_POWER2 (
sizeof (
GBSearchArray) + new_size);
195 old_size = G_BSEARCH_UPPER_POWER2 (
sizeof (
GBSearchArray) + old_size);
196 if (old_size != new_size)
201 node = G_BSEARCH_ARRAY_NODES (barray) + index * bconfig->sizeof_node;
202 memmove (node + bconfig->sizeof_node, node, (barray->n_nodes - index) * bconfig->sizeof_node);
203 barray->n_nodes += 1;
209 gconstpointer key_node)
213 if (G_UNLIKELY (!barray->n_nodes))
215 barray = g_bsearch_array_grow (barray, bconfig, 0);
216 node = G_BSEARCH_ARRAY_NODES (barray);
220 node = (guint8 *) g_bsearch_array_lookup_insertion (barray, bconfig, key_node);
223 guint index = g_bsearch_array_get_index (barray, bconfig, node);
226 barray = g_bsearch_array_grow (barray, bconfig, index);
227 node = G_BSEARCH_ARRAY_NODES (barray) + index * bconfig->sizeof_node;
232 memcpy (node, key_node, bconfig->sizeof_node);
238 gconstpointer key_node)
240 guint8 *node = (guint8 *) g_bsearch_array_lookup (barray, bconfig, key_node);
242 memcpy (node, key_node, bconfig->sizeof_node);
244 barray = g_bsearch_array_insert (barray, bconfig, key_node);
254 g_return_val_if_fail (index < barray->n_nodes, NULL);
256 barray->n_nodes -= 1;
257 node = G_BSEARCH_ARRAY_NODES (barray) + index * bconfig->sizeof_node;
258 memmove (node, node + bconfig->sizeof_node, (barray->n_nodes - index) * bconfig->sizeof_node);
259 if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_AUTO_SHRINK))
261 guint new_size = barray->n_nodes * bconfig->sizeof_node;
262 guint old_size = new_size + bconfig->sizeof_node;
264 if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2))
266 new_size = G_BSEARCH_UPPER_POWER2 (
sizeof (
GBSearchArray) + new_size);
267 old_size = G_BSEARCH_UPPER_POWER2 (
sizeof (
GBSearchArray) + old_size);
268 if (old_size != new_size)
279 gconstpointer node_in_array)
281 return g_bsearch_array_remove (barray, bconfig, g_bsearch_array_get_index (barray, bconfig, node_in_array));
287 g_return_if_fail (barray != NULL);
Definition: gbsearcharray.hh:31
Definition: gbsearcharray.hh:37