2a59ed8906
Importes now use logger. Refactored order of constrution of objects in Db. Moved index creation/removing from Db to Indexes. Completed Garbage class. Cleaner now calls garbage.clean() for databases. Renamed List to ConcurrentList which better names it.
285 lines
10 KiB
C++
285 lines
10 KiB
C++
#pragma once
|
|
|
|
#include "storage/model/properties/all.hpp"
|
|
|
|
// Generates constructor by value which accepts type_name object and stores them
|
|
// in union_name field.
|
|
#define GENERATE_CONSTRUCTOR_FOR_DATA(type_name, union_name) \
|
|
PropertyHolder(type_name &&data, T k) \
|
|
: union_name(std::move(data)), key(k) \
|
|
{ \
|
|
assert(type_name::type == key.get_type()); \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to construct type_name object in
|
|
// place of union_name field by a move from other
|
|
#define GENERATE_CASE_CLAUSE_FOR_CONSTRUCTOR_MOVE(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
new (&(this->union_name)) type_name(std::move(other.union_name)); \
|
|
break; \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to construct type_name object in
|
|
// place of union_name field by a copy from other
|
|
#define GENERATE_CASE_CLAUSE_FOR_CONSTRUCTOR_COPY(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
new (&(this->union_name)) type_name(other.union_name); \
|
|
break; \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to destruct type_name object in
|
|
// place of union_name field
|
|
#define GENERATE_CASE_CLAUSE_FOR_DESTRUCTOR(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
this->union_name.~type_name(); \
|
|
break; \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to handle type_name object from
|
|
// field of union_name
|
|
#define GENERATE_CASE_CLAUSE_FOR_HANDLER(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
h.handle(this->union_name); \
|
|
break; \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to handle primitives of type_name
|
|
// object from field of union_name
|
|
#define GENERATE_CASE_CLAUSE_FOR_HANDLER_PRIMITIVE(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
h.handle(this->union_name.value()); \
|
|
break; \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to print type_name object from
|
|
// field of union_name
|
|
#define GENERATE_CASE_CLAUSE_FOR_PRINT(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
return this->union_name.print(stream); \
|
|
}
|
|
|
|
// Genrates case claus for Flags::type_name to comapre type_name object from
|
|
// field of union_name with same named and field from other holder.
|
|
#define GENERATE_CASE_CLAUSE_FOR_COMPARISON(type_name, union_name) \
|
|
case Flags::type_name: { \
|
|
return this->union_name == other.union_name; \
|
|
}
|
|
|
|
// Generates field in a union with a given type and name
|
|
#define GENERATE_UNION_FIELD(type_name, union_name) type_name union_name
|
|
|
|
// Generates signatures GENERATE_define_generator(type_name, union_name );
|
|
// for every pair type,property
|
|
#define GENERATE_FOR_ALL_PROPERTYS(define_generator) \
|
|
GENERATE_##define_generator(Null, null_v); \
|
|
GENERATE_##define_generator(Bool, bool_v); \
|
|
GENERATE_##define_generator(Int32, int32_v); \
|
|
GENERATE_##define_generator(Int64, int64_v); \
|
|
GENERATE_##define_generator(Float, float_V); \
|
|
GENERATE_##define_generator(Double, double_v); \
|
|
GENERATE_##define_generator(String, string_v); \
|
|
GENERATE_##define_generator(ArrayBool, array_bool); \
|
|
GENERATE_##define_generator(ArrayInt32, array_int32); \
|
|
GENERATE_##define_generator(ArrayInt64, array_int64); \
|
|
GENERATE_##define_generator(ArrayFloat, array_float); \
|
|
GENERATE_##define_generator(ArrayDouble, array_double); \
|
|
GENERATE_##define_generator(ArrayString, array_string);
|
|
|
|
// Holds property and has some means of determining its type.
|
|
// T must have method get_type() const which returns Type.
|
|
template <class T>
|
|
class PropertyHolder
|
|
{
|
|
// He is his own best friend.
|
|
template <class O>
|
|
friend class PropertyHolder;
|
|
|
|
public:
|
|
PropertyHolder() = delete;
|
|
|
|
GENERATE_FOR_ALL_PROPERTYS(CONSTRUCTOR_FOR_DATA);
|
|
|
|
PropertyHolder(PropertyHolder const &other) : key(other.key)
|
|
{
|
|
switch (other.key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_CONSTRUCTOR_COPY);
|
|
default:
|
|
assert(false);
|
|
}
|
|
assert(key.get_type().flags() == Flags::Int64 || this->int64_v != 0);
|
|
}
|
|
|
|
PropertyHolder(PropertyHolder &&other) : key(other.key)
|
|
{
|
|
switch (other.key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_CONSTRUCTOR_MOVE);
|
|
default:
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
template <class O>
|
|
PropertyHolder(PropertyHolder<O> &&other, T const &key) : key(key)
|
|
{
|
|
assert(other.key.get_type() == key.get_type());
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_CONSTRUCTOR_MOVE);
|
|
default:
|
|
assert(false);
|
|
}
|
|
assert(key.get_type().flags() == Flags::Int64 || this->int64_v != 0);
|
|
}
|
|
|
|
~PropertyHolder()
|
|
{
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_DESTRUCTOR);
|
|
default:
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
PropertyHolder &operator=(PropertyHolder const &other)
|
|
{
|
|
this->~PropertyHolder();
|
|
new (this) PropertyHolder(other);
|
|
assert(key.get_type().flags() == Flags::Int64 || this->int64_v != 0);
|
|
return *this;
|
|
}
|
|
|
|
PropertyHolder &operator=(PropertyHolder &&other)
|
|
{
|
|
this->~PropertyHolder();
|
|
new (this) PropertyHolder(std::move(other));
|
|
assert(key.get_type().flags() == Flags::Int64 || this->int64_v != 0);
|
|
return *this;
|
|
}
|
|
|
|
// Calls appropiate handler with a database property.
|
|
// (String,Int64,ArrayBool,...)
|
|
template <class Handler>
|
|
void accept(Handler &h) const
|
|
{
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_HANDLER);
|
|
default:
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
// Calls appropiate handler with a primitive.(std::string,bool,int64_t,...)
|
|
template <class Handler>
|
|
void accept_primitive(Handler &h) const
|
|
{
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_HANDLER_PRIMITIVE);
|
|
default:
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
std::ostream &print(std::ostream &stream) const
|
|
{
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_PRINT);
|
|
default:
|
|
assert(false);
|
|
}
|
|
}
|
|
|
|
friend std::ostream &operator<<(std::ostream &stream,
|
|
const PropertyHolder &prop)
|
|
{
|
|
return prop.print(stream);
|
|
}
|
|
|
|
bool operator==(const PropertyHolder &other) const
|
|
{
|
|
if (key == other.key) {
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_COMPARISON);
|
|
default:
|
|
assert(false);
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template <class O>
|
|
bool operator==(const PropertyHolder<O> &other) const
|
|
{
|
|
if (key.get_type() == other.key.get_type()) {
|
|
switch (key.get_type().flags()) {
|
|
GENERATE_FOR_ALL_PROPERTYS(CASE_CLAUSE_FOR_COMPARISON);
|
|
default:
|
|
assert(false);
|
|
}
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
template <class O, Flags f = O::type.flags()>
|
|
bool operator==(const O &other) const
|
|
{
|
|
if (key.get_type() == O::type) {
|
|
return other == as<O>();
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
bool operator!=(const PropertyHolder &other) const
|
|
{
|
|
return !(*this == other);
|
|
}
|
|
|
|
// True if NULL
|
|
bool is_empty() const { return is<Null>(); }
|
|
|
|
// True if contains T property
|
|
template <class D>
|
|
bool is() const
|
|
{
|
|
return D::type == key.get_type();
|
|
}
|
|
|
|
// T MUST be type with which this holder was constructed.
|
|
template <class D>
|
|
D &as()
|
|
{
|
|
assert(is<D>());
|
|
return *reinterpret_cast<D *>(&array_string);
|
|
}
|
|
|
|
// T MUST be type with which this PropertyData was constructed.
|
|
// Specialized after this class
|
|
template <class D>
|
|
D const &as() const
|
|
{
|
|
assert(is<D>());
|
|
return *reinterpret_cast<D const *>(&array_string);
|
|
}
|
|
|
|
// Knows type
|
|
const T key;
|
|
|
|
private:
|
|
// Stored data.
|
|
union
|
|
{
|
|
GENERATE_FOR_ALL_PROPERTYS(UNION_FIELD);
|
|
};
|
|
};
|
|
|
|
#undef GENERATE_CONSTRUCTOR_FOR_DATA
|
|
#undef GENERATE_CASE_CLAUSE_FOR_CONSTRUCTOR_MOVE
|
|
#undef GENERATE_CASE_CLAUSE_FOR_CONSTRUCTOR_COPY
|
|
#undef GENERATE_CASE_CLAUSE_FOR_DESTRUCTOR
|
|
#undef GENERATE_CASE_CLAUSE_FOR_HANDLER
|
|
#undef GENERATE_CASE_CLAUSE_FOR_PRINT
|
|
#undef GENERATE_CASE_CLAUSE_FOR_COMPARISON
|
|
#undef GENERATE_UNION_FIELD
|
|
#undef GENERATE_FOR_ALL_PROPERTYS
|