From: Mike D. Lowis Date: Thu, 11 Apr 2013 19:47:14 +0000 (-0400) Subject: Updated vector to allocate in powers of 2 X-Git-Url: https://git.mdlowis.com/?a=commitdiff_plain;h=d98a68159061bab3666dee6b6099c4fd5ce3741b;p=projs%2Flibcds.git Updated vector to allocate in powers of 2 --- diff --git a/source/vector/vec.c b/source/vector/vec.c index 19f9f23..298f685 100644 --- a/source/vector/vec.c +++ b/source/vector/vec.c @@ -1,8 +1,8 @@ /** - @file vec.c - @brief See header for details - $Revision$ - $HeadURL$ + @file vec.c + @brief See header for details + $Revision$ + $HeadURL$ */ #include "vec.h" #include @@ -70,7 +70,7 @@ void vec_resize(vec_t* p_vec, size_t size, void* data) { if (size > p_vec->size) { - vec_reserve(p_vec,size); + vec_reserve(p_vec,vec_next_capacity(size)); for (p_vec->size; p_vec->size < size; p_vec->size++) { p_vec->p_buffer[ p_vec->size ] = data; @@ -84,6 +84,23 @@ void vec_resize(vec_t* p_vec, size_t size, void* data) } } +size_t vec_next_capacity(size_t req_size) +{ + size_t next_power = req_size; + size_t num_bits = sizeof(size_t) * 8; + size_t bit_n; + + /* Find the next highest power of 2 */ + next_power--; + for (bit_n = 1; bit_n < num_bits; bit_n = bit_n << 1) + { + next_power = next_power | (next_power >> bit_n); + } + next_power++; + + return next_power; +} + void vec_shrink_to_fit(vec_t* p_vec) { p_vec->p_buffer = realloc( p_vec->p_buffer, sizeof(void*) * p_vec->size ); @@ -133,8 +150,8 @@ bool vec_insert(vec_t* p_vec, size_t index, size_t num_elements, ...) vec_resize( p_vec, p_vec->size + num_elements, NULL ); /* Move the displaced items to the end */ memcpy( &(p_vec->p_buffer[index + num_elements]), - &(p_vec->p_buffer[index]), - sizeof(void*) * (p_vec->size - index)); + &(p_vec->p_buffer[index]), + sizeof(void*) * (p_vec->size - index)); /* insert the new items */ va_start(elements, num_elements); new_size = index + num_elements; @@ -162,8 +179,8 @@ bool vec_erase(vec_t* p_vec, size_t start_idx, size_t end_idx) } /* Compact the remaining data */ memcpy( &(p_vec->p_buffer[start_idx]), /* Destination is beginning of erased range */ - &(p_vec->p_buffer[end_idx+1]), /* Source is end of erased range */ - sizeof(void*) * (p_vec->size - end_idx)); + &(p_vec->p_buffer[end_idx+1]), /* Source is end of erased range */ + sizeof(void*) * (p_vec->size - end_idx)); /* Shrink the size */ p_vec->size = p_vec->size - ((end_idx - start_idx) + 1); ret = true; diff --git a/source/vector/vec.h b/source/vector/vec.h index 99125ae..aa9d2d7 100644 --- a/source/vector/vec.h +++ b/source/vector/vec.h @@ -91,6 +91,15 @@ bool vec_empty(vec_t* p_vec); */ void vec_resize(vec_t* p_vec, size_t size, void* data); +/** + * @brief Returns the next power of two that is not less than the desired size. + * + * @param req_size The desired size of the vector. + * + * @return The necessary capacity. + */ +size_t vec_next_capacity(size_t req_size); + /** * @brief Shrinks the vector's capacity to equal it's size. * diff --git a/tests/test_vec.cpp b/tests/test_vec.cpp index 4897aaa..8711815 100644 --- a/tests/test_vec.cpp +++ b/tests/test_vec.cpp @@ -145,7 +145,7 @@ namespace { CHECK( false == p_vec->own_contents ); CHECK( 5 == p_vec->size ); - CHECK( 5 == p_vec->capacity ); + CHECK( 8 == p_vec->capacity ); CHECK( (void*)0x2A == p_vec->p_buffer[3] ); CHECK( (void*)0x2A == p_vec->p_buffer[4] ); @@ -378,4 +378,26 @@ namespace { vec_clear( &vector ); CHECK(0 == vector.size); } + + //TEST(foo) + //{ + // size_t next_power = 9; + // size_t num_bits = sizeof(size_t) * 8; + // size_t bit_n; + + // next_power--; + // for (bit_n = 1; bit_n < num_bits; bit_n = bit_n << 1) + // { + // next_power = next_power | (next_power >> bit_n); + // } + // next_power++; + + // std::cout << next_power << std::endl; + + // //int n = 7; + // //int exp = 0; + // //while(n>1) { n = n>>1; exp++; } + // //while(exp>=0) { n = n<<1; exp--; } + // //std::cout << n << " " << exp << std::endl; + //} }