#pragma once #include #include #include // TODO: remove #include "utils/underlying_cast.hpp" #include // entities are nodes or relationship namespace entity_search { // returns maximum value for given template argument (for give type) template constexpr T max() { return std::numeric_limits::max(); } using cost_t = uint64_t; // TODO: rething // at least load hard coded values from somewhere constexpr cost_t internal_id_cost = 10; constexpr cost_t property_cost = 100; constexpr cost_t label_cost = 1000; constexpr cost_t max_cost = max(); template class SearchCost { public: enum class SearchPlace : int { internal_id, label_index, property_index, main_storage }; using costs_t = std::map; using cost_pair_t = std::pair; SearchCost() { costs[SearchPlace::internal_id] = max(); costs[SearchPlace::label_index] = max(); costs[SearchPlace::property_index] = max(); costs[SearchPlace::main_storage] = max(); } SearchCost(const SearchCost &other) = default; SearchCost(SearchCost &&other) : costs(std::move(other.costs)) {} void set(SearchPlace place, T cost) { costs[place] = cost; } T get(SearchPlace place) const { return costs.at(place); } SearchPlace min() const { auto min_pair = std::min_element( costs.begin(), costs.end(), [](const cost_pair_t &l, const cost_pair_t &r) -> bool { return l.second < r.second; }); if (min_pair->second == max_cost) return SearchPlace::main_storage; return min_pair->first; } private: costs_t costs; }; using search_cost_t = SearchCost; constexpr auto search_internal_id = search_cost_t::SearchPlace::internal_id; constexpr auto search_label_index = search_cost_t::SearchPlace::label_index; constexpr auto search_property_index = search_cost_t::SearchPlace::property_index; constexpr auto search_main_storage = search_cost_t::SearchPlace::main_storage; } class CypherStateMachine { public: void init_cost(const std::string &entity) { entity_search::search_cost_t search_cost; _search_costs.emplace(entity, search_cost); } void search_cost(const std::string &entity, entity_search::search_cost_t::SearchPlace search_place, entity_search::cost_t cost) { if (_search_costs.find(entity) != _search_costs.end()) { entity_search::search_cost_t search_cost; _search_costs.emplace(entity, std::move(search_cost)); } _search_costs[entity].set(search_place, cost); } entity_search::cost_t search_cost(const std::string &entity, entity_search::search_cost_t::SearchPlace search_place) const { return _search_costs.at(entity).get(search_place); } entity_search::search_cost_t::SearchPlace min(const std::string &entity) const { if (_search_costs.find(entity) == _search_costs.end()) return entity_search::search_cost_t::SearchPlace::main_storage; return _search_costs.at(entity).min(); } private: std::map _search_costs; };