Browse Source

Merge master

devel
Ludovic 'Archivist' Lagouardette 4 years ago
parent
commit
7b2395a419
14 changed files with 341 additions and 19 deletions
  1. +6
    -0
      .vscode/settings.json
  2. +1
    -1
      Makefile
  3. +5
    -4
      include/gp/algorithm/move.hpp
  4. +2
    -2
      include/gp/algorithm/tmp_manip.hpp
  5. +8
    -6
      include/gp/allocator/arena.hpp
  6. +1
    -1
      include/gp/array.hpp
  7. +1
    -1
      include/gp/buffer.hpp
  8. +72
    -0
      include/gp/pair.hpp
  9. +1
    -0
      include/gp/quotient_filter.hpp
  10. +11
    -2
      include/gp/ring_list.hpp
  11. +1
    -0
      tests.cpp
  12. +130
    -1
      tests/gp_test.cpp
  13. +35
    -0
      tests/pair_test.cpp
  14. +67
    -1
      tests/quotient_filter.cpp

+ 6
- 0
.vscode/settings.json View File

@ -0,0 +1,6 @@
{
"clang.cflags": [
"-std=c++17",
"-I${workspaceRoot}/include"
]
}

+ 1
- 1
Makefile View File

@ -1,4 +1,4 @@
CXX= clang++-8
CXX= clang++-10
CXXFLAGS= --std=c++17 -O0 -pthread -DGP_TESTS -DFUZZ_STRENGTH=500 -pedantic -Werror \
-Wno-unknown-attributes -frtti \
-g -fprofile-instr-generate -fcoverage-mapping \

+ 5
- 4
include/gp/algorithm/move.hpp View File

@ -58,11 +58,12 @@ namespace gp{
return nameless_range<typename range_out::associated_iterator>{out, dest.end()};
}
template<typename T, typename range_in, typename range_out>
nameless_range<typename range_out::associated_iterator> move_uninitialized(range_in src, range_out dest)
template<typename range_in, typename range_out>
nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator> move_uninitialized(range_in&& src, range_out&& dest)
{
using T = typename gp::remove_reference<decltype(*dest.begin())>::type;
if(src.size()>dest.size())
return nameless_range<typename range_out::associated_iterator>(dest.begin(), dest.end());
return nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator>(dest.begin(), dest.end());
auto in = src.begin();
auto in_close = src.end();
auto out = dest.begin();
@ -70,6 +71,6 @@ namespace gp{
{
new(&*(out++)) T{gp::move(*(in++))};
}
return nameless_range<typename range_out::associated_iterator>{out, dest.end()};
return nameless_range<typename gp::remove_reference<range_out>::type::associated_iterator>{out, dest.end()};
}
}

+ 2
- 2
include/gp/algorithm/tmp_manip.hpp View File

