2022-03-29 15:48:45 -04:00
/* SPDX-License-Identifier: GPL-2.0 */
# ifndef _BCACHEFS_DARRAY_H
# define _BCACHEFS_DARRAY_H
/*
* Dynamic arrays :
*
* Inspired by CCAN ' s darray
*/
# include <linux/slab.h>
2023-12-30 14:38:29 -05:00
# define DARRAY_PREALLOCATED(_type, _nr) \
2022-03-29 15:48:45 -04:00
struct { \
size_t nr , size ; \
2023-12-30 14:38:29 -05:00
_type * data ; \
_type preallocated [ _nr ] ; \
2022-03-29 15:48:45 -04:00
}
2023-12-30 14:38:29 -05:00
# define DARRAY(_type) DARRAY_PREALLOCATED(_type, 0)
2022-03-29 15:48:45 -04:00
2023-12-30 14:38:29 -05:00
typedef DARRAY ( char ) darray_char ;
2023-12-22 21:10:32 -05:00
typedef DARRAY ( char * ) darray_str ;
2023-11-08 17:11:44 -05:00
2023-12-30 14:38:29 -05:00
int __bch2_darray_resize ( darray_char * , size_t , size_t , gfp_t ) ;
static inline int __darray_resize ( darray_char * d , size_t element_size ,
2023-11-08 17:11:44 -05:00
size_t new_size , gfp_t gfp )
2022-03-29 15:48:45 -04:00
{
2023-11-08 17:11:44 -05:00
return unlikely ( new_size > d - > size )
? __bch2_darray_resize ( d , element_size , new_size , gfp )
: 0 ;
}
2022-03-29 15:48:45 -04:00
2023-11-08 17:11:44 -05:00
# define darray_resize_gfp(_d, _new_size, _gfp) \
2023-12-30 14:38:29 -05:00
unlikely ( __darray_resize ( ( darray_char * ) ( _d ) , sizeof ( ( _d ) - > data [ 0 ] ) , ( _new_size ) , _gfp ) )
2022-03-29 15:48:45 -04:00
2023-11-08 17:11:44 -05:00
# define darray_resize(_d, _new_size) \
darray_resize_gfp ( _d , _new_size , GFP_KERNEL )
2022-03-29 15:48:45 -04:00
2023-12-30 14:38:29 -05:00
static inline int __darray_make_room ( darray_char * d , size_t t_size , size_t more , gfp_t gfp )
2023-11-08 17:11:44 -05:00
{
return __darray_resize ( d , t_size , d - > nr + more , gfp ) ;
2022-03-29 15:48:45 -04:00
}
2023-03-15 11:53:51 -04:00
# define darray_make_room_gfp(_d, _more, _gfp) \
2023-12-30 14:38:29 -05:00
__darray_make_room ( ( darray_char * ) ( _d ) , sizeof ( ( _d ) - > data [ 0 ] ) , ( _more ) , _gfp )
2023-03-15 11:53:51 -04:00
2022-03-29 15:48:45 -04:00
# define darray_make_room(_d, _more) \
2023-03-15 11:53:51 -04:00
darray_make_room_gfp ( _d , _more , GFP_KERNEL )
2022-03-29 15:48:45 -04:00
2023-11-08 17:11:44 -05:00
# define darray_room(_d) ((_d).size - (_d).nr)
2022-03-29 15:48:45 -04:00
# define darray_top(_d) ((_d).data[(_d).nr])
2023-03-15 11:53:51 -04:00
# define darray_push_gfp(_d, _item, _gfp) \
2022-03-29 15:48:45 -04:00
( { \
2023-03-15 11:53:51 -04:00
int _ret = darray_make_room_gfp ( ( _d ) , 1 , _gfp ) ; \
2022-03-29 15:48:45 -04:00
\
if ( ! _ret ) \
( _d ) - > data [ ( _d ) - > nr + + ] = ( _item ) ; \
_ret ; \
} )
2023-03-15 11:53:51 -04:00
# define darray_push(_d, _item) darray_push_gfp(_d, _item, GFP_KERNEL)
2023-03-18 21:37:43 -04:00
# define darray_pop(_d) ((_d)->data[--(_d)->nr])
# define darray_first(_d) ((_d).data[0])
# define darray_last(_d) ((_d).data[(_d).nr - 1])
2023-08-01 20:06:45 -04:00
# define darray_insert_item(_d, pos, _item) \
2022-03-29 15:48:45 -04:00
( { \
2023-08-01 20:06:45 -04:00
size_t _pos = ( pos ) ; \
2022-03-29 15:48:45 -04:00
int _ret = darray_make_room ( ( _d ) , 1 ) ; \
\
if ( ! _ret ) \
2023-08-01 20:06:45 -04:00
array_insert_item ( ( _d ) - > data , ( _d ) - > nr , _pos , ( _item ) ) ; \
2022-03-29 15:48:45 -04:00
_ret ; \
} )
2023-10-31 22:35:49 -04:00
# define darray_remove_item(_d, _pos) \
array_remove_item ( ( _d ) - > data , ( _d ) - > nr , ( _pos ) - ( _d ) - > data )
2023-12-16 21:40:26 -05:00
# define __darray_for_each(_d, _i) \
for ( ( _i ) = ( _d ) . data ; _i < ( _d ) . data + ( _d ) . nr ; _i + + )
2022-03-29 15:48:45 -04:00
# define darray_for_each(_d, _i) \
2023-12-16 21:40:26 -05:00
for ( typeof ( & ( _d ) . data [ 0 ] ) _i = ( _d ) . data ; _i < ( _d ) . data + ( _d ) . nr ; _i + + )
2022-03-29 15:48:45 -04:00
2023-10-31 22:35:49 -04:00
# define darray_for_each_reverse(_d, _i) \
2023-12-16 21:40:26 -05:00
for ( typeof ( & ( _d ) . data [ 0 ] ) _i = ( _d ) . data + ( _d ) . nr - 1 ; _i > = ( _d ) . data ; - - _i )
2023-10-31 22:35:49 -04:00
2022-03-29 15:48:45 -04:00
# define darray_init(_d) \
do { \
2023-12-30 14:38:29 -05:00
( _d ) - > nr = 0 ; \
( _d ) - > size = ARRAY_SIZE ( ( _d ) - > preallocated ) ; \
( _d ) - > data = ( _d ) - > size ? ( _d ) - > preallocated : NULL ; \
2022-03-29 15:48:45 -04:00
} while ( 0 )
# define darray_exit(_d) \
do { \
2023-12-30 14:38:29 -05:00
if ( ! ARRAY_SIZE ( ( _d ) - > preallocated ) | | \
( _d ) - > data ! = ( _d ) - > preallocated ) \
kvfree ( ( _d ) - > data ) ; \
2022-03-29 15:48:45 -04:00
darray_init ( _d ) ; \
} while ( 0 )
# endif /* _BCACHEFS_DARRAY_H */