// Copyright (C) 2019-2020 Zilliz. All rights reserved. // // Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, software distributed under the License // is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express // or implied. See the License for the specific language governing permissions and limitations under the License. #pragma once #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "db/snapshot/Utils.h" #include "db/snapshot/WrappedTypes.h" namespace milvus { namespace engine { namespace snapshot { using ScopedResourcesT = std::tuple; class Snapshot : public ReferenceProxy { public: using Ptr = std::shared_ptr; explicit Snapshot(ID_TYPE id); ID_TYPE GetID() { return GetCollectionCommit()->GetID(); } ID_TYPE GetCollectionId() const { auto it = GetResources().begin(); return it->first; } const std::string& GetName() const { return GetResources().begin()->second->GetName(); } CollectionCommitPtr GetCollectionCommit() { return GetResources().begin()->second.Get(); } ID_TYPE GetLatestSchemaCommitId() const { return latest_schema_commit_id_; } // PXU TODO: add const. Need to change Scopedxxxx::Get SegmentCommitPtr GetSegmentCommit(ID_TYPE segment_id) { auto it = seg_segc_map_.find(segment_id); if (it == seg_segc_map_.end()) return nullptr; return GetResource(it->second); } PartitionCommitPtr GetPartitionCommitByPartitionId(ID_TYPE partition_id) { auto it = p_pc_map_.find(partition_id); if (it == p_pc_map_.end()) return nullptr; return GetResource(it->second); } std::vector GetFieldNames() const { std::vector names; for (auto& kv : field_names_map_) { names.emplace_back(kv.first); } return std::move(names); } bool HasField(const std::string& name) const { auto it = field_names_map_.find(name); return it != field_names_map_.end(); } bool HasFieldElement(const std::string& field_name, const std::string& field_element_name) const { auto id = GetFieldElementId(field_name, field_element_name); return id > 0; } ID_TYPE GetSegmentFileId(const std::string& field_name, const std::string& field_element_name, ID_TYPE segment_id) const { auto field_element_id = GetFieldElementId(field_name, field_element_name); auto it = element_segfiles_map_.find(field_element_id); if (it == element_segfiles_map_.end()) { return 0; } auto its = it->second.find(segment_id); if (its == it->second.end()) { return 0; } return its->second; } bool HasSegmentFile(const std::string& field_name, const std::string& field_element_name, ID_TYPE segment_id) const { auto id = GetSegmentFileId(field_name, field_element_name, segment_id); return id > 0; } ID_TYPE GetFieldElementId(const std::string& field_name, const std::string& field_element_name) const { auto itf = field_element_names_map_.find(field_name); if (itf == field_element_names_map_.end()) return false; auto itfe = itf->second.find(field_element_name); if (itfe == itf->second.end()) { return 0; } return itfe->second; } NUM_TYPE GetMaxSegmentNumByPartition(ID_TYPE partition_id) { auto it = p_max_seg_num_.find(partition_id); if (it == p_max_seg_num_.end()) return 0; return it->second; } void RefAll(); void UnRefAll(); template void DumpResource(const std::string& tag = "") { auto& resources = GetResources(); std::cout << typeid(*this).name() << " Dump" << ResourceT::Name << " Start [" << tag << "]:" << resources.size() << std::endl; for (auto& kv : resources) { std::cout << "\t" << kv.second->ToString() << std::endl; } std::cout << typeid(*this).name() << " Dump" << ResourceT::Name << " End [" << tag << "]:" << resources.size() << std::endl; } template void DoUnRef(T& resource_map) { for (auto& kv : resource_map) { kv.second->UnRef(); } } template void DoRef(T& resource_map) { for (auto& kv : resource_map) { kv.second->Ref(); } } template typename ResourceT::ScopedMapT& GetResources() { return std::get::value>(resources_); } template const typename ResourceT::ScopedMapT& GetResources() const { return std::get::value>(resources_); } template typename ResourceT::Ptr GetResource(ID_TYPE id) { auto& resources = GetResources(); auto it = resources.find(id); if (it == resources.end()) { return nullptr; } return it->second.Get(); } template void AddResource(ScopedResource& resource) { auto& resources = GetResources(); resources[resource->GetID()] = resource; } private: // PXU TODO: Re-org below data structures to reduce memory usage ScopedResourcesT resources_; ID_TYPE current_schema_id_; std::map field_names_map_; std::map> field_element_names_map_; std::map> element_segfiles_map_; std::map seg_segc_map_; std::map p_pc_map_; ID_TYPE latest_schema_commit_id_ = 0; std::map p_max_seg_num_; }; using ScopedSnapshotT = ScopedResource; using GCHandler = std::function; } // namespace snapshot } // namespace engine } // namespace milvus