2011-09-13 14:29:12 +04: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 16:12:17 +04:00
# include <linux/list.h>
# include <linux/rbtree.h>
2011-09-13 14:29:12 +04: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 .
*
*/
2012-05-22 16:56:50 +04:00
struct ulist_iterator {
2014-01-28 20:25:34 +04:00
# ifdef CONFIG_BTRFS_DEBUG
2012-05-22 16:56:50 +04:00
int i ;
2014-01-28 20:25:34 +04:00
# endif
struct list_head * cur_list ; /* hint to start search */
2012-05-22 16:56:50 +04:00
} ;
2011-09-13 14:29:12 +04:00
/*
* element of the list
*/
struct ulist_node {
u64 val ; /* value to store */
2012-07-28 18:18:58 +04:00
u64 aux ; /* auxiliary value saved along with the val */
2014-01-28 20:25:34 +04:00
# ifdef CONFIG_BTRFS_DEBUG
int seqnum ; /* sequence number this node is added */
# endif
struct list_head list ; /* used to link node */
2013-04-12 16:12:17 +04:00
struct rb_node rb_node ; /* used to speed up search */
2011-09-13 14:29:12 +04:00
} ;
struct ulist {
/*
* number of elements stored in list
*/
unsigned long nnodes ;
2014-01-28 20:25:34 +04:00
struct list_head nodes ;
2013-04-12 16:12:17 +04:00
struct rb_root root ;
2011-09-13 14:29:12 +04:00
} ;
void ulist_init ( struct ulist * ulist ) ;
void ulist_reinit ( struct ulist * ulist ) ;
2012-04-25 20:37:14 +04:00
struct ulist * ulist_alloc ( gfp_t gfp_mask ) ;
2011-09-13 14:29:12 +04:00
void ulist_free ( struct ulist * ulist ) ;
2012-07-28 18:18:58 +04: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 ) ;
2015-04-20 04:26:02 +03:00
int ulist_del ( struct ulist * ulist , u64 val , u64 aux ) ;
2014-07-28 12:57:04 +04:00
/* just like ulist_add_merge() but take a pointer for the aux data */
static inline int ulist_add_merge_ptr ( struct ulist * ulist , u64 val , void * aux ,
void * * old_aux , gfp_t gfp_mask )
{
# if BITS_PER_LONG == 32
u64 old64 = ( uintptr_t ) * old_aux ;
int ret = ulist_add_merge ( ulist , val , ( uintptr_t ) aux , & old64 , gfp_mask ) ;
* old_aux = ( void * ) ( ( uintptr_t ) old64 ) ;
return ret ;
# else
return ulist_add_merge ( ulist , val , ( u64 ) aux , ( u64 * ) old_aux , gfp_mask ) ;
# endif
}
2012-05-22 16:56:50 +04:00
struct ulist_node * ulist_next ( struct ulist * ulist ,
struct ulist_iterator * uiter ) ;
2014-01-28 20:25:34 +04:00
# define ULIST_ITER_INIT(uiter) ((uiter)->cur_list = NULL)
2011-09-13 14:29:12 +04:00
# endif