Commit b74c9889 authored by Andreas Schmidt's avatar Andreas Schmidt
Browse files

Add bitmap class.

parent 932c8472
add_library(UTIL ../defines.h common.c common.h list.c list.h dbg.h bptree.c bptree.h)
\ No newline at end of file
add_library(UTIL ../defines.h common.c common.h list.c list.h dbg.h bptree.c bptree.h bitmap.c bitmap.h)
set_property(TARGET UTIL PROPERTY C_STANDARD 99)
\ No newline at end of file
#include <stddef.h>
#include <malloc.h>
#include <string.h>
#include <math.h>
#include "bitmap.h"
#include "dbg.h"
#include "common.h"
Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount)
{
Bitmap* bitmap = calloc(1, sizeof(Bitmap));
check_mem(bitmap);
bitmap->count = elementCount;
uint32_t blockCount = (uint32_t) ceil(elementCount / 32.0);
bitmap->data = calloc(blockCount, sizeof(uint32_t));
if(initialValue == true) {
memset(bitmap->data, -1, blockCount * sizeof(uint32_t));
}
return bitmap;
error:
PERROR("Could not create bitmap.%s", "");
return NULL;
}
bool Bitmap_get(Bitmap *bitmap, uint32_t position)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
return (bool) ((bitmap->data[byte_offset] & (1 << bit_offset)) != 0);
}
void Bitmap_set(Bitmap *bitmap, uint32_t position, bool value)
{
uint32_t byte_offset = position / 32;
uint32_t bit_offset = position % 32;
if(value) {
bitmap->data[byte_offset] |= (1 << bit_offset);
} else {
bitmap->data[byte_offset] &= ~(1 << bit_offset);
}
}
void Bitmap_set_range(Bitmap *bitmap, uint32_t start, uint32_t length, bool value)
{
// TODO: highly inefficient - optimize
for(int i = 0; i < length; i++) {
Bitmap_set(bitmap, start + i, value);
}
}
uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t sum = 0;
// TODO: highly inefficient - optimize
for(uint32_t i = 0; i < length; i++) {
sum += (Bitmap_get(bitmap, start + i) == true);
}
return sum;
}
uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length)
{
uint32_t sum = 0;
// TODO: highly inefficient - optimize
for(uint32_t i = 0; i < length; i++) {
sum += (Bitmap_get(bitmap, start + i) == false);
}
return sum;
}
bool Bitmap_destroy(Bitmap *bitmap)
{
free(bitmap->data);
return true;
}
#ifndef PRRT_BITMAP_H
#define PRRT_BITMAP_H
#include <stdint.h>
#include <stdbool.h>
typedef struct bitmap {
uint32_t* data;
uint32_t count;
} Bitmap;
Bitmap *Bitmap_create(bool initialValue, uint32_t elementCount);
bool Bitmap_get(Bitmap* bitmap, uint32_t position);
void Bitmap_set(Bitmap* bitmap, uint32_t position, bool value);
void Bitmap_set_range(Bitmap *bitmap, uint32_t start, uint32_t length, bool value);
uint32_t Bitmap_sum_ones(Bitmap *bitmap, uint32_t start, uint32_t length);
uint32_t Bitmap_sum_zeros(Bitmap *bitmap, uint32_t start, uint32_t length);
bool Bitmap_destroy(Bitmap* bitmap);
#endif //PRRT_BITMAP_H
add_subdirectory(lib/gtest-1.7.0)
include_directories(SYSTEM ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
add_executable(prrtTests forward_packet_table_tests.cpp bptree_tests.cpp PrrtBlock_tests.cpp)
add_executable(prrtTests bitmap_tests.cpp forward_packet_table_tests.cpp bptree_tests.cpp PrrtBlock_tests.cpp)
set_property(TARGET prrtTests PROPERTY C_STANDARD 99)
target_link_libraries(prrtTests LINK_PUBLIC PRRT UTIL gtest gtest_main)
\ No newline at end of file
#include <gtest/gtest.h>
extern "C" {
#include "src/util/bitmap.h"
}
class BitmapTest : public ::testing::Test {
protected:
virtual void SetUp()
{
size = 65536;
bitmap = Bitmap_create(true, size);
}
virtual void TearDown()
{
Bitmap_destroy(bitmap);
}
Bitmap *bitmap;
uint32_t size;
};
TEST_F(BitmapTest, CreateWithCorrectInitValue)
{
Bitmap *bitmap = Bitmap_create(false, size);
ASSERT_EQ(size, bitmap->count);
ASSERT_EQ(false, Bitmap_get(bitmap, 5));
Bitmap_destroy(bitmap);
bitmap = Bitmap_create(true, size);
ASSERT_EQ(true, Bitmap_get(bitmap, 5));
Bitmap_destroy(bitmap);
}
TEST_F(BitmapTest, GetSet)
{
Bitmap *bitmap = Bitmap_create(true, size);
ASSERT_TRUE(Bitmap_get(bitmap, 17));
Bitmap_set(bitmap, 17, false);
ASSERT_FALSE(Bitmap_get(bitmap, 17));
Bitmap_destroy(bitmap);
}
TEST_F(BitmapTest, GetRange)
{
ASSERT_EQ(5, Bitmap_sum_ones(bitmap, 1, 5));
ASSERT_EQ(0, Bitmap_sum_zeros(bitmap, 1, 5));
Bitmap_set(bitmap, 2, false);
Bitmap_set(bitmap, 4, false);
ASSERT_EQ(3, Bitmap_sum_ones(bitmap, 1, 5));
ASSERT_EQ(2, Bitmap_sum_zeros(bitmap, 1, 5));
}
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));
}
\ No newline at end of file
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment