#ifndef _NET_ART_H_
#define _NET_ART_H_
typedef uintptr_t art_heap_entry;
struct art {
art_heap_entry *art_root;
const unsigned int *art_levels;
unsigned int art_nlevels;
unsigned int art_alen;
};
struct art_table {
art_heap_entry *at_heap;
struct art_table *at_parent;
unsigned int at_index;
unsigned int at_minfringe;
unsigned int at_level;
unsigned int at_bits;
unsigned int at_offset;
unsigned int at_refcnt;
};
#define ART_HEAP_IDX_TABLE 0
#define ART_HEAP_IDX_DEFAULT 1
#define AT_HEAPSIZE(bits) ((1 << ((bits) + 1)) * sizeof(art_heap_entry))
struct art_node {
void *an_value;
union {
struct art_node *an__gc;
uint8_t an__addr[16];
} an__u;
#define an_gc an__u.an__gc
#define an_addr an__u.an__addr
unsigned int an_plen;
};
static inline struct art_table *
art_heap_to_table(art_heap_entry *heap)
{
return ((struct art_table *)heap[ART_HEAP_IDX_TABLE]);
}
static inline int
art_heap_entry_is_node(art_heap_entry ahe)
{
return ((ahe & 1UL) == 0);
}
static inline struct art_node *
art_heap_entry_to_node(art_heap_entry ahe)
{
return ((struct art_node *)ahe);
}
static inline art_heap_entry *
art_heap_entry_to_heap(art_heap_entry ahe)
{
return ((art_heap_entry *)(ahe & ~1UL));
}
static inline art_heap_entry
art_node_to_heap_entry(struct art_node *an)
{
return ((art_heap_entry)an);
}
static inline art_heap_entry
art_heap_to_heap_entry(art_heap_entry *heap)
{
return ((art_heap_entry)heap | 1UL);
}
#ifdef _KERNEL
void art_boot(void);
struct art *art_alloc(unsigned int);
void art_init(struct art *, unsigned int);
struct art_node *art_insert(struct art *, struct art_node *);
struct art_node *art_delete(struct art *, const void *, unsigned int);
struct art_node *art_match(struct art *, const void *);
struct art_node *art_lookup(struct art *, const void *, unsigned int);
int art_is_empty(struct art *);
struct art_node *art_get(const uint8_t *, unsigned int);
void art_node_init(struct art_node *,
const uint8_t *, unsigned int);
void art_put(struct art_node *);
struct art_iter {
struct art *ai_art;
struct art_table *ai_table;
unsigned int ai_j;
unsigned int ai_i;
};
struct art_node *art_iter_open(struct art *, struct art_iter *);
struct art_node *art_iter_next(struct art_iter *);
void art_iter_close(struct art_iter *);
#define ART_FOREACH(_an, _art, _ai) \
for ((_an) = art_iter_open((_art), (_ai)); \
(_an) != NULL; \
(_an) = art_iter_next((_ai)))
int art_walk(struct art *,
int (*)(struct art_node *, void *), void *);
#endif
#endif