bitset: Add a bitset_run_count_ex that lets you learn the value of the bits in the run
This commit is contained in:
36
src/bitset.h
36
src/bitset.h
@@ -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(
|
||||||
|
@@ -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",
|
||||||
|
Reference in New Issue
Block a user