2011-09-13 12:29:12 +02:00
/*
* Copyright ( C ) 2011 STRATO AG
* written by Arne Jansen < sensille @ gmx . net >
* Distributed under the GNU GPL license version 2.
*
*/
# ifndef __ULIST__
# define __ULIST__
2013-04-12 12:12:17 +00:00
# include <linux/list.h>
# include <linux/rbtree.h>
2011-09-13 12:29:12 +02:00
/*
* ulist is a generic data structure to hold a collection of unique u64
* values . The only operations it supports is adding to the list and
* enumerating it .
* It is possible to store an auxiliary value along with the key .
*
* The implementation is preliminary and can probably be sped up
* significantly . A first step would be to store the values in an rbtree
* as soon as ULIST_SIZE is exceeded .
*/
/*
* number of elements statically allocated inside struct ulist
*/
# define ULIST_SIZE 16
2012-05-22 14:56:50 +02:00
struct ulist_iterator {
int i ;
} ;
2011-09-13 12:29:12 +02:00
/*
* element of the list
*/
struct ulist_node {
u64 val ; /* value to store */
2012-07-28 16:18:58 +02:00
u64 aux ; /* auxiliary value saved along with the val */
2013-04-12 12:12:17 +00:00
struct rb_node rb_node ; /* used to speed up search */
2011-09-13 12:29:12 +02:00
} ;
struct ulist {
/*
* number of elements stored in list
*/
unsigned long nnodes ;
/*
* number of nodes we already have room for
*/
unsigned long nodes_alloced ;
/*
* pointer to the array storing the elements . The first ULIST_SIZE
* elements are stored inline . In this case the it points to int_nodes .
* After exceeding ULIST_SIZE , dynamic memory is allocated .
*/
struct ulist_node * nodes ;
2013-04-12 12:12:17 +00:00
struct rb_root root ;
2011-09-13 12:29:12 +02:00
/*
* inline storage space for the first ULIST_SIZE entries
*/
struct ulist_node int_nodes [ ULIST_SIZE ] ;
} ;
void ulist_init ( struct ulist * ulist ) ;
void ulist_fini ( struct ulist * ulist ) ;
void ulist_reinit ( struct ulist * ulist ) ;
2012-04-26 00:37:14 +08:00
struct ulist * ulist_alloc ( gfp_t gfp_mask ) ;
2011-09-13 12:29:12 +02:00
void ulist_free ( struct ulist * ulist ) ;
2012-07-28 16:18:58 +02:00
int ulist_add ( struct ulist * ulist , u64 val , u64 aux , gfp_t gfp_mask ) ;
int ulist_add_merge ( struct ulist * ulist , u64 val , u64 aux ,
u64 * old_aux , gfp_t gfp_mask ) ;
2012-05-22 14:56:50 +02:00
struct ulist_node * ulist_next ( struct ulist * ulist ,
struct ulist_iterator * uiter ) ;
# define ULIST_ITER_INIT(uiter) ((uiter)->i = 0)
2011-09-13 12:29:12 +02:00
# endif