bitset: Fix large runs
This commit is contained in:
12
src/bitset.h
12
src/bitset.h
@@ -74,7 +74,7 @@ static inline void bit_clear_range(char* b, uint64_t from, uint64_t len)
|
|||||||
* up to a maximum number of bits ''len''. Returns the number of contiguous
|
* up to a maximum number of bits ''len''. Returns the number of contiguous
|
||||||
* bits that are the same as the first one specified.
|
* bits that are the same as the first one specified.
|
||||||
*/
|
*/
|
||||||
static inline int bit_run_count(char* b, uint64_t from, uint64_t len) {
|
static inline uint64_t bit_run_count(char* b, uint64_t from, uint64_t len) {
|
||||||
uint64_t* current_block;
|
uint64_t* current_block;
|
||||||
uint64_t count = 0;
|
uint64_t count = 0;
|
||||||
int first_value = bit_is_set(b, from);
|
int first_value = bit_is_set(b, from);
|
||||||
@@ -138,8 +138,8 @@ static inline struct bitset_mapping* bitset_alloc(
|
|||||||
|
|
||||||
#define INT_FIRST_AND_LAST \
|
#define INT_FIRST_AND_LAST \
|
||||||
uint64_t first = from/set->resolution, \
|
uint64_t first = from/set->resolution, \
|
||||||
last = (from+len-1)/set->resolution, \
|
last = ((from+len)-1)/set->resolution, \
|
||||||
bitlen = last-first+1
|
bitlen = (last-first)+1
|
||||||
|
|
||||||
#define BITSET_LOCK \
|
#define BITSET_LOCK \
|
||||||
FATAL_IF_NEGATIVE(pthread_mutex_lock(&set->lock), "Error locking bitset")
|
FATAL_IF_NEGATIVE(pthread_mutex_lock(&set->lock), "Error locking bitset")
|
||||||
@@ -214,10 +214,12 @@ static inline uint64_t bitset_run_count(
|
|||||||
len = ( len + from ) > set->size ? ( set->size - from ) : len;
|
len = ( len + from ) > set->size ? ( set->size - from ) : len;
|
||||||
|
|
||||||
INT_FIRST_AND_LAST;
|
INT_FIRST_AND_LAST;
|
||||||
|
|
||||||
BITSET_LOCK;
|
BITSET_LOCK;
|
||||||
run = (bit_run_count(set->bits, first, bitlen) * set->resolution) -
|
run = bit_run_count(set->bits, first, bitlen) * set->resolution;
|
||||||
(from % set->resolution);
|
run -= (from % set->resolution);
|
||||||
BITSET_UNLOCK;
|
BITSET_UNLOCK;
|
||||||
|
|
||||||
return run;
|
return run;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -140,7 +140,7 @@ void write_not_zeroes(struct client* client, uint64_t from, uint64_t len)
|
|||||||
char zerobuffer[block_allocation_resolution];
|
char zerobuffer[block_allocation_resolution];
|
||||||
/* not allocated, read in block_allocation_resoution */
|
/* not allocated, read in block_allocation_resoution */
|
||||||
while (run > 0) {
|
while (run > 0) {
|
||||||
int blockrun = block_allocation_resolution -
|
uint64_t blockrun = block_allocation_resolution -
|
||||||
(from % block_allocation_resolution);
|
(from % block_allocation_resolution);
|
||||||
if (blockrun > run)
|
if (blockrun > run)
|
||||||
blockrun = run;
|
blockrun = run;
|
||||||
|
@@ -270,7 +270,7 @@ int fd_is_closed( int fd_in )
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline int io_errno_permanent()
|
static inline int io_errno_permanent(void)
|
||||||
{
|
{
|
||||||
return ( errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR );
|
return ( errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR );
|
||||||
}
|
}
|
||||||
|
@@ -106,6 +106,10 @@ void mirror_reset( struct mirror * mirror )
|
|||||||
NULLCHECK( mirror->dirty_map );
|
NULLCHECK( mirror->dirty_map );
|
||||||
mirror_set_state( mirror, MS_INIT );
|
mirror_set_state( mirror, MS_INIT );
|
||||||
bitset_set(mirror->dirty_map);
|
bitset_set(mirror->dirty_map);
|
||||||
|
|
||||||
|
uint64_t run = bitset_run_count(mirror->dirty_map, 0, mirror->dirty_map->size);
|
||||||
|
warn( "bitset_run_count: %"PRIu64, run);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@@ -188,6 +188,9 @@ START_TEST( test_bitset_run_count )
|
|||||||
|
|
||||||
assert_bitset_is( map, 0x0000000000000000 );
|
assert_bitset_is( map, 0x0000000000000000 );
|
||||||
|
|
||||||
|
run = bitset_run_count( map, 0, 64 );
|
||||||
|
ck_assert_int_eq( 64, run );
|
||||||
|
|
||||||
bitset_set_range( map, 0, 32 );
|
bitset_set_range( map, 0, 32 );
|
||||||
assert_bitset_is( map, 0x00000000ffffffff );
|
assert_bitset_is( map, 0x00000000ffffffff );
|
||||||
|
|
||||||
@@ -215,6 +218,11 @@ START_TEST( test_bitset_run_count )
|
|||||||
free( map );
|
free( map );
|
||||||
|
|
||||||
map = bitset_alloc( 6400, 100 );
|
map = bitset_alloc( 6400, 100 );
|
||||||
|
assert_bitset_is( map, 0x0000000000000000 );
|
||||||
|
|
||||||
|
run = bitset_run_count( map, 0, 6400 );
|
||||||
|
ck_assert_int_eq( 6400, run );
|
||||||
|
|
||||||
bitset_set_range( map, 0, 3200 );
|
bitset_set_range( map, 0, 3200 );
|
||||||
|
|
||||||
run = bitset_run_count( map, 0, 6400 );
|
run = bitset_run_count( map, 0, 6400 );
|
||||||
@@ -228,6 +236,16 @@ START_TEST( test_bitset_run_count )
|
|||||||
|
|
||||||
run = bitset_run_count( map, 6500, 6400 );
|
run = bitset_run_count( map, 6500, 6400 );
|
||||||
ck_assert_int_eq( 0, run );
|
ck_assert_int_eq( 0, run );
|
||||||
|
free( map );
|
||||||
|
|
||||||
|
// Now do something large and representative
|
||||||
|
map = bitset_alloc( 53687091200, 4096 );
|
||||||
|
bitset_set( map );
|
||||||
|
run = bitset_run_count( map, 0, 53687091200 );
|
||||||
|
ck_assert_int_eq( run, 53687091200 );
|
||||||
|
|
||||||
|
free( map );
|
||||||
|
|
||||||
}
|
}
|
||||||
END_TEST
|
END_TEST
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user