Loading prrt/util/bitmap.c +55 −16 Original line number Diff line number Diff line Loading @@ -28,32 +28,71 @@ Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount) void Bitmap_set_range_0(Bitmap *bitmap, uint32_t start, uint32_t length) { uint32_t i = 0; // TODO: highly inefficient - optimize for(i = 0; i < length; i++) { Bitmap_set_0(bitmap, start + i); uint32_t start_byte = start / 32; uint32_t start_bit = start % 32; uint32_t end_byte = (start + length) / 32; uint32_t end_bit = (start + length) % 32; uint32_t full_mask = ~0u; if (start_byte == end_byte) { uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit); bitmap->data[start_byte] ^= (bitmap->data[start_byte] & mask); } else { uint32_t start_mask = full_mask << start_bit; bitmap->data[start_byte] ^= (bitmap->data[start_byte] & start_mask); for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) { bitmap->data[current_byte] = 0; } uint32_t end_mask = ~(full_mask << end_bit); bitmap->data[end_byte] ^= (bitmap->data[end_byte] & end_mask); } } void Bitmap_set_range_1(Bitmap *bitmap, uint32_t start, uint32_t length) { uint32_t i = 0; // TODO: highly inefficient - optimize for(i = 0; i < length; i++) { Bitmap_set_1(bitmap, start + i); uint32_t start_byte = start / 32; uint32_t start_bit = start % 32; uint32_t end_byte = (start + length) / 32; uint32_t end_bit = (start + length) % 32; uint32_t full_mask = ~0u; if (start_byte == end_byte) { uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit); bitmap->data[start_byte] |= mask; } else { uint32_t start_mask = full_mask << start_bit; bitmap->data[start_byte] |= start_mask; for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) { bitmap->data[current_byte] = full_mask; } uint32_t end_mask = ~(full_mask << end_bit); bitmap->data[end_byte] |= end_mask; } } uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length) { uint32_t sum = 0; uint32_t i = 0; // TODO: highly inefficient - optimize for(i = 0; i < length; i++) { sum += (Bitmap_get(bitmap, start + i) == true); uint32_t start_byte = start / 32; uint32_t start_bit = start % 32; uint32_t end_byte = (start + length) / 32; uint32_t end_bit = (start + length) % 32; uint32_t full_mask = ~0u; if (start_byte == end_byte) { uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit); return __builtin_popcount(bitmap->data[start_byte] & mask); } else { uint32_t start_mask = full_mask << start_bit; uint32_t sum = __builtin_popcount(bitmap->data[start_byte] & start_mask); for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) { sum += __builtin_popcount(bitmap->data[current_byte]); } uint32_t end_mask = ~(full_mask << end_bit); sum += __builtin_popcount(bitmap->data[end_byte] & end_mask); return sum; } } uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length) { Loading tests/bitmap_tests.cpp +18 −8 Original line number Diff line number Diff line Loading @@ -54,12 +54,22 @@ TEST_F(BitmapTest, GetRange) TEST_F(BitmapTest, SetRange) { ASSERT_EQ(5, Bitmap_sum_ones(bitmap, 1, 5)); ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 1, 5)); Bitmap_set_range(bitmap, 2, 2, false); ASSERT_FALSE(Bitmap_get(bitmap, 2)); ASSERT_FALSE(Bitmap_get(bitmap, 3)); ASSERT_TRUE(Bitmap_get(bitmap, 4)); ASSERT_EQ(3, Bitmap_sum_ones(bitmap, 1, 5)); ASSERT_EQ(2, Bitmap_sum_zeros(bitmap, 1, 5)); ASSERT_EQ(500, Bitmap_sum_ones(bitmap, 17, 500)); ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 17, 500)); Bitmap_set_range(bitmap, 2, 300, false); ASSERT_TRUE(Bitmap_get(bitmap, 1)); for (int i = 2; i < 302; ++i) { ASSERT_FALSE(Bitmap_get(bitmap, i)); } ASSERT_TRUE(Bitmap_get(bitmap, 302)); Bitmap_set_range(bitmap, 150, 100, true); ASSERT_FALSE(Bitmap_get(bitmap, 149)); for (int i = 150; i < 250; ++i) { ASSERT_TRUE(Bitmap_get(bitmap, i)); } ASSERT_FALSE(Bitmap_get(bitmap, 250)); ASSERT_EQ(300, Bitmap_sum_ones(bitmap, 1, 500)); ASSERT_EQ(200, Bitmap_sum_zeros(bitmap, 1, 500)); } Loading
prrt/util/bitmap.c +55 −16 Original line number Diff line number Diff line Loading @@ -28,32 +28,71 @@ Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount) void Bitmap_set_range_0(Bitmap *bitmap, uint32_t start, uint32_t length) { uint32_t i = 0; // TODO: highly inefficient - optimize for(i = 0; i < length; i++) { Bitmap_set_0(bitmap, start + i); uint32_t start_byte = start / 32; uint32_t start_bit = start % 32; uint32_t end_byte = (start + length) / 32; uint32_t end_bit = (start + length) % 32; uint32_t full_mask = ~0u; if (start_byte == end_byte) { uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit); bitmap->data[start_byte] ^= (bitmap->data[start_byte] & mask); } else { uint32_t start_mask = full_mask << start_bit; bitmap->data[start_byte] ^= (bitmap->data[start_byte] & start_mask); for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) { bitmap->data[current_byte] = 0; } uint32_t end_mask = ~(full_mask << end_bit); bitmap->data[end_byte] ^= (bitmap->data[end_byte] & end_mask); } } void Bitmap_set_range_1(Bitmap *bitmap, uint32_t start, uint32_t length) { uint32_t i = 0; // TODO: highly inefficient - optimize for(i = 0; i < length; i++) { Bitmap_set_1(bitmap, start + i); uint32_t start_byte = start / 32; uint32_t start_bit = start % 32; uint32_t end_byte = (start + length) / 32; uint32_t end_bit = (start + length) % 32; uint32_t full_mask = ~0u; if (start_byte == end_byte) { uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit); bitmap->data[start_byte] |= mask; } else { uint32_t start_mask = full_mask << start_bit; bitmap->data[start_byte] |= start_mask; for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) { bitmap->data[current_byte] = full_mask; } uint32_t end_mask = ~(full_mask << end_bit); bitmap->data[end_byte] |= end_mask; } } uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length) { uint32_t sum = 0; uint32_t i = 0; // TODO: highly inefficient - optimize for(i = 0; i < length; i++) { sum += (Bitmap_get(bitmap, start + i) == true); uint32_t start_byte = start / 32; uint32_t start_bit = start % 32; uint32_t end_byte = (start + length) / 32; uint32_t end_bit = (start + length) % 32; uint32_t full_mask = ~0u; if (start_byte == end_byte) { uint32_t mask = (full_mask << end_bit) ^ (full_mask << start_bit); return __builtin_popcount(bitmap->data[start_byte] & mask); } else { uint32_t start_mask = full_mask << start_bit; uint32_t sum = __builtin_popcount(bitmap->data[start_byte] & start_mask); for (uint32_t current_byte = start_byte + 1; current_byte < end_byte; ++current_byte) { sum += __builtin_popcount(bitmap->data[current_byte]); } uint32_t end_mask = ~(full_mask << end_bit); sum += __builtin_popcount(bitmap->data[end_byte] & end_mask); return sum; } } uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length) { Loading
tests/bitmap_tests.cpp +18 −8 Original line number Diff line number Diff line Loading @@ -54,12 +54,22 @@ TEST_F(BitmapTest, GetRange) TEST_F(BitmapTest, SetRange) { ASSERT_EQ(5, Bitmap_sum_ones(bitmap, 1, 5)); ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 1, 5)); Bitmap_set_range(bitmap, 2, 2, false); ASSERT_FALSE(Bitmap_get(bitmap, 2)); ASSERT_FALSE(Bitmap_get(bitmap, 3)); ASSERT_TRUE(Bitmap_get(bitmap, 4)); ASSERT_EQ(3, Bitmap_sum_ones(bitmap, 1, 5)); ASSERT_EQ(2, Bitmap_sum_zeros(bitmap, 1, 5)); ASSERT_EQ(500, Bitmap_sum_ones(bitmap, 17, 500)); ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 17, 500)); Bitmap_set_range(bitmap, 2, 300, false); ASSERT_TRUE(Bitmap_get(bitmap, 1)); for (int i = 2; i < 302; ++i) { ASSERT_FALSE(Bitmap_get(bitmap, i)); } ASSERT_TRUE(Bitmap_get(bitmap, 302)); Bitmap_set_range(bitmap, 150, 100, true); ASSERT_FALSE(Bitmap_get(bitmap, 149)); for (int i = 150; i < 250; ++i) { ASSERT_TRUE(Bitmap_get(bitmap, i)); } ASSERT_FALSE(Bitmap_get(bitmap, 250)); ASSERT_EQ(300, Bitmap_sum_ones(bitmap, 1, 500)); ASSERT_EQ(200, Bitmap_sum_zeros(bitmap, 1, 500)); }