@ -202,7 +202,7 @@ namespace gp{
typedef std::true_type yes;
typedef std::false_type no;
template<typename U, void* (U::*f)(size_t) const> struct SFINAE{};
template<typename U, void* (U::*f)(size_t)> struct SFINAE{};
template<class C> static yes test(SFINAE<C,&C::allocate>*);
@ -219,7 +219,7 @@ namespace gp{
typedef std::true_type yes;
typedef std::false_type no;
template<typename U, void (U::*f)(void*) const> struct SFINAE{};
template<typename U, bool (U::*f)(void*)> struct SFINAE{};
template<class C> static yes test(SFINAE<C,&C::deallocate>*);

+ 8
- 6
include/gp/allocator/arena.hpp View File

@ -7,7 +7,7 @@
namespace gp{
template<typename page_allocator, size_t align = 1>
template<typename page_allocator = int, size_t align = 1>
class arena{
page_allocator allocator;
gp::buffer<char> data;
@ -20,18 +20,20 @@ namespace gp{
,data(gp::buffer<char>(nullptr,nullptr))
{}
template<typename T = typename std::enable_if<gp::has_allocator_interface<page_allocator>::value,int>::type>
arena(size_t sz)
:last(0)
,count(0)
,data(nullptr,nullptr)
{
if(sz!=0)
if constexpr (gp::has_allocator_interface<page_allocator>::value)
{
auto v=allocator.allocate(sz);
if(v!=nullptr)
if(sz!=0)
{
data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
auto v=allocator.allocate(sz);
if(v!=nullptr)
{
data=gp::buffer<char>(reinterpret_cast<char*>(v),reinterpret_cast<char*>(v)+sz);
}
}
}
}

+ 1
- 1
include/gp/array.hpp View File

@ -33,7 +33,7 @@ namespace gp{
array(array&& values)
{
gp::move_uninitializedo"><T>(
gp::move_uninitialized(
values,
*this
);

+ 1
- 1
include/gp/buffer.hpp View File

@ -81,7 +81,7 @@ namespace gp{
}
else
{
if(size()*sizeof(T)o">/sizeof(U))
if(p">(size()*sizeof(T)p">)%sizeof(U) == 0)
{
return buffer<U>(reinterpret_cast<U*>(&*begin_elem), size()*sizeof(T)/sizeof(U));
}

+ 72
- 0
include/gp/pair.hpp View File

@ -0,0 +1,72 @@
#pragma once
#include "gp/algorithm/move.hpp"
namespace gp{
template<typename T1, typename T2>
struct pair{
T1 first;
T2 second;
pair() : first(), second() {}
pair(const T1& a, const T2& b) : first(a), second(b) {}
pair(pair&& v)
: first(gp::move(v.first))
, second(gp::move(v.second))
{}
template<typename U1, typename U2>
pair(U1&& a, U2&& b)
: first(gp::forward<U1>(a))
, second(gp::forward<U2>(b))
{}
template<typename U1, typename U2>
pair(pair<U1, U2>&& v)
: first(gp::move(v.first))
, second(gp::move(v.second))
{}
pair& operator=(pair&& v)
{
first = gp::move(v.first);
second = gp::move(v.second);
return *this;
}
bool operator==(const pair& rhs) {
return first == rhs.first and second == rhs.second;
}
bool operator!=(const pair& rhs) {
return first != rhs.first or second != rhs.second;
}
bool operator<=(const pair& rhs) {
if(first > rhs.first) {
return false;
} else if(first == rhs.first) {
return second <= rhs.second;
}
return true;
}
bool operator>=(const pair& rhs) {
if(first < rhs.first) {
return false;
} else if(first == rhs.first) {
return second >= rhs.second;
}
return true;
}
bool operator<(const pair& rhs) {
return !(*this >= rhs);
}
bool operator>(const pair& rhs) {
return !(*this <= rhs);
}
};
}

+ 1
- 0
include/gp/quotient_filter.hpp View File

@ -193,6 +193,7 @@ namespace gp {
if(slot.r == r)
{
slot.is_deleted = true;
slot.is_occupied = false;
}
}
skip.next();

+ 11
- 2
include/gp/ring_list.hpp View File

@ -95,13 +95,22 @@ namespace gp {
, alloc{_alloc}
{}
ring_list(allocator& _alloc)
: any_node{nullptr}
, sz{0}
, alloc{_alloc}
{}
template<typename V = T, typename ...Args>
bool insert(Args&&... elem) {
allocator& used_allocator = alloc;
void* mem = used_allocator.allocate(sizeof(V));
void* mem;
[[unlikely]] if(
nullptr == (mem = used_allocator.allocate(sizeof(V)))
) return false;
T* p = new(mem) V(elem...);
node* to_insert = nullptr;
if(
na">[[unlikely]] if(
nullptr == (to_insert = reinterpret_cast<node*>(used_allocator.allocate(sizeof(node))))
) return false;
to_insert = new(to_insert) node(p);

+ 1
- 0
tests.cpp View File

@ -8,6 +8,7 @@
#include "bloomfilter.cpp"
#include "quotient_filter.cpp"
#include "math.cpp"
#include "pair_test.cpp"
#include <iostream>
alignas(2048) gp::array<char, 4096> static_mapper::store;

+ 130
- 1
tests/gp_test.cpp View File

@ -3,10 +3,12 @@
#include "gp/array.hpp"
#include "gp/indexed_array.hpp"
#include "gp/allocator/aggregator.hpp"
#include "gp/allocator/arena.hpp"
#include "gp/allocator/buddy.hpp"
#include "gp/allocator/dummy.hpp"
#include "gp/algorithm/repeat.hpp"
#include "gp/algorithm/rotate.hpp"
#include "gp/algorithm/move.hpp"
#include "gp/ring_list.hpp"
#include <thread>
#include <chrono>
@ -415,6 +417,35 @@ struct aggregator_test : public test_scaffold {
}
auto duration = std::chrono::steady_clock::now() - start;
}
void* a = allocator.allocate(8);
gp_config::assertion(allocator.try_reallocate(a, 16) == false, "could reallocate? was it implemented?");
gp_config::assertion(allocator.deallocate(nullptr) == false, "error, could free an invalid pointer");
allocator.deallocate(a);
{
gp::ring_list<int, gp::aggregator, false> list{allocator};
list.insert(8);
list.insert(16);
list.insert(32);
}
{
gp::array<char, 256> work_array;
gp::arena<> alloc_work(work_array.begin().data, work_array.size());
gp::ring_list<int, gp::arena<>, false> list{alloc_work};
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
gp_config::assertion(list.insert(8) == true, "could allocate in list with good enough allocator");
}
{
gp::array<char, sizeof(int)> once_array;
gp::arena<> alloc_once(once_array.begin().data, once_array.size());
gp::ring_list<int, gp::arena<>, false> list{alloc_once};
gp_config::assertion(list.insert(8) == false, "could allocate in list with insufficient allocator");
}
{
gp::arena<> alloc_none(nullptr, 0);
gp::ring_list<int, gp::arena<>, false> list{alloc_none};
gp_config::assertion(list.insert(8) == false, "could allocate in list with fake allocator");
}
return res;
}
};
@ -531,4 +562,102 @@ struct indexed_array_test : public test_scaffold {
}
};
append_test dummy_khxurgsd3(new indexed_array_test{});
append_test dummy_khxurgsd3(new indexed_array_test{});
struct move_uninitialized_test : public test_scaffold {
move_uninitialized_test() {
name = __FILE__ ":8";
}
struct tester {
size_t* const incremented;
tester(size_t* ptr)
: incremented(ptr)
{}
tester(tester&& oth)
: incremented(oth.incremented)
{
++*incremented;
}
};
virtual int run() {
int res = 0;
{
size_t counter;
using src_t = gp::array<tester, 16>;
src_t *source = reinterpret_cast<src_t*>(malloc(sizeof(src_t)));
gp::array<char, sizeof(tester)*16> buffer;
for(auto& a : *source) {
new(&a) tester(&counter);
}
gp::move_uninitialized(*source, buffer.as_buffer().cast<tester>());
free(source);
}
return res;
}
};
append_test dummy_hkfyr5f5(new move_uninitialized_test{});
struct clamp_test : public test_scaffold {
clamp_test() {
name = __FILE__ ":9";
}
virtual int run() {
int res = 0;
{
res += gp::clamp<float>(0.0, -1.0, 1.0);
res += gp::clamp<float>(-1.0, 1.0, 0.0);
res += gp::max(-1, -2, 0, -3);
}
return res;
}
};
append_test dummy_gsdh25f5(new clamp_test{});
struct buffer_test : public test_scaffold {
buffer_test() {
name = __FILE__ ":10";
}
virtual int run() {
int res = 0;
{
gp::array<char, 24> data;
gp::array<char, 24> data_e;
gp::buffer<char> handle = data.as_buffer();
handle[12] = '&';
gp_config::assertion(*(handle.begin()+12) == '&', "Could not assign to the buffer");
res += 1;
try {
handle[24] = 16;
res += 1;
handle[-1] = 16;
res += 1;
handle[1024] = 16;
} catch (...) {
res -= 1;
}
res += 1;
try {
auto cast = handle.cast<gp::array<char, 32>>();
} catch (...) {
res -= 1;
}
auto cast = handle.template cast<gp::array<char, 6>>().template cast<gp::array<char, 4>>();
gp_config::assertion(false == (data == data_e), "Different arrays should return false here");
}
return res;
}
};
append_test dummy_gs87ytf5f5(new buffer_test{});

+ 35
- 0
tests/pair_test.cpp View File

@ -0,0 +1,35 @@
#include "test_scaffold.h"
#include <random>
#include <string>
#include "gp/pair.hpp"
typedef std::mt19937_64 cheap_rand;
struct pair_test : public test_scaffold {
uint32_t seed;
pair_test() {
seed = std::random_device{}();
name = __FILE__ ":1_seed";
name += std::to_string(seed);
}
virtual int run() {
cheap_rand setter(seed);
gp::pair<double, std::string> v{0, "zero"};
bool result = true;
for(int i = 0 ; i < 100; i++)
{
auto a = setter();
v = gp::pair(a, std::to_string(a));
result = gp::pair<double, std::string>(a, std::to_string(a)) == v ? result : false;
}
return !result;
}
};
append_test dummy_rsly21r43(new pair_test{});

+ 67
- 1
tests/quotient_filter.cpp View File

@ -124,4 +124,70 @@ struct qfilter3_test : public test_scaffold {
}
};
append_test dummy_kjdflu3(new qfilter3_test{});
append_test dummy_kjdflu3(new qfilter3_test{});
struct qfilter4_test : public test_scaffold {
qfilter4_test() {
}
virtual int run() {
gp::quotient_filter<> test_filter;
for(int a = 0 ; a < 10000; a++)
{
test_filter.set_hash(a);
}
for(int a = 0 ; a < 10000; a++)
{
test_filter.remove_hash(a);
}
for(int a = 0 ; a < 10000; a++)
{
gp_config::assertion(!test_filter.test_hash(a), "everything should have been removed");
}
for(int a = 0 ; a < 10000; a++)
{
test_filter.set_hash(a);
}
for(int a = 0 ; a < 10000; a++)
{
gp_config::assertion(test_filter.test_hash(a), "everything should have been set");
}
return 0;
}
};
append_test dummy_kj54ghu3(new qfilter4_test{});
struct qfilter5_test : public test_scaffold {
qfilter5_test() {
}
virtual int run() {
gp::quotient_filter<uint32_t, 16> test_filter;
for(int a = 0 ; a < 65536; a++)
{
test_filter.set_hash(a);
}
int res = 1;
try {
test_filter.set_hash(123456);
} catch(gp::runtime_error e) {
res = 0;
}
return res;
}
};
append_test dummy_k65421u3(new qfilter5_test{});

Loading…
Cancel
Save