Remove b++ tree

This commit is contained in:
jbajic 2022-11-29 14:40:44 +01:00
parent 632db4175a
commit 1f98d33fa6
9 changed files with 1 additions and 3994 deletions

View File

@ -68,9 +68,6 @@ target_link_libraries(${test_prefix}storage_v2_property_store mg-storage-v2)
add_benchmark(future.cpp)
target_link_libraries(${test_prefix}future mg-io)
add_benchmark(data_structures_random.cpp)
target_link_libraries(${test_prefix}data_structures_random mg-utils)
add_benchmark(data_structures_insert.cpp)
target_link_libraries(${test_prefix}data_structures_insert mg-utils mg-storage-v3)

File diff suppressed because it is too large Load Diff

View File

@ -1,475 +0,0 @@
/*******************************************************************************
* tlx/container/btree_map.hpp
*
* Part of tlx - http://panthema.net/tlx
*
* Copyright (C) 2008-2017 Timo Bingmann <tb@panthema.net>
*
* All rights reserved. Published under the Boost Software License, Version 1.0
******************************************************************************/
#ifndef TLX_CONTAINER_BTREE_MAP_HEADER
#define TLX_CONTAINER_BTREE_MAP_HEADER
#include <functional>
#include <memory>
#include <utility>
#include "btree.hpp"
namespace tlx {
//! \addtogroup tlx_container_btree
//! \{
/*!
* Specialized B+ tree template class implementing STL's map container.
*
* Implements the STL map using a B+ tree. It can be used as a drop-in
* replacement for std::map. Not all asymptotic time requirements are met in
* theory. The class has a traits class defining B+ tree properties like slots
* and self-verification. Furthermore an allocator can be specified for tree
* nodes.
*/
template <typename Key_, typename Data_, typename Compare_ = std::less<Key_>,
typename Traits_ = btree_default_traits<Key_, std::pair<Key_, Data_>>,
typename Alloc_ = std::allocator<std::pair<Key_, Data_>>>
class btree_map {
public:
//! \name Template Parameter Types
//! \{
//! First template parameter: The key type of the btree. This is stored in
//! inner nodes.
typedef Key_ key_type;
//! Second template parameter: The value type associated with each key.
//! Stored in the B+ tree's leaves
typedef Data_ data_type;
//! Third template parameter: Key comparison function object
typedef Compare_ key_compare;
//! Fourth template parameter: Traits object used to define more parameters
//! of the B+ tree
typedef Traits_ traits;
//! Fifth template parameter: STL allocator
typedef Alloc_ allocator_type;
//! \}
// The macro TLX_BTREE_FRIENDS can be used by outside class to access the B+
// tree internals. This was added for wxBTreeDemo to be able to draw the
// tree.
TLX_BTREE_FRIENDS;
public:
//! \name Constructed Types
//! \{
//! Typedef of our own type
typedef btree_map<key_type, data_type, key_compare, traits, allocator_type> self;
//! Construct the STL-required value_type as a composition pair of key and
//! data types
typedef std::pair<key_type, data_type> value_type;
//! Key Extractor Struct
struct key_of_value {
//! pull first out of pair
static const key_type &get(const value_type &v) { return v.first; }
};
//! Implementation type of the btree_base
typedef BTree<key_type, value_type, key_of_value, key_compare, traits, false, allocator_type> btree_impl;
//! Function class comparing two value_type pairs.
typedef typename btree_impl::value_compare value_compare;
//! Size type used to count keys
typedef typename btree_impl::size_type size_type;
//! Small structure containing statistics about the tree
typedef typename btree_impl::tree_stats tree_stats;
//! \}
public:
//! \name Static Constant Options and Values of the B+ Tree
//! \{
//! Base B+ tree parameter: The number of key/data slots in each leaf
static const unsigned short leaf_slotmax = btree_impl::leaf_slotmax;
//! Base B+ tree parameter: The number of key slots in each inner node,
//! this can differ from slots in each leaf.
static const unsigned short inner_slotmax = btree_impl::inner_slotmax;
//! Computed B+ tree parameter: The minimum number of key/data slots used
//! in a leaf. If fewer slots are used, the leaf will be merged or slots
//! shifted from it's siblings.
static const unsigned short leaf_slotmin = btree_impl::leaf_slotmin;
//! Computed B+ tree parameter: The minimum number of key slots used
//! in an inner node. If fewer slots are used, the inner node will be
//! merged or slots shifted from it's siblings.
static const unsigned short inner_slotmin = btree_impl::inner_slotmin;
//! Debug parameter: Enables expensive and thorough checking of the B+ tree
//! invariants after each insert/erase operation.
static const bool self_verify = btree_impl::self_verify;
//! Debug parameter: Prints out lots of debug information about how the
//! algorithms change the tree. Requires the header file to be compiled
//! with TLX_BTREE_DEBUG and the key type must be std::ostream printable.
static const bool debug = btree_impl::debug;
//! Operational parameter: Allow duplicate keys in the btree.
static const bool allow_duplicates = btree_impl::allow_duplicates;
//! \}
public:
//! \name Iterators and Reverse Iterators
//! \{
//! STL-like iterator object for B+ tree items. The iterator points to a
//! specific slot number in a leaf.
typedef typename btree_impl::iterator iterator;
//! STL-like iterator object for B+ tree items. The iterator points to a
//! specific slot number in a leaf.
typedef typename btree_impl::const_iterator const_iterator;
//! create mutable reverse iterator by using STL magic
typedef typename btree_impl::reverse_iterator reverse_iterator;
//! create constant reverse iterator by using STL magic
typedef typename btree_impl::const_reverse_iterator const_reverse_iterator;
//! \}
private:
//! \name Tree Implementation Object
//! \{
//! The contained implementation object
btree_impl tree_;
//! \}
public:
//! \name Constructors and Destructor
//! \{
//! Default constructor initializing an empty B+ tree with the standard key
//! comparison function
explicit btree_map(const allocator_type &alloc = allocator_type()) : tree_(alloc) {}
//! Constructor initializing an empty B+ tree with a special key
//! comparison object
explicit btree_map(const key_compare &kcf, const allocator_type &alloc = allocator_type()) : tree_(kcf, alloc) {}
//! Constructor initializing a B+ tree with the range [first,last)
template <class InputIterator>
btree_map(InputIterator first, InputIterator last, const allocator_type &alloc = allocator_type())
: tree_(first, last, alloc) {}
//! Constructor initializing a B+ tree with the range [first,last) and a
//! special key comparison object
template <class InputIterator>
btree_map(InputIterator first, InputIterator last, const key_compare &kcf,
const allocator_type &alloc = allocator_type())
: tree_(first, last, kcf, alloc) {}
//! Frees up all used B+ tree memory pages
~btree_map() {}
//! Fast swapping of two identical B+ tree objects.
void swap(btree_map &from) { std::swap(tree_, from.tree_); }
//! \}
public:
//! \name Key and Value Comparison Function Objects
//! \{
//! Constant access to the key comparison object sorting the B+ tree
key_compare key_comp() const { return tree_.key_comp(); }
//! Constant access to a constructed value_type comparison object. required
//! by the STL
value_compare value_comp() const { return tree_.value_comp(); }
//! \}
public:
//! \name Allocators
//! \{
//! Return the base node allocator provided during construction.
allocator_type get_allocator() const { return tree_.get_allocator(); }
//! \}
public:
//! \name Fast Destruction of the B+ Tree
//! \{
//! Frees all key/data pairs and all nodes of the tree
void clear() { tree_.clear(); }
//! \}
public:
//! \name STL Iterator Construction Functions
//! \{
//! Constructs a read/data-write iterator that points to the first slot in
//! the first leaf of the B+ tree.
iterator begin() { return tree_.begin(); }
//! Constructs a read/data-write iterator that points to the first invalid
//! slot in the last leaf of the B+ tree.
iterator end() { return tree_.end(); }
//! Constructs a read-only constant iterator that points to the first slot
//! in the first leaf of the B+ tree.
const_iterator begin() const { return tree_.begin(); }
//! Constructs a read-only constant iterator that points to the first
//! invalid slot in the last leaf of the B+ tree.
const_iterator end() const { return tree_.end(); }
//! Constructs a read/data-write reverse iterator that points to the first
//! invalid slot in the last leaf of the B+ tree. Uses STL magic.
reverse_iterator rbegin() { return tree_.rbegin(); }
//! Constructs a read/data-write reverse iterator that points to the first
//! slot in the first leaf of the B+ tree. Uses STL magic.
reverse_iterator rend() { return tree_.rend(); }
//! Constructs a read-only reverse iterator that points to the first
//! invalid slot in the last leaf of the B+ tree. Uses STL magic.
const_reverse_iterator rbegin() const { return tree_.rbegin(); }
//! Constructs a read-only reverse iterator that points to the first slot
//! in the first leaf of the B+ tree. Uses STL magic.
const_reverse_iterator rend() const { return tree_.rend(); }
//! \}
public:
//! \name Access Functions to the Item Count
//! \{
//! Return the number of key/data pairs in the B+ tree
size_type size() const { return tree_.size(); }
//! Returns true if there is at least one key/data pair in the B+ tree
bool empty() const { return tree_.empty(); }
//! Returns the largest possible size of the B+ Tree. This is just a
//! function required by the STL standard, the B+ Tree can hold more items.
size_type max_size() const { return tree_.max_size(); }
//! Return a const reference to the current statistics.
const tree_stats &get_stats() const { return tree_.get_stats(); }
//! \}
public:
//! \name STL Access Functions Querying the Tree by Descending to a Leaf
//! \{
//! Non-STL function checking whether a key is in the B+ tree. The same as
//! (find(k) != end()) or (count() != 0).
bool exists(const key_type &key) const { return tree_.exists(key); }
//! Tries to locate a key in the B+ tree and returns an iterator to the
//! key/data slot if found. If unsuccessful it returns end().
iterator find(const key_type &key) { return tree_.find(key); }
//! Tries to locate a key in the B+ tree and returns an constant iterator to
//! the key/data slot if found. If unsuccessful it returns end().
const_iterator find(const key_type &key) const { return tree_.find(key); }
//! Tries to locate a key in the B+ tree and returns the number of identical
//! key entries found. Since this is a unique map, count() returns either 0
//! or 1.
size_type count(const key_type &key) const { return tree_.count(key); }
//! Searches the B+ tree and returns an iterator to the first pair equal to
//! or greater than key, or end() if all keys are smaller.
iterator lower_bound(const key_type &key) { return tree_.lower_bound(key); }
//! Searches the B+ tree and returns a constant iterator to the first pair
//! equal to or greater than key, or end() if all keys are smaller.
const_iterator lower_bound(const key_type &key) const { return tree_.lower_bound(key); }
//! Searches the B+ tree and returns an iterator to the first pair greater
//! than key, or end() if all keys are smaller or equal.
iterator upper_bound(const key_type &key) { return tree_.upper_bound(key); }
//! Searches the B+ tree and returns a constant iterator to the first pair
//! greater than key, or end() if all keys are smaller or equal.
const_iterator upper_bound(const key_type &key) const { return tree_.upper_bound(key); }
//! Searches the B+ tree and returns both lower_bound() and upper_bound().
std::pair<iterator, iterator> equal_range(const key_type &key) { return tree_.equal_range(key); }
//! Searches the B+ tree and returns both lower_bound() and upper_bound().
std::pair<const_iterator, const_iterator> equal_range(const key_type &key) const { return tree_.equal_range(key); }
//! \}
public:
//! \name B+ Tree Object Comparison Functions
//! \{
//! Equality relation of B+ trees of the same type. B+ trees of the same
//! size and equal elements (both key and data) are considered equal.
bool operator==(const btree_map &other) const { return (tree_ == other.tree_); }
//! Inequality relation. Based on operator==.
bool operator!=(const btree_map &other) const { return (tree_ != other.tree_); }
//! Total ordering relation of B+ trees of the same type. It uses
//! std::lexicographical_compare() for the actual comparison of elements.
bool operator<(const btree_map &other) const { return (tree_ < other.tree_); }
//! Greater relation. Based on operator<.
bool operator>(const btree_map &other) const { return (tree_ > other.tree_); }
//! Less-equal relation. Based on operator<.
bool operator<=(const btree_map &other) const { return (tree_ <= other.tree_); }
//! Greater-equal relation. Based on operator<.
bool operator>=(const btree_map &other) const { return (tree_ >= other.tree_); }
//! \}
public:
//! \name Fast Copy: Assign Operator and Copy Constructors
//! \{
//! Assignment operator. All the key/data pairs are copied
btree_map &operator=(const btree_map &other) {
if (this != &other) tree_ = other.tree_;
return *this;
}
//! Copy constructor. The newly initialized B+ tree object will contain a
//! copy of all key/data pairs.
btree_map(const btree_map &other) : tree_(other.tree_) {}
//! \}
public:
//! \name Public Insertion Functions
//! \{
//! Attempt to insert a key/data pair into the B+ tree. Fails if the pair is
//! already present.
std::pair<iterator, bool> insert(const value_type &x) { return tree_.insert(x); }
//! Attempt to insert a key/data pair into the B+ tree. This function is the
//! same as the other insert. Fails if the inserted pair is already present.
std::pair<iterator, bool> insert2(const key_type &key, const data_type &data) {
return tree_.insert(value_type(key, data));
}
//! Attempt to insert a key/data pair into the B+ tree. The iterator hint is
//! currently ignored by the B+ tree insertion routine.
iterator insert(iterator hint, const value_type &x) { return tree_.insert(hint, x); }
//! Attempt to insert a key/data pair into the B+ tree. The iterator hint is
//! currently ignored by the B+ tree insertion routine.
iterator insert2(iterator hint, const key_type &key, const data_type &data) {
return tree_.insert(hint, value_type(key, data));
}
//! Returns a reference to the object that is associated with a particular
//! key. If the map does not already contain such an object, operator[]
//! inserts the default object data_type().
data_type &operator[](const key_type &key) {
iterator i = insert(value_type(key, data_type())).first;
return i->second;
}
//! Attempt to insert the range [first,last) of value_type pairs into the B+
//! tree. Each key/data pair is inserted individually.
template <typename InputIterator>
void insert(InputIterator first, InputIterator last) {
return tree_.insert(first, last);
}
//! Bulk load a sorted range [first,last). Loads items into leaves and
//! constructs a B-tree above them. The tree must be empty when calling this
//! function.
template <typename Iterator>
void bulk_load(Iterator first, Iterator last) {
return tree_.bulk_load(first, last);
}
//! \}
public:
//! \name Public Erase Functions
//! \{
//! Erases the key/data pairs associated with the given key. For this
//! unique-associative map there is no difference to erase().
bool erase_one(const key_type &key) { return tree_.erase_one(key); }
//! Erases all the key/data pairs associated with the given key. This is
//! implemented using erase_one().
size_type erase(const key_type &key) { return tree_.erase(key); }
//! Erase the key/data pair referenced by the iterator.
void erase(iterator iter) { return tree_.erase(iter); }
#ifdef TLX_BTREE_TODO
//! Erase all key/data pairs in the range [first,last). This function is
//! currently not implemented by the B+ Tree.
void erase(iterator /* first */, iterator /* last */) { abort(); }
#endif
//! \}
#ifdef TLX_BTREE_DEBUG
public:
//! \name Debug Printing
//! \{
//! Print out the B+ tree structure with keys onto the given ostream. This
//! function requires that the header is compiled with TLX_BTREE_DEBUG and
//! that key_type is printable via std::ostream.
void print(std::ostream &os) const { tree_.print(os); }
//! Print out only the leaves via the double linked list.
void print_leaves(std::ostream &os) const { tree_.print_leaves(os); }
//! \}
#endif
public:
//! \name Verification of B+ Tree Invariants
//! \{
//! Run a thorough verification of all B+ tree invariants. The program
//! aborts via TLX_BTREE_ASSERT() if something is wrong.
void verify() const { tree_.verify(); }
//! \}
};
//! \}
} // namespace tlx
#endif // !TLX_CONTAINER_BTREE_MAP_HEADER
/******************************************************************************/

