Block Allocator Test - initial implementation

Summary: Block Allocator Test - initial implementation

Test Plan: ctest -R memgraph_unit_block_allocator

Reviewers: sale

Subscribers: sale, buda

Differential Revision: https://memgraph.phacility.com/D20
This commit is contained in:
Marko Budiselic 2016-12-18 19:21:29 +01:00
parent 948694fd27
commit 4d6c315c1e
7 changed files with 142 additions and 88 deletions

View File

@ -55,3 +55,10 @@ private:
TOKEN_PASTE(auto_, counter)(TOKEN_PASTE(auto_func_, counter));
#define Auto(Destructor) Auto_INTERNAL(Destructor, __COUNTER__)
// -- example:
// Auto(f());
// -- is expended to:
// auto auto_func_1 = [&]() { f(); };
// OnScopeExit<decltype(auto_func_1)> auto_1(auto_func_1);
// -- f() is called at the end of a scope

View File

@ -5,6 +5,9 @@
#include "utils/auto_scope.hpp"
/* @brief Allocates blocks of block_size and stores
* the pointers on allocated blocks inside a vector.
*/
template <size_t block_size>
class BlockAllocator
{
@ -23,29 +26,45 @@ public:
BlockAllocator(size_t capacity = 0)
{
for (size_t i = 0; i < capacity; ++i)
blocks.emplace_back();
unused_.emplace_back();
}
~BlockAllocator()
{
for (auto b : blocks) {
free(b.data);
}
blocks.clear();
for (auto block : unused_)
free(block.data);
unused_.clear();
for (auto block : release_)
free(block.data);
release_.clear();
}
size_t unused_size() const
{
return unused_.size();
}
size_t release_size() const
{
return release_.size();
}
// Returns nullptr on no memory.
void *acquire()
{
if (blocks.size() == 0) blocks.emplace_back();
if (unused_.size() == 0) unused_.emplace_back();
auto ptr = blocks.back().data;
Auto(blocks.pop_back());
auto ptr = unused_.back().data;
Auto(unused_.pop_back());
return ptr;
}
void release(void *ptr) { blocks.emplace_back(ptr); }
void release(void *ptr) { release_.emplace_back(ptr); }
private:
std::vector<Block> blocks;
// TODO: try implement with just one vector
// but consecutive acquire release calls should work
// TODO: measure first!
std::vector<Block> unused_;
std::vector<Block> release_;
};

View File

@ -26,6 +26,8 @@ foreach(test_cpp ${test_type_cpps})
set_target_properties(${target_name} PROPERTIES OUTPUT_NAME ${exec_name})
# link libraries
# gtest
target_link_libraries(${target_name} gtest gtest_main)
# filesystem
target_link_libraries(${target_name} stdc++fs)
# threads (cross-platform)

View File

