From d6f150558250dc260b977e69d38aae3cb6c4e3e4 Mon Sep 17 00:00:00 2001 From: Tyler Neely <t@jujit.su> Date: Mon, 12 Dec 2022 15:14:48 +0000 Subject: [PATCH 1/6] Make Shard into a proper struct that can contain additional metadata --- src/coordinator/shard_map.cpp | 10 +++++----- src/coordinator/shard_map.hpp | 29 ++++++++++++++++++++++++++++- src/query/v2/request_router.hpp | 10 +++++----- tests/simulation/request_router.cpp | 4 ++-- tests/simulation/sharded_map.cpp | 6 +++--- 5 files changed, 43 insertions(+), 16 deletions(-) diff --git a/src/coordinator/shard_map.cpp b/src/coordinator/shard_map.cpp index ea167db87..7334fd0f9 100644 --- a/src/coordinator/shard_map.cpp +++ b/src/coordinator/shard_map.cpp @@ -283,7 +283,7 @@ std::vector<ShardToInitialize> ShardMap::AssignShards(Address storage_manager, // TODO(tyler) avoid these triple-nested loops by having the heartbeat include better info bool machine_contains_shard = false; - for (auto &aas : shard) { + for (auto &aas : shard.peers) { if (initialized.contains(aas.address.unique_id)) { machine_contains_shard = true; if (aas.status != Status::CONSENSUS_PARTICIPANT) { @@ -311,7 +311,7 @@ std::vector<ShardToInitialize> ShardMap::AssignShards(Address storage_manager, } } - if (!machine_contains_shard && shard.size() < label_space.replication_factor) { + if (!machine_contains_shard && shard.peers.size() < label_space.replication_factor) { // increment version for each new uuid for deterministic creation IncrementShardMapVersion(); @@ -337,7 +337,7 @@ std::vector<ShardToInitialize> ShardMap::AssignShards(Address storage_manager, .status = Status::INITIALIZING, }; - shard.emplace_back(aas); + shard.peers.emplace_back(aas); } } } @@ -556,12 +556,12 @@ EdgeTypeIdMap ShardMap::AllocateEdgeTypeIds(const std::vector<EdgeTypeName> &new bool ShardMap::ClusterInitialized() const { for (const auto &[label_id, label_space] : label_spaces) { for (const auto &[low_key, shard] : label_space.shards) { - if (shard.size() < label_space.replication_factor) { + if (shard.peers.size() < label_space.replication_factor) { spdlog::info("label_space below desired replication factor"); return false; } - for (const auto &aas : shard) { + for (const auto &aas : shard.peers) { if (aas.status != Status::CONSENSUS_PARTICIPANT) { spdlog::info("shard member not yet a CONSENSUS_PARTICIPANT"); return false; diff --git a/src/coordinator/shard_map.hpp b/src/coordinator/shard_map.hpp index 80c32eeba..6bb7a0624 100644 --- a/src/coordinator/shard_map.hpp +++ b/src/coordinator/shard_map.hpp @@ -76,7 +76,34 @@ struct AddressAndStatus { }; using PrimaryKey = std::vector<PropertyValue>; -using Shard = std::vector<AddressAndStatus>; + +struct Shard { + std::vector<AddressAndStatus> peers; + uint64_t version; + + friend std::ostream &operator<<(std::ostream &in, const Shard &shard) { + using utils::print_helpers::operator<<; + + in << "Shard { peers: "; + in << shard.peers; + in << " version: "; + in << shard.version; + in << " }"; + + return in; + } + + friend bool operator==(const Shard &lhs, const Shard &rhs) = default; + + friend bool operator<(const Shard &lhs, const Shard &rhs) { + if (lhs.peers != rhs.peers) { + return lhs.peers < rhs.peers; + } + + return lhs.version < rhs.version; + } +}; + using Shards = std::map<PrimaryKey, Shard>; using LabelName = std::string; using PropertyName = std::string; diff --git a/src/query/v2/request_router.hpp b/src/query/v2/request_router.hpp index 116e884c2..05918e8a3 100644 --- a/src/query/v2/request_router.hpp +++ b/src/query/v2/request_router.hpp @@ -484,7 +484,7 @@ class RequestRouter : public RequestRouterInterface { for (auto &shards : multi_shards) { for (auto &[key, shard] : shards) { - MG_ASSERT(!shard.empty()); + MG_ASSERT(!shard.peers.empty()); msgs::ScanVerticesRequest request; request.transaction_id = transaction_id_; @@ -584,11 +584,11 @@ class RequestRouter : public RequestRouterInterface { } void AddStorageClientToManager(Shard target_shard) { - MG_ASSERT(!target_shard.empty()); - auto leader_addr = target_shard.front(); + MG_ASSERT(!target_shard.peers.empty()); + auto leader_addr = target_shard.peers.front(); std::vector<Address> addresses; - addresses.reserve(target_shard.size()); - for (auto &address : target_shard) { + addresses.reserve(target_shard.peers.size()); + for (auto &address : target_shard.peers) { addresses.push_back(std::move(address.address)); } auto cli = StorageClient(io_, std::move(leader_addr.address), std::move(addresses)); diff --git a/tests/simulation/request_router.cpp b/tests/simulation/request_router.cpp index 0f712793f..dc60bb8e5 100644 --- a/tests/simulation/request_router.cpp +++ b/tests/simulation/request_router.cpp @@ -113,7 +113,7 @@ ShardMap CreateDummyShardmap(coordinator::Address a_io_1, coordinator::Address a AddressAndStatus aas1_2{.address = a_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas1_3{.address = a_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard1 = {aas1_1, aas1_2, aas1_3}; + Shard shard1 = Shard{.peers = {aas1_1, aas1_2, aas1_3}, .version = 1}; auto key1 = storage::v3::PropertyValue(0); auto key2 = storage::v3::PropertyValue(0); @@ -125,7 +125,7 @@ ShardMap CreateDummyShardmap(coordinator::Address a_io_1, coordinator::Address a AddressAndStatus aas2_2{.address = b_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas2_3{.address = b_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard2 = {aas2_1, aas2_2, aas2_3}; + Shard shard2 = Shard{.peers = {aas2_1, aas2_2, aas2_3}, .version = 1}; auto key3 = storage::v3::PropertyValue(12); auto key4 = storage::v3::PropertyValue(13); diff --git a/tests/simulation/sharded_map.cpp b/tests/simulation/sharded_map.cpp index 91661fc66..cdc2d69b6 100644 --- a/tests/simulation/sharded_map.cpp +++ b/tests/simulation/sharded_map.cpp @@ -109,7 +109,7 @@ ShardMap CreateDummyShardmap(Address a_io_1, Address a_io_2, Address a_io_3, Add AddressAndStatus aas1_2{.address = a_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas1_3{.address = a_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard1 = {aas1_1, aas1_2, aas1_3}; + Shard shard1 = Shard{.peers = {aas1_1, aas1_2, aas1_3}, .version = 1}; const auto key1 = PropertyValue(0); const auto key2 = PropertyValue(0); @@ -121,7 +121,7 @@ ShardMap CreateDummyShardmap(Address a_io_1, Address a_io_2, Address a_io_3, Add AddressAndStatus aas2_2{.address = b_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas2_3{.address = b_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard2 = {aas2_1, aas2_2, aas2_3}; + Shard shard2 = Shard{.peers = {aas2_1, aas2_2, aas2_3}, .version = 1}; auto key3 = PropertyValue(12); auto key4 = PropertyValue(13); @@ -134,7 +134,7 @@ ShardMap CreateDummyShardmap(Address a_io_1, Address a_io_2, Address a_io_3, Add std::optional<ShardClient *> DetermineShardLocation(const Shard &target_shard, const std::vector<Address> &a_addrs, ShardClient &a_client, const std::vector<Address> &b_addrs, ShardClient &b_client) { - for (const auto &addr : target_shard) { + for (const auto &addr : target_shard.peers) { if (addr.address == b_addrs[0]) { return &b_client; } From 1170e6762f0909055b1ae0e7411e1d093bb6eefc Mon Sep 17 00:00:00 2001 From: Tyler Neely <t@jujit.su> Date: Mon, 12 Dec 2022 15:22:17 +0000 Subject: [PATCH 2/6] Rename coordinator::Shard to coordinator::ShardMetadata to avoid conflation with storage::v3::Shard --- src/coordinator/shard_map.cpp | 10 +++---- src/coordinator/shard_map.hpp | 18 ++++++------ src/query/v2/request_router.hpp | 28 +++++++++---------- tests/simulation/request_router.cpp | 6 ++-- tests/simulation/sharded_map.cpp | 14 +++++----- tests/simulation/test_cluster.hpp | 2 +- tests/unit/high_density_shard_create_scan.cpp | 2 +- tests/unit/machine_manager.cpp | 2 +- 8 files changed, 41 insertions(+), 41 deletions(-) diff --git a/src/coordinator/shard_map.cpp b/src/coordinator/shard_map.cpp index 7334fd0f9..f38e6f823 100644 --- a/src/coordinator/shard_map.cpp +++ b/src/coordinator/shard_map.cpp @@ -360,9 +360,9 @@ bool ShardMap::SplitShard(Hlc previous_shard_map_version, LabelId label_id, cons MG_ASSERT(!shards_in_map.contains(key)); MG_ASSERT(label_spaces.contains(label_id)); - // Finding the Shard that the new PrimaryKey should map to. + // Finding the ShardMetadata that the new PrimaryKey should map to. auto prev = std::prev(shards_in_map.upper_bound(key)); - Shard duplicated_shard = prev->second; + ShardMetadata duplicated_shard = prev->second; // Apply the split shards_in_map[key] = duplicated_shard; @@ -383,7 +383,7 @@ std::optional<LabelId> ShardMap::InitializeNewLabel(std::string label_name, std: labels.emplace(std::move(label_name), label_id); PrimaryKey initial_key = SchemaToMinKey(schema); - Shard empty_shard = {}; + ShardMetadata empty_shard = {}; Shards shards = { {initial_key, empty_shard}, @@ -479,7 +479,7 @@ Shards ShardMap::GetShardsForRange(const LabelName &label_name, const PrimaryKey return shards; } -Shard ShardMap::GetShardForKey(const LabelName &label_name, const PrimaryKey &key) const { +ShardMetadata ShardMap::GetShardForKey(const LabelName &label_name, const PrimaryKey &key) const { MG_ASSERT(labels.contains(label_name)); LabelId label_id = labels.at(label_name); @@ -492,7 +492,7 @@ Shard ShardMap::GetShardForKey(const LabelName &label_name, const PrimaryKey &ke return std::prev(label_space.shards.upper_bound(key))->second; } -Shard ShardMap::GetShardForKey(const LabelId &label_id, const PrimaryKey &key) const { +ShardMetadata ShardMap::GetShardForKey(const LabelId &label_id, const PrimaryKey &key) const { MG_ASSERT(label_spaces.contains(label_id)); const auto &label_space = label_spaces.at(label_id); diff --git a/src/coordinator/shard_map.hpp b/src/coordinator/shard_map.hpp index 6bb7a0624..fc408e965 100644 --- a/src/coordinator/shard_map.hpp +++ b/src/coordinator/shard_map.hpp @@ -77,14 +77,14 @@ struct AddressAndStatus { using PrimaryKey = std::vector<PropertyValue>; -struct Shard { +struct ShardMetadata { std::vector<AddressAndStatus> peers; uint64_t version; - friend std::ostream &operator<<(std::ostream &in, const Shard &shard) { + friend std::ostream &operator<<(std::ostream &in, const ShardMetadata &shard) { using utils::print_helpers::operator<<; - in << "Shard { peers: "; + in << "ShardMetadata { peers: "; in << shard.peers; in << " version: "; in << shard.version; @@ -93,9 +93,9 @@ struct Shard { return in; } - friend bool operator==(const Shard &lhs, const Shard &rhs) = default; + friend bool operator==(const ShardMetadata &lhs, const ShardMetadata &rhs) = default; - friend bool operator<(const Shard &lhs, const Shard &rhs) { + friend bool operator<(const ShardMetadata &lhs, const ShardMetadata &rhs) { if (lhs.peers != rhs.peers) { return lhs.peers < rhs.peers; } @@ -104,7 +104,7 @@ struct Shard { } }; -using Shards = std::map<PrimaryKey, Shard>; +using Shards = std::map<PrimaryKey, ShardMetadata>; using LabelName = std::string; using PropertyName = std::string; using EdgeTypeName = std::string; @@ -126,7 +126,7 @@ PrimaryKey SchemaToMinKey(const std::vector<SchemaProperty> &schema); struct LabelSpace { std::vector<SchemaProperty> schema; // Maps between the smallest primary key stored in the shard and the shard - std::map<PrimaryKey, Shard> shards; + std::map<PrimaryKey, ShardMetadata> shards; size_t replication_factor; friend std::ostream &operator<<(std::ostream &in, const LabelSpace &label_space) { @@ -187,9 +187,9 @@ struct ShardMap { Shards GetShardsForRange(const LabelName &label_name, const PrimaryKey &start_key, const PrimaryKey &end_key) const; - Shard GetShardForKey(const LabelName &label_name, const PrimaryKey &key) const; + ShardMetadata GetShardForKey(const LabelName &label_name, const PrimaryKey &key) const; - Shard GetShardForKey(const LabelId &label_id, const PrimaryKey &key) const; + ShardMetadata GetShardForKey(const LabelId &label_id, const PrimaryKey &key) const; PropertyMap AllocatePropertyIds(const std::vector<PropertyName> &new_properties); diff --git a/src/query/v2/request_router.hpp b/src/query/v2/request_router.hpp index 05918e8a3..3dd2f164b 100644 --- a/src/query/v2/request_router.hpp +++ b/src/query/v2/request_router.hpp @@ -50,7 +50,7 @@ template <typename TStorageClient> class RsmStorageClientManager { public: using CompoundKey = io::rsm::ShardRsmKey; - using Shard = coordinator::Shard; + using ShardMetadata = coordinator::ShardMetadata; RsmStorageClientManager() = default; RsmStorageClientManager(const RsmStorageClientManager &) = delete; RsmStorageClientManager(RsmStorageClientManager &&) = delete; @@ -58,25 +58,25 @@ class RsmStorageClientManager { RsmStorageClientManager &operator=(RsmStorageClientManager &&) = delete; ~RsmStorageClientManager() = default; - void AddClient(Shard key, TStorageClient client) { cli_cache_.emplace(std::move(key), std::move(client)); } + void AddClient(ShardMetadata key, TStorageClient client) { cli_cache_.emplace(std::move(key), std::move(client)); } - bool Exists(const Shard &key) { return cli_cache_.contains(key); } + bool Exists(const ShardMetadata &key) { return cli_cache_.contains(key); } void PurgeCache() { cli_cache_.clear(); } - TStorageClient &GetClient(const Shard &key) { + TStorageClient &GetClient(const ShardMetadata &key) { auto it = cli_cache_.find(key); MG_ASSERT(it != cli_cache_.end(), "Non-existing shard client"); return it->second; } private: - std::map<Shard, TStorageClient> cli_cache_; + std::map<ShardMetadata, TStorageClient> cli_cache_; }; template <typename TRequest> struct ShardRequestState { - memgraph::coordinator::Shard shard; + memgraph::coordinator::ShardMetadata shard; TRequest request; }; @@ -125,7 +125,7 @@ class RequestRouter : public RequestRouterInterface { using CoordinatorWriteRequests = coordinator::CoordinatorWriteRequests; using CoordinatorClient = coordinator::CoordinatorClient<TTransport>; using Address = io::Address; - using Shard = coordinator::Shard; + using ShardMetadata = coordinator::ShardMetadata; using ShardMap = coordinator::ShardMap; using CompoundKey = coordinator::PrimaryKey; using VertexAccessor = query::v2::accessors::VertexAccessor; @@ -403,7 +403,7 @@ class RequestRouter : public RequestRouterInterface { private: std::vector<ShardRequestState<msgs::CreateVerticesRequest>> RequestsForCreateVertices( const std::vector<msgs::NewVertex> &new_vertices) { - std::map<Shard, msgs::CreateVerticesRequest> per_shard_request_table; + std::map<ShardMetadata, msgs::CreateVerticesRequest> per_shard_request_table; for (auto &new_vertex : new_vertices) { MG_ASSERT(!new_vertex.label_ids.empty(), "No label_ids provided for new vertex in RequestRouter::CreateVertices"); @@ -431,9 +431,9 @@ class RequestRouter : public RequestRouterInterface { std::vector<ShardRequestState<msgs::CreateExpandRequest>> RequestsForCreateExpand( const std::vector<msgs::NewExpand> &new_expands) { - std::map<Shard, msgs::CreateExpandRequest> per_shard_request_table; + std::map<ShardMetadata, msgs::CreateExpandRequest> per_shard_request_table; auto ensure_shard_exists_in_table = [&per_shard_request_table, - transaction_id = transaction_id_](const Shard &shard) { + transaction_id = transaction_id_](const ShardMetadata &shard) { if (!per_shard_request_table.contains(shard)) { msgs::CreateExpandRequest create_expand_request{.transaction_id = transaction_id}; per_shard_request_table.insert({shard, std::move(create_expand_request)}); @@ -503,7 +503,7 @@ class RequestRouter : public RequestRouterInterface { } std::vector<ShardRequestState<msgs::ExpandOneRequest>> RequestsForExpandOne(const msgs::ExpandOneRequest &request) { - std::map<Shard, msgs::ExpandOneRequest> per_shard_request_table; + std::map<ShardMetadata, msgs::ExpandOneRequest> per_shard_request_table; msgs::ExpandOneRequest top_level_rqst_template = request; top_level_rqst_template.transaction_id = transaction_id_; top_level_rqst_template.src_vertices.clear(); @@ -533,7 +533,7 @@ class RequestRouter : public RequestRouterInterface { std::vector<ShardRequestState<msgs::GetPropertiesRequest>> RequestsForGetProperties( msgs::GetPropertiesRequest &&request) { - std::map<Shard, msgs::GetPropertiesRequest> per_shard_request_table; + std::map<ShardMetadata, msgs::GetPropertiesRequest> per_shard_request_table; auto top_level_rqst_template = request; top_level_rqst_template.transaction_id = transaction_id_; top_level_rqst_template.vertex_ids.clear(); @@ -571,7 +571,7 @@ class RequestRouter : public RequestRouterInterface { return requests; } - StorageClient &GetStorageClientForShard(Shard shard) { + StorageClient &GetStorageClientForShard(ShardMetadata shard) { if (!storage_cli_manager_.Exists(shard)) { AddStorageClientToManager(shard); } @@ -583,7 +583,7 @@ class RequestRouter : public RequestRouterInterface { return GetStorageClientForShard(std::move(shard)); } - void AddStorageClientToManager(Shard target_shard) { + void AddStorageClientToManager(ShardMetadata target_shard) { MG_ASSERT(!target_shard.peers.empty()); auto leader_addr = target_shard.peers.front(); std::vector<Address> addresses; diff --git a/tests/simulation/request_router.cpp b/tests/simulation/request_router.cpp index dc60bb8e5..4248e7876 100644 --- a/tests/simulation/request_router.cpp +++ b/tests/simulation/request_router.cpp @@ -46,8 +46,8 @@ using coordinator::CoordinatorClient; using coordinator::CoordinatorRsm; using coordinator::HlcRequest; using coordinator::HlcResponse; -using coordinator::Shard; using coordinator::ShardMap; +using coordinator::ShardMetadata; using coordinator::Shards; using coordinator::Status; using io::Address; @@ -113,7 +113,7 @@ ShardMap CreateDummyShardmap(coordinator::Address a_io_1, coordinator::Address a AddressAndStatus aas1_2{.address = a_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas1_3{.address = a_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard1 = Shard{.peers = {aas1_1, aas1_2, aas1_3}, .version = 1}; + ShardMetadata shard1 = ShardMetadata{.peers = {aas1_1, aas1_2, aas1_3}, .version = 1}; auto key1 = storage::v3::PropertyValue(0); auto key2 = storage::v3::PropertyValue(0); @@ -125,7 +125,7 @@ ShardMap CreateDummyShardmap(coordinator::Address a_io_1, coordinator::Address a AddressAndStatus aas2_2{.address = b_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas2_3{.address = b_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard2 = Shard{.peers = {aas2_1, aas2_2, aas2_3}, .version = 1}; + ShardMetadata shard2 = ShardMetadata{.peers = {aas2_1, aas2_2, aas2_3}, .version = 1}; auto key3 = storage::v3::PropertyValue(12); auto key4 = storage::v3::PropertyValue(13); diff --git a/tests/simulation/sharded_map.cpp b/tests/simulation/sharded_map.cpp index cdc2d69b6..d27858abc 100644 --- a/tests/simulation/sharded_map.cpp +++ b/tests/simulation/sharded_map.cpp @@ -40,8 +40,8 @@ using memgraph::coordinator::CoordinatorRsm; using memgraph::coordinator::HlcRequest; using memgraph::coordinator::HlcResponse; using memgraph::coordinator::PrimaryKey; -using memgraph::coordinator::Shard; using memgraph::coordinator::ShardMap; +using memgraph::coordinator::ShardMetadata; using memgraph::coordinator::Shards; using memgraph::coordinator::Status; using memgraph::io::Address; @@ -109,7 +109,7 @@ ShardMap CreateDummyShardmap(Address a_io_1, Address a_io_2, Address a_io_3, Add AddressAndStatus aas1_2{.address = a_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas1_3{.address = a_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard1 = Shard{.peers = {aas1_1, aas1_2, aas1_3}, .version = 1}; + ShardMetadata shard1 = ShardMetadata{.peers = {aas1_1, aas1_2, aas1_3}, .version = 1}; const auto key1 = PropertyValue(0); const auto key2 = PropertyValue(0); @@ -121,7 +121,7 @@ ShardMap CreateDummyShardmap(Address a_io_1, Address a_io_2, Address a_io_3, Add AddressAndStatus aas2_2{.address = b_io_2, .status = Status::CONSENSUS_PARTICIPANT}; AddressAndStatus aas2_3{.address = b_io_3, .status = Status::CONSENSUS_PARTICIPANT}; - Shard shard2 = Shard{.peers = {aas2_1, aas2_2, aas2_3}, .version = 1}; + ShardMetadata shard2 = ShardMetadata{.peers = {aas2_1, aas2_2, aas2_3}, .version = 1}; auto key3 = PropertyValue(12); auto key4 = PropertyValue(13); @@ -131,9 +131,9 @@ ShardMap CreateDummyShardmap(Address a_io_1, Address a_io_2, Address a_io_3, Add return sm; } -std::optional<ShardClient *> DetermineShardLocation(const Shard &target_shard, const std::vector<Address> &a_addrs, - ShardClient &a_client, const std::vector<Address> &b_addrs, - ShardClient &b_client) { +std::optional<ShardClient *> DetermineShardLocation(const ShardMetadata &target_shard, + const std::vector<Address> &a_addrs, ShardClient &a_client, + const std::vector<Address> &b_addrs, ShardClient &b_client) { for (const auto &addr : target_shard.peers) { if (addr.address == b_addrs[0]) { return &b_client; @@ -275,7 +275,7 @@ int main() { const PrimaryKey compound_key = {cm_key_1, cm_key_2}; - // Look for Shard + // Look for ShardMetadata BasicResult<TimedOut, memgraph::coordinator::CoordinatorWriteResponses> read_res = coordinator_client.SendWriteRequest(req); diff --git a/tests/simulation/test_cluster.hpp b/tests/simulation/test_cluster.hpp index 3e14545a9..2e8bdf92f 100644 --- a/tests/simulation/test_cluster.hpp +++ b/tests/simulation/test_cluster.hpp @@ -47,8 +47,8 @@ using coordinator::GetShardMapRequest; using coordinator::GetShardMapResponse; using coordinator::Hlc; using coordinator::HlcResponse; -using coordinator::Shard; using coordinator::ShardMap; +using coordinator::ShardMetadata; using io::Address; using io::Io; using io::rsm::RsmClient; diff --git a/tests/unit/high_density_shard_create_scan.cpp b/tests/unit/high_density_shard_create_scan.cpp index cefa238ed..9fabf6ccc 100644 --- a/tests/unit/high_density_shard_create_scan.cpp +++ b/tests/unit/high_density_shard_create_scan.cpp @@ -44,8 +44,8 @@ using coordinator::GetShardMapRequest; using coordinator::GetShardMapResponse; using coordinator::Hlc; using coordinator::HlcResponse; -using coordinator::Shard; using coordinator::ShardMap; +using coordinator::ShardMetadata; using io::Address; using io::Io; using io::local_transport::LocalSystem; diff --git a/tests/unit/machine_manager.cpp b/tests/unit/machine_manager.cpp index 748233737..74b7d3863 100644 --- a/tests/unit/machine_manager.cpp +++ b/tests/unit/machine_manager.cpp @@ -45,8 +45,8 @@ using memgraph::coordinator::CoordinatorWriteRequests; using memgraph::coordinator::CoordinatorWriteResponses; using memgraph::coordinator::Hlc; using memgraph::coordinator::HlcResponse; -using memgraph::coordinator::Shard; using memgraph::coordinator::ShardMap; +using memgraph::coordinator::ShardMetadata; using memgraph::io::Io; using memgraph::io::local_transport::LocalSystem; using memgraph::io::local_transport::LocalTransport; From 76dcf3ad0f418b679a93fe7a096ce62ee2d6f94a Mon Sep 17 00:00:00 2001 From: jbajic <jure.bajic@memgraph.com> Date: Tue, 13 Dec 2022 13:21:52 +0100 Subject: [PATCH 3/6] Use std::set in LabelIndex --- src/storage/v3/indices.cpp | 25 +++++++++++-------------- src/storage/v3/indices.hpp | 31 +++++++++++-------------------- 2 files changed, 22 insertions(+), 34 deletions(-) diff --git a/src/storage/v3/indices.cpp b/src/storage/v3/indices.cpp index c3dbe6c97..aeb451128 100644 --- a/src/storage/v3/indices.cpp +++ b/src/storage/v3/indices.cpp @@ -271,8 +271,7 @@ bool CurrentVersionHasLabelProperty(const Vertex &vertex, LabelId label, Propert void LabelIndex::UpdateOnAddLabel(LabelId label, Vertex *vertex, const Transaction &tx) { auto it = index_.find(label); if (it == index_.end()) return; - auto acc = it->second.access(); - acc.insert(Entry{vertex, tx.start_timestamp.logical_id}); + it->second.insert(Entry{vertex, tx.start_timestamp.logical_id}); } bool LabelIndex::CreateIndex(LabelId label, VertexContainer &vertices) { @@ -283,12 +282,11 @@ bool LabelIndex::CreateIndex(LabelId label, VertexContainer &vertices) { return false; } try { - auto acc = it->second.access(); - for ([[maybe_unused]] auto &vertex : vertices) { + for (auto &vertex : vertices) { if (vertex.second.deleted || !VertexHasLabel(vertex, label)) { continue; } - acc.insert(Entry{&vertex, 0}); + it->second.insert(Entry{&vertex, 0}); } } catch (const utils::OutOfMemoryException &) { utils::MemoryTracker::OutOfMemoryExceptionBlocker oom_exception_blocker; @@ -309,7 +307,7 @@ std::vector<LabelId> LabelIndex::ListIndices() const { void LabelIndex::RemoveObsoleteEntries(const uint64_t clean_up_before_timestamp) { for (auto &label_storage : index_) { - auto vertices_acc = label_storage.second.access(); + auto &vertices_acc = label_storage.second; for (auto it = vertices_acc.begin(); it != vertices_acc.end();) { auto next_it = it; ++next_it; @@ -321,7 +319,7 @@ void LabelIndex::RemoveObsoleteEntries(const uint64_t clean_up_before_timestamp) if ((next_it != vertices_acc.end() && it->vertex == next_it->vertex) || !AnyVersionHasLabel(*it->vertex, label_storage.first, clean_up_before_timestamp)) { - vertices_acc.remove(*it); + vertices_acc.erase(*it); } it = next_it; @@ -329,7 +327,7 @@ void LabelIndex::RemoveObsoleteEntries(const uint64_t clean_up_before_timestamp) } } -LabelIndex::Iterable::Iterator::Iterator(Iterable *self, utils::SkipList<Entry>::Iterator index_iterator) +LabelIndex::Iterable::Iterator::Iterator(Iterable *self, LabelIndexContainer::iterator index_iterator) : self_(self), index_iterator_(index_iterator), current_vertex_accessor_(nullptr, nullptr, nullptr, self_->config_, *self_->vertex_validator_), @@ -344,7 +342,7 @@ LabelIndex::Iterable::Iterator &LabelIndex::Iterable::Iterator::operator++() { } void LabelIndex::Iterable::Iterator::AdvanceUntilValid() { - for (; index_iterator_ != self_->index_accessor_.end(); ++index_iterator_) { + for (; index_iterator_ != self_->index_accessor_->end(); ++index_iterator_) { if (index_iterator_->vertex == current_vertex_) { continue; } @@ -357,10 +355,9 @@ void LabelIndex::Iterable::Iterator::AdvanceUntilValid() { } } -LabelIndex::Iterable::Iterable(utils::SkipList<Entry>::Accessor index_accessor, LabelId label, View view, - Transaction *transaction, Indices *indices, Config::Items config, - const VertexValidator &vertex_validator) - : index_accessor_(std::move(index_accessor)), +LabelIndex::Iterable::Iterable(LabelIndexContainer &index_accessor, LabelId label, View view, Transaction *transaction, + Indices *indices, Config::Items config, const VertexValidator &vertex_validator) + : index_accessor_(&index_accessor), label_(label), view_(view), transaction_(transaction), @@ -422,7 +419,7 @@ bool LabelPropertyIndex::CreateIndex(LabelId label, PropertyId property, VertexC return false; } try { - for ([[maybe_unused]] auto &vertex : vertices) { + for (auto &vertex : vertices) { if (vertex.second.deleted || !VertexHasLabel(vertex, label)) { continue; } diff --git a/src/storage/v3/indices.hpp b/src/storage/v3/indices.hpp index d8b730a87..ef80625f2 100644 --- a/src/storage/v3/indices.hpp +++ b/src/storage/v3/indices.hpp @@ -30,7 +30,6 @@ namespace memgraph::storage::v3 { struct Indices; class LabelIndex { - private: struct Entry { Vertex *vertex; uint64_t timestamp; @@ -41,17 +40,9 @@ class LabelIndex { bool operator==(const Entry &rhs) const { return vertex == rhs.vertex && timestamp == rhs.timestamp; } }; - struct LabelStorage { - LabelId label; - utils::SkipList<Entry> vertices; - - bool operator<(const LabelStorage &rhs) const { return label < rhs.label; } - bool operator<(LabelId rhs) const { return label < rhs; } - bool operator==(const LabelStorage &rhs) const { return label == rhs.label; } - bool operator==(LabelId rhs) const { return label == rhs; } - }; - public: + using LabelIndexContainer = std::set<Entry>; + LabelIndex(Indices *indices, Config::Items config, const VertexValidator &vertex_validator) : indices_(indices), config_(config), vertex_validator_{&vertex_validator} {} @@ -72,12 +63,12 @@ class LabelIndex { class Iterable { public: - Iterable(utils::SkipList<Entry>::Accessor index_accessor, LabelId label, View view, Transaction *transaction, - Indices *indices, Config::Items config, const VertexValidator &vertex_validator); + Iterable(LabelIndexContainer &index_accessor, LabelId label, View view, Transaction *transaction, Indices *indices, + Config::Items config, const VertexValidator &vertex_validator); class Iterator { public: - Iterator(Iterable *self, utils::SkipList<Entry>::Iterator index_iterator); + Iterator(Iterable *self, LabelIndexContainer::iterator index_iterator); VertexAccessor operator*() const { return current_vertex_accessor_; } @@ -90,16 +81,16 @@ class LabelIndex { void AdvanceUntilValid(); Iterable *self_; - utils::SkipList<Entry>::Iterator index_iterator_; + LabelIndexContainer::iterator index_iterator_; VertexAccessor current_vertex_accessor_; Vertex *current_vertex_; }; - Iterator begin() { return {this, index_accessor_.begin()}; } - Iterator end() { return {this, index_accessor_.end()}; } + Iterator begin() { return {this, index_accessor_->begin()}; } + Iterator end() { return {this, index_accessor_->end()}; } private: - utils::SkipList<Entry>::Accessor index_accessor_; + LabelIndexContainer *index_accessor_; LabelId label_; View view_; Transaction *transaction_; @@ -112,7 +103,7 @@ class LabelIndex { Iterable Vertices(LabelId label, View view, Transaction *transaction) { auto it = index_.find(label); MG_ASSERT(it != index_.end(), "Index for label {} doesn't exist", label.AsUint()); - return {it->second.access(), label, view, transaction, indices_, config_, *vertex_validator_}; + return {it->second, label, view, transaction, indices_, config_, *vertex_validator_}; } int64_t ApproximateVertexCount(LabelId label) { @@ -124,7 +115,7 @@ class LabelIndex { void Clear() { index_.clear(); } private: - std::map<LabelId, utils::SkipList<Entry>> index_; + std::map<LabelId, LabelIndexContainer> index_; Indices *indices_; Config::Items config_; const VertexValidator *vertex_validator_; From 817433d342de9574fc99c24b02ea2bc78d50b783 Mon Sep 17 00:00:00 2001 From: jbajic <jure.bajic@memgraph.com> Date: Tue, 13 Dec 2022 13:32:14 +0100 Subject: [PATCH 4/6] Revert to approximate --- src/storage/v3/bindings/db_accessor.hpp | 8 ++++---- src/storage/v3/shard.hpp | 24 ++++++++++++++---------- tests/unit/storage_v3_indices.cpp | 8 ++++---- 3 files changed, 22 insertions(+), 18 deletions(-) diff --git a/src/storage/v3/bindings/db_accessor.hpp b/src/storage/v3/bindings/db_accessor.hpp index a8afdcffa..6392ed18f 100644 --- a/src/storage/v3/bindings/db_accessor.hpp +++ b/src/storage/v3/bindings/db_accessor.hpp @@ -162,23 +162,23 @@ class DbAccessor final { return accessor_->LabelPropertyIndexExists(label, prop); } - int64_t VerticesCount() const { return accessor_->VertexCount(); } + int64_t VerticesCount() const { return accessor_->ApproximateVertexCount(); } int64_t VerticesCount(storage::v3::LabelId label) const { return accessor_->ApproximateVertexCount(label); } int64_t VerticesCount(storage::v3::LabelId label, storage::v3::PropertyId property) const { - return accessor_->VertexCount(label, property); + return accessor_->ApproximateVertexCount(label, property); } int64_t VerticesCount(storage::v3::LabelId label, storage::v3::PropertyId property, const storage::v3::PropertyValue &value) const { - return accessor_->VertexCount(label, property, value); + return accessor_->ApproximateVertexCount(label, property, value); } int64_t VerticesCount(storage::v3::LabelId label, storage::v3::PropertyId property, const std::optional<utils::Bound<storage::v3::PropertyValue>> &lower, const std::optional<utils::Bound<storage::v3::PropertyValue>> &upper) const { - return accessor_->VertexCount(label, property, lower, upper); + return accessor_->ApproximateVertexCount(label, property, lower, upper); } storage::v3::IndicesInfo ListAllIndices() const { return accessor_->ListAllIndices(); } diff --git a/src/storage/v3/shard.hpp b/src/storage/v3/shard.hpp index 8542d47eb..16e2bf6be 100644 --- a/src/storage/v3/shard.hpp +++ b/src/storage/v3/shard.hpp @@ -225,30 +225,34 @@ class Shard final { const std::optional<utils::Bound<PropertyValue>> &lower_bound, const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view); - /// Return number of all vertices in the database. - int64_t VertexCount() const { return static_cast<int64_t>(shard_->vertices_.size()); } + /// Return approximate number of all vertices in the database. + /// Note that this is always an over-estimate and never an under-estimate. + int64_t ApproximateVertexCount() const { return static_cast<int64_t>(shard_->vertices_.size()); } /// Return approximate number of vertices with the given label. /// Note that this is always an over-estimate and never an under-estimate. int64_t ApproximateVertexCount(LabelId label) const { return shard_->indices_.label_index.ApproximateVertexCount(label); } - - /// Return number of vertices with the given label and property. - int64_t VertexCount(LabelId label, PropertyId property) const { + /// Return approximate number of vertices with the given label and property. + /// Note that this is always an over-estimate and never an under-estimate. + int64_t ApproximateVertexCount(LabelId label, PropertyId property) const { return shard_->indices_.label_property_index.VertexCount(label, property); } - /// Return number of vertices with the given label and the given - int64_t VertexCount(LabelId label, PropertyId property, const PropertyValue &value) const { + /// Return approximate number of vertices with the given label and the given + /// value for the given property. + /// Note that this is always an over-estimate and never an under-estimate. + int64_t ApproximateVertexCount(LabelId label, PropertyId property, const PropertyValue &value) const { return shard_->indices_.label_property_index.VertexCount(label, property, value); } - /// Return number of vertices with the given label and value for + /// Return approximate number of vertices with the given label and value for /// the given property in the range defined by provided upper and lower /// bounds. - int64_t VertexCount(LabelId label, PropertyId property, const std::optional<utils::Bound<PropertyValue>> &lower, - const std::optional<utils::Bound<PropertyValue>> &upper) const { + int64_t ApproximateVertexCount(LabelId label, PropertyId property, + const std::optional<utils::Bound<PropertyValue>> &lower, + const std::optional<utils::Bound<PropertyValue>> &upper) const { return shard_->indices_.label_property_index.VertexCount(label, property, lower, upper); } diff --git a/tests/unit/storage_v3_indices.cpp b/tests/unit/storage_v3_indices.cpp index 13f528d5a..620878fcf 100644 --- a/tests/unit/storage_v3_indices.cpp +++ b/tests/unit/storage_v3_indices.cpp @@ -652,13 +652,13 @@ TEST_F(IndexTest, LabelPropertyIndexCountEstimate) { } } - EXPECT_EQ(acc.VertexCount(label1, prop_val), 55); + EXPECT_EQ(acc.ApproximateVertexCount(label1, prop_val), 55); for (int i = 1; i <= 10; ++i) { - EXPECT_EQ(acc.VertexCount(label1, prop_val, PropertyValue(i)), i); + EXPECT_EQ(acc.ApproximateVertexCount(label1, prop_val, PropertyValue(i)), i); } - EXPECT_EQ(acc.VertexCount(label1, prop_val, memgraph::utils::MakeBoundInclusive(PropertyValue(2)), - memgraph::utils::MakeBoundInclusive(PropertyValue(6))), + EXPECT_EQ(acc.ApproximateVertexCount(label1, prop_val, memgraph::utils::MakeBoundInclusive(PropertyValue(2)), + memgraph::utils::MakeBoundInclusive(PropertyValue(6))), 2 + 3 + 4 + 5 + 6); } From a0e0791aa15d88658c66636f5333a78f42533df6 Mon Sep 17 00:00:00 2001 From: jbajic <jure.bajic@memgraph.com> Date: Thu, 15 Dec 2022 11:25:37 +0100 Subject: [PATCH 5/6] Address review comments --- src/storage/v3/delta.hpp | 3 +- src/storage/v3/indices.cpp | 51 ++++++++++++------------------- src/storage/v3/indices.hpp | 12 ++++---- src/storage/v3/mvcc.hpp | 21 +++++-------- src/storage/v3/property_value.hpp | 30 ------------------ src/storage/v3/shard.cpp | 2 +- 6 files changed, 36 insertions(+), 83 deletions(-) diff --git a/src/storage/v3/delta.hpp b/src/storage/v3/delta.hpp index 1c6e57d2b..0bc58f5ef 100644 --- a/src/storage/v3/delta.hpp +++ b/src/storage/v3/delta.hpp @@ -11,6 +11,7 @@ #pragma once +#include <cstdint> #include <memory> #include "storage/v3/edge_ref.hpp" #include "storage/v3/id_types.hpp" @@ -129,7 +130,7 @@ inline bool operator==(const PreviousPtr::Pointer &a, const PreviousPtr::Pointer inline bool operator!=(const PreviousPtr::Pointer &a, const PreviousPtr::Pointer &b) { return !(a == b); } struct Delta { - enum class Action { + enum class Action : uint8_t { // Used for both Vertex and Edge DELETE_OBJECT, RECREATE_OBJECT, diff --git a/src/storage/v3/indices.cpp b/src/storage/v3/indices.cpp index aeb451128..dd2bdf75e 100644 --- a/src/storage/v3/indices.cpp +++ b/src/storage/v3/indices.cpp @@ -12,8 +12,6 @@ #include "indices.hpp" #include <algorithm> -#include <cstddef> -#include <cstdint> #include <functional> #include <limits> @@ -342,7 +340,7 @@ LabelIndex::Iterable::Iterator &LabelIndex::Iterable::Iterator::operator++() { } void LabelIndex::Iterable::Iterator::AdvanceUntilValid() { - for (; index_iterator_ != self_->index_accessor_->end(); ++index_iterator_) { + for (; index_iterator_ != self_->index_container_->end(); ++index_iterator_) { if (index_iterator_->vertex == current_vertex_) { continue; } @@ -355,9 +353,9 @@ void LabelIndex::Iterable::Iterator::AdvanceUntilValid() { } } -LabelIndex::Iterable::Iterable(LabelIndexContainer &index_accessor, LabelId label, View view, Transaction *transaction, +LabelIndex::Iterable::Iterable(LabelIndexContainer &index_container, LabelId label, View view, Transaction *transaction, Indices *indices, Config::Items config, const VertexValidator &vertex_validator) - : index_accessor_(&index_accessor), + : index_container_(&index_container), label_(label), view_(view), transaction_(transaction), @@ -482,7 +480,7 @@ LabelPropertyIndex::Iterable::Iterator &LabelPropertyIndex::Iterable::Iterator:: } void LabelPropertyIndex::Iterable::Iterator::AdvanceUntilValid() { - for (; index_iterator_ != self_->index_accessor_->end(); ++index_iterator_) { + for (; index_iterator_ != self_->index_container_->end(); ++index_iterator_) { if (index_iterator_->vertex == current_vertex_) { continue; } @@ -497,11 +495,11 @@ void LabelPropertyIndex::Iterable::Iterator::AdvanceUntilValid() { } if (self_->upper_bound_) { if (self_->upper_bound_->value() < index_iterator_->value) { - index_iterator_ = self_->index_accessor_->end(); + index_iterator_ = self_->index_container_->end(); break; } if (!self_->upper_bound_->IsInclusive() && index_iterator_->value == self_->upper_bound_->value()) { - index_iterator_ = self_->index_accessor_->end(); + index_iterator_ = self_->index_container_->end(); break; } } @@ -528,12 +526,12 @@ const PropertyValue kSmallestMap = PropertyValue(std::map<std::string, PropertyV const PropertyValue kSmallestTemporalData = PropertyValue(TemporalData{static_cast<TemporalType>(0), std::numeric_limits<int64_t>::min()}); -LabelPropertyIndex::Iterable::Iterable(LabelPropertyIndexContainer &index_accessor, LabelId label, PropertyId property, +LabelPropertyIndex::Iterable::Iterable(LabelPropertyIndexContainer &index_container, LabelId label, PropertyId property, const std::optional<utils::Bound<PropertyValue>> &lower_bound, const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view, Transaction *transaction, Indices *indices, Config::Items config, const VertexValidator &vertex_validator) - : index_accessor_(&index_accessor), + : index_container_(&index_container), label_(label), property_(property), lower_bound_(lower_bound), @@ -641,29 +639,24 @@ LabelPropertyIndex::Iterable::Iterator LabelPropertyIndex::Iterable::begin() { // If the bounds are set and don't have comparable types we don't yield any // items from the index. if (!bounds_valid_) { - return {this, index_accessor_->end()}; + return {this, index_container_->end()}; } - auto index_iterator = index_accessor_->begin(); if (lower_bound_) { - index_iterator = std::ranges::find_if(*index_accessor_, [lower_bound = lower_bound_->value()](const auto &pair) { - return pair.value >= lower_bound; - }); + return {this, std::ranges::lower_bound(*index_container_, lower_bound_->value(), std::less{}, &Entry::value)}; } - return {this, index_iterator}; + return {this, index_container_->begin()}; } -LabelPropertyIndex::Iterable::Iterator LabelPropertyIndex::Iterable::end() { return {this, index_accessor_->end()}; } +LabelPropertyIndex::Iterable::Iterator LabelPropertyIndex::Iterable::end() { return {this, index_container_->end()}; } int64_t LabelPropertyIndex::VertexCount(LabelId label, PropertyId property, const PropertyValue &value) const { auto it = index_.find({label, property}); MG_ASSERT(it != index_.end(), "Index for label {} and property {} doesn't exist", label.AsUint(), property.AsUint()); - if (!value.IsNull()) { - return static_cast<int64_t>( - std::ranges::count_if(it->second, [&value](const auto &elem) { return elem.value == value; })); - } - // TODO Do check this + MG_ASSERT(!value.IsNull(), "Null is not supported!"); + + auto start_it = std::ranges::lower_bound(it->second, value, std::less{}, &Entry::value); return static_cast<int64_t>( - std::ranges::count_if(it->second, [&value](const auto &elem) { return elem.value == value; })); + std::ranges::count_if(start_it, it->second.end(), [&value](const auto &elem) { return elem.value == value; })); } int64_t LabelPropertyIndex::VertexCount(LabelId label, PropertyId property, @@ -675,11 +668,9 @@ int64_t LabelPropertyIndex::VertexCount(LabelId label, PropertyId property, [&index = it->second](const auto value, const auto def) { if (value) { if (value->IsInclusive()) { - return std::lower_bound(index.begin(), index.end(), value->value(), - [](const Entry &elem, const PropertyValue &val) { return elem.value < val; }); + return std::ranges::lower_bound(index, value->value(), std::less{}, &Entry::value); } - return std::upper_bound(index.begin(), index.end(), value->value(), - [](const PropertyValue &val, const Entry &elem) { return val < elem.value; }); + return std::ranges::upper_bound(index, value->value(), std::less{}, &Entry::value); } return def; }, @@ -688,11 +679,9 @@ int64_t LabelPropertyIndex::VertexCount(LabelId label, PropertyId property, [&index = it->second](const auto value, const auto def) { if (value) { if (value->IsInclusive()) { - return std::upper_bound(index.begin(), index.end(), value->value(), - [](const PropertyValue &val, const Entry &elem) { return val < elem.value; }); + return std::ranges::upper_bound(index, value->value(), std::less{}, &Entry::value); } - return std::lower_bound(index.begin(), index.end(), value->value(), - [](const Entry &elem, const PropertyValue &val) { return elem.value < val; }); + return std::ranges::lower_bound(index, value->value(), std::less{}, &Entry::value); } return def; }, diff --git a/src/storage/v3/indices.hpp b/src/storage/v3/indices.hpp index ef80625f2..d8e491470 100644 --- a/src/storage/v3/indices.hpp +++ b/src/storage/v3/indices.hpp @@ -63,7 +63,7 @@ class LabelIndex { class Iterable { public: - Iterable(LabelIndexContainer &index_accessor, LabelId label, View view, Transaction *transaction, Indices *indices, + Iterable(LabelIndexContainer &index_container, LabelId label, View view, Transaction *transaction, Indices *indices, Config::Items config, const VertexValidator &vertex_validator); class Iterator { @@ -86,11 +86,11 @@ class LabelIndex { Vertex *current_vertex_; }; - Iterator begin() { return {this, index_accessor_->begin()}; } - Iterator end() { return {this, index_accessor_->end()}; } + Iterator begin() { return {this, index_container_->begin()}; } + Iterator end() { return {this, index_container_->end()}; } private: - LabelIndexContainer *index_accessor_; + LabelIndexContainer *index_container_; LabelId label_; View view_; Transaction *transaction_; @@ -159,7 +159,7 @@ class LabelPropertyIndex { class Iterable { public: - Iterable(LabelPropertyIndexContainer &index_accessor, LabelId label, PropertyId property, + Iterable(LabelPropertyIndexContainer &index_container, LabelId label, PropertyId property, const std::optional<utils::Bound<PropertyValue>> &lower_bound, const std::optional<utils::Bound<PropertyValue>> &upper_bound, View view, Transaction *transaction, Indices *indices, Config::Items config, const VertexValidator &vertex_validator); @@ -188,7 +188,7 @@ class LabelPropertyIndex { Iterator end(); private: - LabelPropertyIndexContainer *index_accessor_; + LabelPropertyIndexContainer *index_container_; LabelId label_; PropertyId property_; std::optional<utils::Bound<PropertyValue>> lower_bound_; diff --git a/src/storage/v3/mvcc.hpp b/src/storage/v3/mvcc.hpp index 001f57003..6ce058d62 100644 --- a/src/storage/v3/mvcc.hpp +++ b/src/storage/v3/mvcc.hpp @@ -12,6 +12,7 @@ #pragma once #include <type_traits> + #include "storage/v3/edge.hpp" #include "storage/v3/property_value.hpp" #include "storage/v3/transaction.hpp" @@ -21,6 +22,10 @@ namespace memgraph::storage::v3 { +inline VertexData *GetDeltaHolder(Vertex *vertex) { return &vertex->second; } + +inline Edge *GetDeltaHolder(Edge *edge) { return edge; } + /// This function iterates through the undo buffers from an object (starting /// from the supplied delta) and determines what deltas should be applied to get /// the currently visible version of the object. When the function finds a delta @@ -83,13 +88,7 @@ inline void ApplyDeltasForRead(Transaction *transaction, const Delta *delta, Vie template <typename TObj> requires utils::SameAsAnyOf<TObj, Edge, Vertex> inline bool PrepareForWrite(Transaction *transaction, TObj *object) { - auto *delta_holder = std::invoke([object]() -> auto * { - if constexpr (std::is_same_v<TObj, Vertex>) { - return &object->second; - } else { - return object; - } - }); + auto *delta_holder = GetDeltaHolder(object); if (delta_holder->delta == nullptr) return true; const auto &delta_commit_info = *delta_holder->delta->commit_info; @@ -121,13 +120,7 @@ requires utils::SameAsAnyOf<TObj, Edge, Vertex> inline void CreateAndLinkDelta(Transaction *transaction, TObj *object, Args &&...args) { auto delta = &transaction->deltas.emplace_back(std::forward<Args>(args)..., transaction->commit_info.get(), transaction->command_id); - auto *delta_holder = std::invoke([object]() -> auto * { - if constexpr (std::is_same_v<TObj, Vertex>) { - return &object->second; - } else { - return object; - } - }); + auto *delta_holder = GetDeltaHolder(object); // The operations are written in such order so that both `next` and `prev` // chains are valid at all times. The chains must be valid at all times diff --git a/src/storage/v3/property_value.hpp b/src/storage/v3/property_value.hpp index e1e4b4d67..56902bed5 100644 --- a/src/storage/v3/property_value.hpp +++ b/src/storage/v3/property_value.hpp @@ -330,36 +330,6 @@ inline bool operator<(const PropertyValue &first, const PropertyValue &second) { } } -inline bool operator>=(const PropertyValue &first, const PropertyValue &second) { - if (!PropertyValue::AreComparableTypes(first.type(), second.type())) return first.type() >= second.type(); - switch (first.type()) { - case PropertyValue::Type::Null: - return false; - case PropertyValue::Type::Bool: - return first.ValueBool() >= second.ValueBool(); - case PropertyValue::Type::Int: - if (second.type() == PropertyValue::Type::Double) { - return static_cast<double>(first.ValueInt()) >= second.ValueDouble(); - } else { - return first.ValueInt() >= second.ValueInt(); - } - case PropertyValue::Type::Double: - if (second.type() == PropertyValue::Type::Double) { - return first.ValueDouble() >= second.ValueDouble(); - } else { - return first.ValueDouble() >= static_cast<double>(second.ValueInt()); - } - case PropertyValue::Type::String: - return first.ValueString() >= second.ValueString(); - case PropertyValue::Type::List: - return first.ValueList() >= second.ValueList(); - case PropertyValue::Type::Map: - return first.ValueMap() >= second.ValueMap(); - case PropertyValue::Type::TemporalData: - return first.ValueTemporalData() >= second.ValueTemporalData(); - } -} - inline PropertyValue::PropertyValue(const PropertyValue &other) : type_(other.type_) { switch (other.type_) { case Type::Null: diff --git a/src/storage/v3/shard.cpp b/src/storage/v3/shard.cpp index 0d8b21402..5e16209d9 100644 --- a/src/storage/v3/shard.cpp +++ b/src/storage/v3/shard.cpp @@ -1017,7 +1017,7 @@ void Shard::CollectGarbage(const io::Time current_time) { RemoveObsoleteEntries(&indices_, clean_up_before_timestamp); } - for (const auto &vertex : deleted_vertices_) { + for (const auto *vertex : deleted_vertices_) { MG_ASSERT(vertices_.erase(*vertex), "Invalid database state!"); } deleted_vertices_.clear(); From e82955895a519379cee39c308d1960baaf8720c0 Mon Sep 17 00:00:00 2001 From: jbajic <jure.bajic@memgraph.com> Date: Tue, 20 Dec 2022 16:14:01 +0100 Subject: [PATCH 6/6] Leave a TODO --- src/storage/v3/indices.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/storage/v3/indices.cpp b/src/storage/v3/indices.cpp index dd2bdf75e..2f11a35ec 100644 --- a/src/storage/v3/indices.cpp +++ b/src/storage/v3/indices.cpp @@ -654,6 +654,7 @@ int64_t LabelPropertyIndex::VertexCount(LabelId label, PropertyId property, cons MG_ASSERT(it != index_.end(), "Index for label {} and property {} doesn't exist", label.AsUint(), property.AsUint()); MG_ASSERT(!value.IsNull(), "Null is not supported!"); + // TODO(jbajic) This can be improved by exiting early auto start_it = std::ranges::lower_bound(it->second, value, std::less{}, &Entry::value); return static_cast<int64_t>( std::ranges::count_if(start_it, it->second.end(), [&value](const auto &elem) { return elem.value == value; }));