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 Format of collection version meta info |
19 | */ |
20 | |
21 | #pragma once |
22 | |
23 | #include <mutex> |
24 | #include <aitheta2/index_storage.h> |
25 | #include "common/macro_define.h" |
26 | #include "common/types.h" |
27 | #include "segment/segment.h" |
28 | #include "typedef.h" |
29 | |
30 | namespace proxima { |
31 | namespace be { |
32 | namespace index { |
33 | |
34 | /** |
35 | * | SummaryBlock | VersionBlock | SegmentBlock | |
36 | * |----------------------|----------------------------|------------------| |
37 | * | CollectionSummary | VersionHeader + VersionSet | SegmentMeta... | |
38 | * |----------------------|----------------------------|------------------| |
39 | **/ |
40 | |
41 | struct CollectionSummary { |
42 | uint64_t schema_revision{0U}; |
43 | uint64_t total_doc_count{0U}; |
44 | uint64_t delete_doc_count{0U}; |
45 | uint64_t reserved_[5]; |
46 | }; |
47 | |
48 | static_assert(sizeof(CollectionSummary) % 64 == 0, |
49 | "CollectionSummary must be aligned with 64 bytes" ); |
50 | |
51 | /* |
52 | * Version info header |
53 | */ |
54 | struct { |
55 | uint64_t {0U}; |
56 | uint64_t {0U}; |
57 | uint64_t {0U}; |
58 | uint64_t [5]; |
59 | }; |
60 | |
61 | static_assert(sizeof(VersionHeader) % 64 == 0, |
62 | "VersionHeader must be aligned with 64 bytes" ); |
63 | |
64 | /* |
65 | * A VersionSet includes serveral segment metas |
66 | */ |
67 | struct VersionSet { |
68 | uint64_t segment_count{0}; |
69 | uint64_t reserved_[7]; |
70 | uint32_t segment_ids[1024]; |
71 | |
72 | VersionSet() { |
73 | memset(this->segment_ids, 0, sizeof(this->segment_ids)); |
74 | } |
75 | }; |
76 | |
77 | static_assert(sizeof(VersionSet) % 64 == 0, |
78 | "VersionSet must be aligned with 64 bytes" ); |
79 | |
80 | /* |
81 | * VersionStore describes the struct of version info storage |
82 | */ |
83 | class VersionStore { |
84 | public: |
85 | PROXIMA_DISALLOW_COPY_AND_ASSIGN(VersionStore); |
86 | |
87 | //! Constructor |
88 | VersionStore() = default; |
89 | |
90 | //! Destructor |
91 | ~VersionStore() = default; |
92 | |
93 | public: |
94 | //! Mount persist storage |
95 | int mount(const IndexStoragePtr &storage); |
96 | |
97 | //! Unmount persist storage |
98 | void unmount(); |
99 | |
100 | //! Alloc new segment meta |
101 | int alloc_segment_meta(SegmentMeta *segment_meta); |
102 | |
103 | //! Get segment meta |
104 | int get_segment_meta(SegmentID segment_id, SegmentMeta *segment_meta) const; |
105 | |
106 | //! Update segment meta |
107 | int update_segment_meta(const SegmentMeta &segment_meta); |
108 | |
109 | //! Get specified version set |
110 | int get_version_set(VersionSet *version_set) const; |
111 | |
112 | //! Update new version set |
113 | int update_version_set(const VersionSet &version_set); |
114 | |
115 | //! Get summary |
116 | int get_collection_summary(CollectionSummary *summary) const; |
117 | |
118 | //! Update summary |
119 | int update_collection_summary(const CollectionSummary &summary); |
120 | |
121 | public: |
122 | //! Return total version count |
123 | uint32_t total_version_count() const { |
124 | return header_.total_version_count; |
125 | } |
126 | |
127 | //! Return total segment count |
128 | uint32_t total_segment_count() const { |
129 | return header_.total_segment_count; |
130 | } |
131 | |
132 | private: |
133 | int init_storage(); |
134 | |
135 | int load_storage(); |
136 | |
137 | private: |
138 | int get_segment_meta_impl(SegmentID segment_id, |
139 | SegmentMeta *segment_meta) const { |
140 | size_t offset = segment_id * sizeof(SegmentMeta); |
141 | size_t read_len = segment_block_->fetch(offset, (void *)segment_meta, |
142 | sizeof(SegmentMeta)); |
143 | if (read_len != sizeof(SegmentMeta)) { |
144 | return ErrorCode_ReadData; |
145 | } |
146 | return 0; |
147 | } |
148 | |
149 | int update_segment_meta_impl(SegmentID segment_id, |
150 | const SegmentMeta &segment_meta) { |
151 | size_t offset = segment_id * sizeof(SegmentMeta); |
152 | size_t write_len = |
153 | segment_block_->write(offset, &segment_meta, sizeof(SegmentMeta)); |
154 | if (write_len != sizeof(SegmentMeta)) { |
155 | return ErrorCode_WriteData; |
156 | } |
157 | return 0; |
158 | } |
159 | |
160 | int (const VersionHeader &) { |
161 | size_t write_len = |
162 | version_block_->write(0U, &header, sizeof(VersionHeader)); |
163 | if (write_len != sizeof(VersionHeader)) { |
164 | return ErrorCode_WriteData; |
165 | } |
166 | return 0; |
167 | } |
168 | |
169 | private: |
170 | constexpr static uint32_t kMaxVersionCount = 5; |
171 | constexpr static uint32_t kMaxSegmentCount = 1024; |
172 | |
173 | private: |
174 | IndexStoragePtr storage_{}; |
175 | IndexBlockPtr summary_block_{}; |
176 | IndexBlockPtr version_block_{}; |
177 | IndexBlockPtr segment_block_{}; |
178 | VersionHeader ; |
179 | |
180 | std::mutex mutex_{}; |
181 | }; |
182 | |
183 | |
184 | } // end namespace index |
185 | } // namespace be |
186 | } // end namespace proxima |
187 | |