@ -9,37 +9,34 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wwritable-strings"
using StringHashFunction = std::function<uint64_t(const std::string&)>;
TEST_CASE("BloomFilter Test") {
StringHashFunction hash1 = fnv64<std::string>;
StringHashFunction hash2 = fnv1a64<std::string>;
using StringHashFunction = std::function<uint64_t(const std::string &)>;
auto c = [](auto x) -> int {
return x % 4;
} ;
std::vector<StringHashFunction> funcs = {
hash1, hash2
};
TEST_CASE("BloomFilter Test")
{
StringHashFunction hash1 = fnv64<std::string>;
StringHashFunction hash2 = fnv1a64<std::string>;
BloomFilter<std::string, 64> bloom(funcs);
auto c = [](auto x) -> int { return x % 4; };
std::vector<StringHashFunction> funcs = {hash1, hash2};
std::string test = "test";
std::string kifla = "kifla";
BloomFilter<std::string, 64> bloom(funcs);
std::cout << hash1(test) << std::endl;
std::cout << hash2(test) << std::endl;
std::cout << hash1(kifla) << std::endl;
std::cout << hash2(kifla) << std::endl;
std::string test = "test";
std::string kifla = "kifla";
std::cout << bloom.contains(test) << std::endl;
bloom.insert(test);
std::cout << bloom.contains(test) << std::endl;
std::cout << hash1(test) << std::endl;
std::cout << hash2(test) << std::endl;
std::cout << bloom.contains(kifla) << std::endl;
bloom.insert(kifla);
std::cout << bloom.contains(kifla) << std::endl;
std::cout << hash1(kifla) << std::endl;
std::cout << hash2(kifla) << std::endl;
std::cout << bloom.contains(test) << std::endl;
bloom.insert(test);
std::cout << bloom.contains(test) << std::endl;
std::cout << bloom.contains(kifla) << std::endl;
bloom.insert(kifla);
std::cout << bloom.contains(kifla) << std::endl;
}
#pragma clang diagnostic pop

View File

@ -0,0 +1,24 @@
#include "gtest/gtest.h"
#include "utils/memory/block_allocator.hpp"
TEST(BlockAllocatorTest, UnusedVsReleaseSize)
{
BlockAllocator<64> block_allocator(10);
void *block = block_allocator.acquire();
block_allocator.release(block);
EXPECT_EQ(block_allocator.unused_size(), 9);
EXPECT_EQ(block_allocator.release_size(), 1);
}
TEST(BlockAllocatorTest, CountMallocAndFreeCalls)
{
// TODO: implementation
EXPECT_EQ(true, true);
}
int main(int argc, char **argv)
{
::testing::InitGoogleTest(&argc, argv);
return RUN_ALL_TESTS();
}

View File

@ -8,12 +8,13 @@ using ParameterIndexKey::Type::Projection;
auto main() -> int
{
std::map<ParameterIndexKey, uint64_t> parameter_index;
std::map<ParameterIndexKey, uint64_t> parameter_index;
parameter_index[ParameterIndexKey(InternalId, "n1")] = 0;
parameter_index[ParameterIndexKey(InternalId, "n2")] = 1;
permanent_assert(parameter_index.size() == 2, "Parameter index size should be 2");
permanent_assert(parameter_index.size() == 2,
"Parameter index size should be 2");
return 0;
}

View File

@ -6,80 +6,84 @@
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wwritable-strings"
TEST_CASE("ProgramArgument FlagOnly Test") {
CLEAR_ARGS();
TEST_CASE("ProgramArgument FlagOnly Test")
{
CLEAR_ARGS();
int argc = 2;
char* argv[] = {"ProgramArgument FlagOnly Test", "-test"};
int argc = 2;
char *argv[] = {"ProgramArgument FlagOnly Test", "-test"};
REGISTER_ARGS(argc, argv);
REGISTER_REQUIRED_ARGS({"-test"});
REGISTER_ARGS(argc, argv);
REGISTER_REQUIRED_ARGS({"-test"});
REQUIRE(CONTAINS_FLAG("-test") == true);
REQUIRE(CONTAINS_FLAG("-test") == true);
}
TEST_CASE("ProgramArgument Single Entry Test") {
CLEAR_ARGS();
TEST_CASE("ProgramArgument Single Entry Test")
{
CLEAR_ARGS();
int argc = 3;
char* argv[] = {"ProgramArgument Single Entry Test", "-bananas", "99"};
int argc = 3;
char *argv[] = {"ProgramArgument Single Entry Test", "-bananas", "99"};
REGISTER_REQUIRED_ARGS({"-bananas"});
REGISTER_ARGS(argc, argv);
REGISTER_REQUIRED_ARGS({"-bananas"});
REGISTER_ARGS(argc, argv);
REQUIRE(GET_ARG("-bananas", "100").get_int() == 99);
REQUIRE(GET_ARG("-bananas", "100").get_int() == 99);
}
TEST_CASE("ProgramArgument Multiple Entries Test") {
CLEAR_ARGS();
TEST_CASE("ProgramArgument Multiple Entries Test")
{
CLEAR_ARGS();
int argc = 4;
char* argv[] = {"ProgramArgument Multiple Entries Test", "-files",
"first_file.txt", "second_file.txt"};
int argc = 4;
char *argv[] = {"ProgramArgument Multiple Entries Test", "-files",
"first_file.txt", "second_file.txt"};
REGISTER_ARGS(argc, argv);
REGISTER_ARGS(argc, argv);
auto files = GET_ARGS("-files", {});
auto files = GET_ARGS("-files", {});
REQUIRE(files[0].get_string() == "first_file.txt");
REQUIRE(files[0].get_string() == "first_file.txt");
}
TEST_CASE("ProgramArgument Combination Test") {
CLEAR_ARGS();
TEST_CASE("ProgramArgument Combination Test")
{
CLEAR_ARGS();
int argc = 14;
char* argv[] = {"ProgramArgument Combination Test",
"-run_tests",
"-tests",
"Test1",
"Test2",
"Test3",
"-run_times",
"10",
"-export",
"test1.txt",
"test2.txt",
"test3.txt",
"-import",
"data.txt"};
int argc = 14;
char *argv[] = {"ProgramArgument Combination Test",
"-run_tests",
"-tests",
"Test1",
"Test2",
"Test3",
"-run_times",
"10",
"-export",
"test1.txt",
"test2.txt",
"test3.txt",
"-import",
"data.txt"};
REGISTER_ARGS(argc, argv);
REGISTER_ARGS(argc, argv);
REQUIRE(CONTAINS_FLAG("-run_tests") == true);
REQUIRE(CONTAINS_FLAG("-run_tests") == true);
auto tests = GET_ARGS("-tests", {});
REQUIRE(tests[0].get_string() == "Test1");
REQUIRE(tests[1].get_string() == "Test2");
REQUIRE(tests[2].get_string() == "Test3");
auto tests = GET_ARGS("-tests", {});
REQUIRE(tests[0].get_string() == "Test1");
REQUIRE(tests[1].get_string() == "Test2");
REQUIRE(tests[2].get_string() == "Test3");
REQUIRE(GET_ARG("-run_times", "0").get_int() == 10);
REQUIRE(GET_ARG("-run_times", "0").get_int() == 10);
auto exports = GET_ARGS("-export", {});
REQUIRE(exports[0].get_string() == "test1.txt");
REQUIRE(exports[1].get_string() == "test2.txt");
REQUIRE(exports[2].get_string() == "test3.txt");
auto exports = GET_ARGS("-export", {});
REQUIRE(exports[0].get_string() == "test1.txt");
REQUIRE(exports[1].get_string() == "test2.txt");
REQUIRE(exports[2].get_string() == "test3.txt");
REQUIRE(GET_ARG("-import", "test.txt").get_string() == "data.txt");
REQUIRE(GET_ARG("-import", "test.txt").get_string() == "data.txt");
}
#pragma clang diagnostic pop