bitset: Add a bitset_run_count_ex that lets you learn the value of the bits in the run

This commit is contained in:
nick
2013-08-09 16:49:38 +01:00
parent f590f8ed3c
commit 754949d43f
2 changed files with 29 additions and 9 deletions

View File

@@ -72,13 +72,18 @@ static inline void bit_clear_range(char* b, uint64_t from, uint64_t len)
/** Counts the number of contiguous bits in array ''b'', starting at ''from'' /** Counts the number of contiguous bits in array ''b'', starting at ''from''
* 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. If ''run_is_set'' is
* non-NULL, the value of that bit is placed into it.
*/ */
static inline uint64_t 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, int *run_is_set) {
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);
if ( run_is_set != NULL ) {
*run_is_set = first_value;
}
for ( ; (from+count) % 64 != 0 && len > 0; len--) { for ( ; (from+count) % 64 != 0 && len > 0; len--) {
if (bit_has_value(b, from+count, first_value)) { if (bit_has_value(b, from+count, first_value)) {
count++; count++;
@@ -196,14 +201,15 @@ static inline void bitset_clear(
bitset_clear_range(set, 0, set->size); bitset_clear_range(set, 0, set->size);
} }
/** As per bitset_run_count but also tells you whether the run it found was set
/** Counts the number of contiguous bytes that are represented as a run in * or unset, atomically.
* the bit field.
*/ */
static inline uint64_t bitset_run_count( static inline uint64_t bitset_run_count_ex(
struct bitset_mapping* set, struct bitset_mapping* set,
uint64_t from, uint64_t from,
uint64_t len) uint64_t len,
int* run_is_set
)
{ {
uint64_t run; uint64_t run;
@@ -216,13 +222,27 @@ static inline uint64_t bitset_run_count(
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, run_is_set) * set->resolution;
run -= (from % set->resolution); run -= (from % set->resolution);
BITSET_UNLOCK; BITSET_UNLOCK;
return run; return run;
} }
/** Counts the number of contiguous bytes that are represented as a run in
* the bit field.
*/
static inline uint64_t bitset_run_count(
struct bitset_mapping* set,
uint64_t from,
uint64_t len)
{
return bitset_run_count_ex( set, from, len, NULL );
}
/** Tests whether the bit field is clear for the given file offset. /** Tests whether the bit field is clear for the given file offset.
*/ */
static inline int bitset_is_clear_at( static inline int bitset_is_clear_at(

View File

@@ -100,7 +100,7 @@ START_TEST(test_bit_runs)
ptr = 0; ptr = 0;
for (i=0; i < 20; i += 1) { for (i=0; i < 20; i += 1) {
int run = bit_run_count(buffer, ptr, 2048-ptr); int run = bit_run_count(buffer, ptr, 2048-ptr, NULL);
fail_unless( fail_unless(
run == runs[i], run == runs[i],
"run %d should have been %d, was %d", "run %d should have been %d, was %d",