From 754949d43f2a0d4c8b0ec3c2982ba46d4680a370 Mon Sep 17 00:00:00 2001 From: nick Date: Fri, 9 Aug 2013 16:49:38 +0100 Subject: [PATCH] bitset: Add a bitset_run_count_ex that lets you learn the value of the bits in the run --- src/bitset.h | 36 ++++++++++++++++++++++++++++-------- tests/unit/check_bitset.c | 2 +- 2 files changed, 29 insertions(+), 9 deletions(-) diff --git a/src/bitset.h b/src/bitset.h index 5bb679c..75fa6d7 100644 --- a/src/bitset.h +++ b/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'' * 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 count = 0; 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--) { if (bit_has_value(b, from+count, first_value)) { count++; @@ -196,14 +201,15 @@ static inline void bitset_clear( bitset_clear_range(set, 0, set->size); } - -/** Counts the number of contiguous bytes that are represented as a run in - * the bit field. +/** As per bitset_run_count but also tells you whether the run it found was set + * or unset, atomically. */ -static inline uint64_t bitset_run_count( +static inline uint64_t bitset_run_count_ex( struct bitset_mapping* set, uint64_t from, - uint64_t len) + uint64_t len, + int* run_is_set +) { uint64_t run; @@ -216,13 +222,27 @@ static inline uint64_t bitset_run_count( INT_FIRST_AND_LAST; 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); + + + BITSET_UNLOCK; 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. */ static inline int bitset_is_clear_at( diff --git a/tests/unit/check_bitset.c b/tests/unit/check_bitset.c index 7653703..07d883b 100644 --- a/tests/unit/check_bitset.c +++ b/tests/unit/check_bitset.c @@ -100,7 +100,7 @@ START_TEST(test_bit_runs) ptr = 0; 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( run == runs[i], "run %d should have been %d, was %d",