View File

@ -1,267 +0,0 @@
/*******************************************************************************
* tlx/die/core.hpp
*
* Part of tlx - http://panthema.net/tlx
*
* Copyright (C) 2016-2018 Timo Bingmann <tb@panthema.net>
*
* All rights reserved. Published under the Boost Software License, Version 1.0
******************************************************************************/
#ifndef TLX_DIE_CORE_HEADER
#define TLX_DIE_CORE_HEADER
#include <cstring>
#include <iomanip>
#include <sstream>
#include <stdexcept>
#include <string>
namespace tlx {
/******************************************************************************/
// die macros
//! die with message - either throw an exception or die via std::terminate()
void die_with_message(const std::string &msg);
//! die with message - either throw an exception or die via std::terminate()
void die_with_message(const char *msg, const char *file, size_t line);
//! die with message - either throw an exception or die via std::terminate()
void die_with_message(const std::string &msg, const char *file, size_t line);
//! Instead of std::terminate(), throw the output the message via an exception.
#define tlx_die_with_sstream(msg) \
do { \
std::ostringstream oss__; \
oss__ << msg << " @ " << __FILE__ << ':' << __LINE__; \
::tlx::die_with_message(oss__.str()); \
std::terminate(); /* tell compiler this never returns */ \
} while (false)
//! Instead of std::terminate(), throw the output the message via an exception.
#define tlx_die(msg) \
do { \
tlx_die_with_sstream("DIE: " << msg); \
} while (false)
//! Exception thrown by die_with_message() if
class DieException : public std::runtime_error {
public:
explicit DieException(const std::string &message);
};
//! Switch between dying via std::terminate() and throwing an exception.
//! Alternatively define the macro TLX_DIE_WITH_EXCEPTION=1
bool set_die_with_exception(bool b);
/******************************************************************************/
// die_unless() and die_if()
//! Check condition X and die miserably if false. Same as assert() except this
//! is also active in Release mode.
#define tlx_die_unless(X) \
do { \
if (!(X)) { \
::tlx::die_with_message("DIE: Assertion \"" #X "\" failed!", __FILE__, __LINE__); \
} \
} while (false)
//! Check condition X and die miserably if true. Opposite of assert() except
//! this is also active in Release mode.
#define tlx_die_if(X) \
do { \
if (X) { \
::tlx::die_with_message("DIE: Assertion \"" #X "\" succeeded!", __FILE__, __LINE__); \
} \
} while (false)
//! Check condition X and die miserably if false. Same as tlx_die_unless()
//! except the user additionally passes a message.
#define tlx_die_verbose_unless(X, msg) \
do { \
if (!(X)) { \
tlx_die_with_sstream("DIE: Assertion \"" #X "\" failed!\n" << msg << '\n'); \
} \
} while (false)
//! Check condition X and die miserably if false. Same as tlx_die_if()
//! except the user additionally passes a message.
#define tlx_die_verbose_if(X, msg) \
do { \
if ((X)) { \
tlx_die_with_sstream("DIE: Assertion \"" #X "\" succeeded!\n" << msg << '\n'); \
} \
} while (false)
/******************************************************************************/
// die_unequal()
//! helper method to compare two values in die_unequal()
template <typename TypeA, typename TypeB>
inline bool die_equal_compare(TypeA a, TypeB b) {
return a == b;
}
template <>
inline bool die_equal_compare(const char *a, const char *b) {
// compare string contents
return std::strcmp(a, b) == 0;
}
template <>
inline bool die_equal_compare(float a, float b) {
// special case for NAN
return a != a ? b != b : a == b;
}
template <>
inline bool die_equal_compare(double a, double b) {
// special case for NAN
return a != a ? b != b : a == b;
}
//! Check that X == Y or die miserably, but output the values of X and Y for
//! better debugging.
#define tlx_die_unequal(X, Y) \
do { \
auto x__ = (X); /* NOLINT */ \
auto y__ = (Y); /* NOLINT */ \
if (!::tlx::die_equal_compare(x__, y__)) \
tlx_die_with_sstream("DIE-UNEQUAL: " #X " != " #Y \
" : " \
"\"" \
<< x__ << "\" != \"" << y__ << "\""); \
} while (false)
//! Check that X == Y or die miserably, but output the values of X and Y for
//! better debugging. Only active if NDEBUG is not defined.
#ifdef NDEBUG
#define tlx_assert_equal(X, Y)
#else
#define tlx_assert_equal(X, Y) die_unequal(X, Y)
#endif
//! Check that X == Y or die miserably, but output the values of X and Y for
//! better debugging. Same as tlx_die_unequal() except the user additionally
//! pass a message.
#define tlx_die_verbose_unequal(X, Y, msg) \
do { \
auto x__ = (X); /* NOLINT */ \
auto y__ = (Y); /* NOLINT */ \
if (!::tlx::die_equal_compare(x__, y__)) \
tlx_die_with_sstream("DIE-UNEQUAL: " #X " != " #Y \
" : " \
"\"" \
<< x__ << "\" != \"" << y__ << "\"\n" \
<< msg << '\n'); \
} while (false)
/******************************************************************************/
// die_unequal_eps()
//! simple replacement for std::abs
template <typename Type>
inline Type die_unequal_eps_abs(const Type &t) {
return t < 0 ? -t : t;
}
//! helper method to compare two values in die_unequal_eps()
template <typename TypeA, typename TypeB>
inline bool die_equal_eps_compare(TypeA x, TypeB y, double eps) {
// special case for NAN
return x != x ? y != y : die_unequal_eps_abs(x - y) <= eps;
}
//! Check that ABS(X - Y) <= eps or die miserably, but output the values of X
//! and Y for better debugging.
#define tlx_die_unequal_eps(X, Y, eps) \
do { \
auto x__ = (X); /* NOLINT */ \
auto y__ = (Y); /* NOLINT */ \
if (!::tlx::die_equal_eps_compare(x__, y__, eps)) \
tlx_die("DIE-UNEQUAL-EPS: " #X " != " #Y " : " << std::setprecision(18) << "\"" << x__ << "\" != \"" << y__ \
<< "\""); \
} while (false)
//! Check that ABS(X - Y) <= eps or die miserably, but output the values of X
//! and Y for better debugging. Same as tlx_die_unequal_eps() except the user
//! additionally passes a message.
#define tlx_die_verbose_unequal_eps(X, Y, eps, msg) \
do { \
auto x__ = (X); /* NOLINT */ \
auto y__ = (Y); /* NOLINT */ \
if (!::tlx::die_equal_eps_compare(x__, y__, eps)) \
tlx_die("DIE-UNEQUAL-EPS: " #X " != " #Y " : " << std::setprecision(18) << "\"" << x__ << "\" != \"" << y__ \
<< "\"\n" \
<< msg << '\n'); \
} while (false)
//! Check that ABS(X - Y) <= 0.000001 or die miserably, but output the values of
//! X and Y for better debugging.
#define tlx_die_unequal_eps6(X, Y) die_unequal_eps(X, Y, 1e-6)
//! Check that ABS(X - Y) <= 0.000001 or die miserably, but output the values of
//! X and Y for better debugging. Same as tlx_die_unequal_eps6() except the user
//! additionally passes a message.
#define tlx_die_verbose_unequal_eps6(X, Y, msg) die_verbose_unequal_eps(X, Y, 1e-6, msg)
/******************************************************************************/
// die_equal()
//! Die miserably if X == Y, but first output the values of X and Y for better
//! debugging.
#define tlx_die_equal(X, Y) \
do { \
auto x__ = (X); /* NOLINT */ \
auto y__ = (Y); /* NOLINT */ \
if (::tlx::die_equal_compare(x__, y__)) \
tlx_die_with_sstream("DIE-EQUAL: " #X " == " #Y \
" : " \
"\"" \
<< x__ << "\" == \"" << y__ << "\""); \
} while (false)
//! Die miserably if X == Y, but first output the values of X and Y for better
//! debugging. Only active if NDEBUG is not defined.
#ifdef NDEBUG
#define tlx_assert_unequal(X, Y)
#else
#define tlx_assert_unequal(X, Y) die_equal(X, Y)
#endif
//! Die miserably if X == Y, but first output the values of X and Y for better
//! debugging. Same as tlx_die_equal() except the user additionally passes a
//! message.
#define tlx_die_verbose_equal(X, Y, msg) \
do { \
auto x__ = (X); /* NOLINT */ \
auto y__ = (Y); /* NOLINT */ \
if (::tlx::die_equal_compare(x__, y__)) \
tlx_die_with_sstream("DIE-EQUAL: " #X " == " #Y \
" : " \
"\"" \
<< x__ << "\" == \"" << y__ << "\"\n" \
<< msg << '\n'); \
} while (false)
/******************************************************************************/
// die_unless_throws()
//! Define to check that [code] throws and exception of given type
#define tlx_die_unless_throws(code, exception_type) \
do { \
try { \
code; \
} catch (const exception_type &) { \
break; \
} \
::tlx::die_with_message("DIE-UNLESS-THROWS: " #code " - NO EXCEPTION " #exception_type, __FILE__, __LINE__); \
} while (false)
} // namespace tlx
#endif // !TLX_DIE_CORE_HEADER
/******************************************************************************/

View File

@ -15,7 +15,6 @@
#include <set>
#include <vector>
#include "btree_map.hpp"
#include "coordinator/hybrid_logical_clock.hpp"
#include "storage/v3/key_store.hpp"
#include "storage/v3/lexicographically_ordered_vertex.hpp"
@ -30,7 +29,6 @@ inline void PrepareData(utils::SkipList<T> &skip_list, const int64_t num_element
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
for (auto i{0}; i < num_elements; ++i) {
auto acc = skip_list.access();
acc.insert({storage::v3::PrimaryKey{storage::v3::PropertyValue{i}}});
@ -55,22 +53,9 @@ inline void PrepareData(std::set<T> &std_set, const int64_t num_elements) {
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
for (auto i{0}; i < num_elements; ++i) {
std_set.insert(std::vector<storage::v3::PropertyValue>{storage::v3::PropertyValue{i}});
}
}
template <typename TKey, typename TValue>
inline void PrepareData(tlx::btree_map<TKey, TValue> &bpp_tree, const int64_t num_elements) {
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
for (auto i{0}; i < num_elements; ++i) {
bpp_tree.insert({storage::v3::PrimaryKey{storage::v3::PropertyValue{i}},
storage::v3::LexicographicallyOrderedVertex{storage::v3::Vertex{
delta, std::vector<storage::v3::PropertyValue>{storage::v3::PropertyValue{i}}}}});
}
}
} // namespace memgraph::benchmark

View File

@ -23,7 +23,6 @@
#include <benchmark/benchmark.h>
#include <gflags/gflags.h>
#include "btree_map.hpp"
#include "data_structures_common.hpp"
#include "storage/v3/key_store.hpp"
#include "storage/v3/lexicographically_ordered_vertex.hpp"
@ -79,10 +78,7 @@ static void BM_BenchmarkContainsStdMap(::benchmark::State &state) {
static void BM_BenchmarkContainsStdSet(::benchmark::State &state) {
std::set<storage::v3::PrimaryKey> std_set;
PrepareData(std_set, state.range(0));
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
// So we can also have elements that does don't exist
std::mt19937 i_generator(std::random_device{}());
std::uniform_int_distribution<int64_t> i_distribution(0, state.range(0) * 2);
@ -98,33 +94,12 @@ static void BM_BenchmarkContainsStdSet(::benchmark::State &state) {
state.SetItemsProcessed(found_elems);
}
static void BM_BenchmarkContainsBppTree(::benchmark::State &state) {
tlx::btree_map<storage::v3::PrimaryKey, storage::v3::LexicographicallyOrderedVertex> bpp_tree;
PrepareData(bpp_tree, state.range(0));
// So we can also have elements that does don't exists
std::mt19937 i_generator(std::random_device{}());
std::uniform_int_distribution<int64_t> i_distribution(0, state.range(0) * 2);
int64_t found_elems{0};
for (auto _ : state) {
for (auto i{0}; i < state.range(0); ++i) {
int64_t value = i_distribution(i_generator);
if (bpp_tree.count(storage::v3::PrimaryKey{{storage::v3::PropertyValue(value)}}) > 0) {
found_elems++;
}
}
}
state.SetItemsProcessed(found_elems);
}
BENCHMARK(BM_BenchmarkContainsSkipList)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkContainsStdMap)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkContainsStdSet)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkContainsBppTree)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
} // namespace memgraph::benchmark
BENCHMARK_MAIN();

View File

@ -23,7 +23,6 @@
#include <benchmark/benchmark.h>
#include <gflags/gflags.h>
#include "btree_map.hpp"
#include "data_structures_common.hpp"
#include "storage/v3/key_store.hpp"
#include "storage/v3/lexicographically_ordered_vertex.hpp"
@ -78,10 +77,6 @@ static void BM_BenchmarkFindStdMap(::benchmark::State &state) {
static void BM_BenchmarkFindStdSet(::benchmark::State &state) {
std::set<storage::v3::PrimaryKey> std_set;
PrepareData(std_set, state.range(0));
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
// So we can also have elements that does don't exist
std::mt19937 i_generator(std::random_device{}());
@ -98,32 +93,12 @@ static void BM_BenchmarkFindStdSet(::benchmark::State &state) {
state.SetItemsProcessed(found_elems);
}
static void BM_BenchmarkFindBppTree(::benchmark::State &state) {
tlx::btree_map<storage::v3::PrimaryKey, storage::v3::LexicographicallyOrderedVertex> bpp_tree;
PrepareData(bpp_tree, state.range(0));
// So we can also have elements that does don't exist
std::mt19937 i_generator(std::random_device{}());
std::uniform_int_distribution<int64_t> i_distribution(0, state.range(0) * 2);
int64_t found_elems{0};
for (auto _ : state) {
for (auto i{0}; i < state.range(0); ++i) {
int64_t value = i_distribution(i_generator);
if (bpp_tree.find(storage::v3::PrimaryKey{{storage::v3::PropertyValue(value)}}) != bpp_tree.end()) {
found_elems++;
}
}
}
state.SetItemsProcessed(found_elems);
}
BENCHMARK(BM_BenchmarkFindSkipList)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkFindStdMap)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkFindStdSet)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkFindBppTree)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
} // namespace memgraph::benchmark
BENCHMARK_MAIN();

View File

@ -23,7 +23,6 @@
#include <benchmark/benchmark.h>
#include <gflags/gflags.h>
#include "btree_map.hpp"
#include "storage/v3/key_store.hpp"
#include "storage/v3/lexicographically_ordered_vertex.hpp"
#include "storage/v3/mvcc.hpp"
@ -82,30 +81,12 @@ static void BM_BenchmarkInsertStdSet(::benchmark::State &state) {
}
}
static void BM_BenchmarkInsertBppTree(::benchmark::State &state) {
tlx::btree_map<storage::v3::PrimaryKey, storage::v3::LexicographicallyOrderedVertex> bpp_tree;
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
for (auto _ : state) {
for (auto i{0}; i < state.range(0); ++i) {
bpp_tree.insert({storage::v3::PrimaryKey{storage::v3::PropertyValue{i}},
storage::v3::LexicographicallyOrderedVertex{storage::v3::Vertex{
delta, std::vector<storage::v3::PropertyValue>{storage::v3::PropertyValue{i}}}}});
}
}
}
BENCHMARK(BM_BenchmarkInsertSkipList)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkInsertStdMap)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkInsertStdSet)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkInsertBppTree)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
} // namespace memgraph::benchmark
BENCHMARK_MAIN();

