Skip to content

Commit

Permalink
cii: Impl set operations in bit set
Browse files Browse the repository at this point in the history
  • Loading branch information
XuShaohua committed Dec 7, 2023
1 parent 15a25c7 commit 7b988d5
Show file tree
Hide file tree
Showing 2 changed files with 101 additions and 17 deletions.
26 changes: 13 additions & 13 deletions cii/include/cii/bit.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,31 +68,31 @@ extern bool bit_get(bit_t* set, size_t index);
extern bool bit_put(bit_t* set, size_t index, bool value);

/**
* Clear bits in range [start, end) in a bit vector.
* Clear bits in range [low, high] in a bit vector.
*
* @param set
* @param start
* @param end
* @param low
* @param high
*/
extern void bit_clear(bit_t* set, size_t start, size_t end);
extern void bit_clear(bit_t* set, size_t low, size_t high);

/**
* Set bits in range [start, end) in a bit vector.
* Set bits in range [low, high] in a bit vector.
*
* @param set
* @param start
* @param end
* @param low
* @param high
*/
extern void bit_set(bit_t* set, size_t start, size_t end);
extern void bit_set(bit_t* set, size_t low, size_t high);

/**
* Toggle bits in range [start, end) in a bit vector.
* Toggle bits in range [low, high] in a bit vector.
*
* @param set
* @param start
* @param end
* @param low
* @param high
*/
extern void bit_not(bit_t* set, size_t start, size_t end);
extern void bit_not(bit_t* set, size_t low, size_t high);

/**
* Check whether bit vector s is less than t.
Expand Down Expand Up @@ -127,7 +127,7 @@ extern bool bit_less_equal(bit_t* s, bit_t* t);
* @param apply
* @param user_data
*/
extern void bit_map(bit_t* s,
extern void bit_map(bit_t* set,
void(*apply)(size_t index, bool is_set, void* user_data),
void* user_data);

Expand Down
92 changes: 88 additions & 4 deletions cii/src/bit.c
Original file line number Diff line number Diff line change
Expand Up @@ -98,14 +98,98 @@ bool bit_put(bit_t* set, size_t index, bool value) {
return prev;
}

void bit_clear(bit_t* set, size_t start, size_t end) {
// Most significant byte mask.
static const uint8_t kMsbMask[] = {
0xFF, 0xFE, 0xFC, 0xF8,
0xF0, 0xE0, 0xC0, 0x80
};

// Least significant byte mask.
static const uint8_t kLsbMask[] = {
0x01, 0x03, 0x07, 0x0F,
0x1F, 0x3F, 0x7F, 0xFF
};

void bit_clear(bit_t* set, size_t low, size_t high) {
assert(set != NULL);
assert(high < set->length);
assert(low <= high);

if (low / 8 < high / 8) {
// Set the most significant bits in byte low/8.
set->bytes[low / 8] &= ~kMsbMask[low % 8];

// Set all the bits in bytes low/8+1..high/8-1.
{
for (size_t i = low / 8 + 1; i < high / 8; ++i) {
set->bytes[i] = 0x00;
}
}

// Set the least significant bits in byte high/8.
set->bytes[high / 8] &= ~kLsbMask[high % 8];
} else {
// Set bits low%8..high%8 in byte low/8.
set->bytes[low / 8] &= ~(kMsbMask[low % 8] & kLsbMask[high % 8]);
}
}

void bit_set(bit_t* set, size_t start, size_t end) {
void bit_set(bit_t* set, size_t low, size_t high) {
assert(set != NULL);
assert(high < set->length);
assert(low <= high);

if (low / 8 < high / 8) {
// Set the most significant bits in byte low/8.
set->bytes[low / 8] |= kMsbMask[low % 8];

// Set all the bits in bytes low/8+1..high/8-1.
{
for (size_t i = low / 8 + 1; i < high / 8; ++i) {
set->bytes[i] = 0xFF;
}
}

// Set the least significant bits in byte high/8.
set->bytes[high / 8] |= kLsbMask[high % 8];
} else {
// Set bits low%8..high%8 in byte low/8.
set->bytes[low / 8] |= (kMsbMask[low % 8] & kLsbMask[high % 8]);
}
}

void bit_not(bit_t* set, size_t low, size_t high) {
assert(set != NULL);
assert(high < set->length);
assert(low <= high);

if (low / 8 < high / 8) {
// Set the most significant bits in byte low/8.
set->bytes[low / 8] ^= kMsbMask[low % 8];

// Set all the bits in bytes low/8+1..high/8-1.
{
for (size_t i = low / 8 + 1; i < high / 8; ++i) {
set->bytes[i] ^= 0xFF;
}
}

// Set the least significant bits in byte high/8.
set->bytes[high / 8] ^= kLsbMask[high % 8];
} else {
// Set bits low%8..high%8 in byte low/8.
set->bytes[low / 8] ^= (kMsbMask[low % 8] & kLsbMask[high % 8]);
}
}

void bit_not(bit_t* set, size_t start, size_t end) {

void bit_map(bit_t* set,
void(*apply)(size_t index, bool is_set, void* user_data),
void* user_data) {
assert(set != NULL);
assert(apply != NULL);

for (size_t i = 0; i < set->length; ++i) {
const bool bit = bit_get_bit(set, i);
apply(i, bit, user_data);
}
}

0 comments on commit 7b988d5

Please sign in to comment.