1/**
2 * Copyright 2021 Alibaba, Inc. and its affiliates. All Rights Reserved.
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15
16 * \author Haichao.chc
17 * \date Oct 2020
18 * \brief Provides management of collection version meta info
19 */
20
21#pragma once
22
23#include <memory>
24#include "common/macro_define.h"
25#include "common/types.h"
26#include "snapshot.h"
27#include "typedef.h"
28#include "version_store.h"
29
30namespace proxima {
31namespace be {
32namespace index {
33
34class VersionManager;
35using VersionManagerPtr = std::shared_ptr<VersionManager>;
36
37/*
38 * Version edit of one segment change
39 */
40struct VersionEdit {
41 std::vector<SegmentID> add_segments;
42 std::vector<SegmentID> delete_segments;
43};
44
45/*
46 * VersionManager is reponsible for recording the stats the segments of
47 * collection. The meta info of collection will snapshot to persist
48 * storage at the same time.
49 */
50class VersionManager {
51 public:
52 PROXIMA_DISALLOW_COPY_AND_ASSIGN(VersionManager);
53
54 //! Constructor
55 VersionManager(const std::string &coll_name, const std::string &coll_path)
56 : collection_name_(coll_name), collection_path_(coll_path) {}
57
58 //! Destructor
59 ~VersionManager();
60
61 //! Create an instance
62 static VersionManagerPtr Create(const std::string &collection_name,
63 const std::string &collection_path);
64
65 //! Create an instance and open
66 static int CreateAndOpen(const std::string &collection_name,
67 const std::string &collection_path,
68 const ReadOptions &options,
69 VersionManagerPtr *version_manager);
70
71 public:
72 //! Open persist storage and open
73 int open(const ReadOptions &options);
74
75 //! Flush memory to persist storage
76 int flush();
77
78 //! Close persist storage and cleanup
79 int close();
80
81 public:
82 //! Apply a version edit
83 int apply(const VersionEdit &edit);
84
85 //! Return current version segment metas
86 const std::vector<SegmentMeta> &current_version() const {
87 return current_version_;
88 }
89
90 //! Allocate new segment meta
91 int alloc_segment_meta(SegmentMeta *segment_meta) {
92 CHECK_STATUS(opened_, true);
93 return version_store_.alloc_segment_meta(segment_meta);
94 }
95
96 //! Get segment meta
97 int get_segment_meta(SegmentID segment_id, SegmentMeta *segment_meta) const {
98 CHECK_STATUS(opened_, true);
99 return version_store_.get_segment_meta(segment_id, segment_meta);
100 }
101
102 //! Get all segment metas
103 int get_segment_metas(SegmentState state,
104 std::vector<SegmentMeta> *segment_metas) const {
105 CHECK_STATUS(opened_, true);
106 for (uint32_t i = 0; i < version_store_.total_segment_count(); i++) {
107 SegmentMeta segment_meta;
108 int ret = version_store_.get_segment_meta(i, &segment_meta);
109 CHECK_RETURN(ret, 0);
110 if (segment_meta.state == state) {
111 segment_metas->emplace_back(segment_meta);
112 }
113 }
114 return 0;
115 }
116
117 //! Update segment meta
118 int update_segment_meta(const SegmentMeta &segment_meta) {
119 CHECK_STATUS(opened_, true);
120 return version_store_.update_segment_meta(segment_meta);
121 }
122
123 //! Get summary
124 int get_collection_summary(CollectionSummary *summary) const {
125 CHECK_STATUS(opened_, true);
126 return version_store_.get_collection_summary(summary);
127 }
128
129 //! Update summary
130 int update_collection_summary(const CollectionSummary &summary) {
131 CHECK_STATUS(opened_, true);
132 return version_store_.update_collection_summary(summary);
133 }
134
135 public:
136 //! Return belonged collection name
137 const std::string &collection_name() const {
138 return collection_name_;
139 }
140
141 //! Return index file path
142 const std::string &file_path() const {
143 return snapshot_->file_path();
144 }
145
146 //! Return total segment count
147 uint32_t total_segment_count() const {
148 return version_store_.total_segment_count();
149 }
150
151 private:
152 std::string collection_name_{};
153 std::string collection_path_{};
154
155 SnapshotPtr snapshot_{};
156 VersionStore version_store_{};
157 std::vector<SegmentMeta> current_version_{};
158 std::mutex mutex_{};
159
160 bool opened_{false};
161};
162
163
164} // end namespace index
165} // namespace be
166} // end namespace proxima
167