View File

@ -23,7 +23,6 @@
#include <benchmark/benchmark.h>
#include <gflags/gflags.h>
#include "btree_map.hpp"
#include "data_structures_common.hpp"
#include "storage/v3/key_store.hpp"
#include "storage/v3/lexicographically_ordered_vertex.hpp"
@ -41,10 +40,6 @@ namespace memgraph::benchmark {
static void BM_BenchmarkRemoveSkipList(::benchmark::State &state) {
utils::SkipList<storage::v3::PrimaryKey> skip_list;
PrepareData(skip_list, state.range(0));
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
// So we can also have elements that does don't exist
std::mt19937 i_generator(std::random_device{}());
@ -84,10 +79,6 @@ static void BM_BenchmarkRemoveStdMap(::benchmark::State &state) {
static void BM_BenchmarkRemoveStdSet(::benchmark::State &state) {
std::set<storage::v3::PrimaryKey> std_set;
PrepareData(std_set, state.range(0));
coordinator::Hlc start_timestamp;
storage::v3::IsolationLevel isolation_level{storage::v3::IsolationLevel::SNAPSHOT_ISOLATION};
storage::v3::Transaction transaction{start_timestamp, isolation_level};
auto *delta = storage::v3::CreateDeleteObjectDelta(&transaction);
// So we can also have elements that does don't exist
std::mt19937 i_generator(std::random_device{}());
@ -104,33 +95,12 @@ static void BM_BenchmarkRemoveStdSet(::benchmark::State &state) {
state.SetItemsProcessed(removed_elems);
}
static void BM_BenchmarkRemoveBppTree(::benchmark::State &state) {
tlx::btree_map<storage::v3::PrimaryKey, storage::v3::LexicographicallyOrderedVertex> bpp_tree;
PrepareData(bpp_tree, state.range(0));
// So we can also have elements that does don't exist
std::mt19937 i_generator(std::random_device{}());
std::uniform_int_distribution<int64_t> i_distribution(0, state.range(0) * 2);
int64_t removed_elems{0};
for (auto _ : state) {
for (auto i{0}; i < state.range(0); ++i) {
int64_t value = i_distribution(i_generator);
if (bpp_tree.erase(storage::v3::PrimaryKey{storage::v3::PropertyValue{value}}) > 0) {
removed_elems++;
}
}
}
state.SetItemsProcessed(removed_elems);
}
BENCHMARK(BM_BenchmarkRemoveSkipList)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkRemoveStdMap)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkRemoveStdSet)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
BENCHMARK(BM_BenchmarkRemoveBppTree)->RangeMultiplier(10)->Range(1000, 10000000)->Unit(::benchmark::kMillisecond);
} // namespace memgraph::benchmark
BENCHMARK_MAIN();