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 storage & search ability of lsn context information
19 */
20
21#pragma once
22
23#include <ailego/container/heap.h>
24#include <ailego/parallel/lock.h>
25#include "common/macro_define.h"
26#include "snapshot.h"
27#include "typedef.h"
28
29namespace proxima {
30namespace be {
31namespace index {
32
33class LsnStore;
34using LsnStorePtr = std::shared_ptr<LsnStore>;
35
36/*
37 * LsnStore is mainly for storage of mysql log sequence number and context.
38 */
39class LsnStore {
40 public:
41 /*
42 * Header info
43 */
44 struct Header {
45 uint64_t tail_block_index{0U};
46 uint64_t lsn_count{0U};
47 uint64_t reserved_[6];
48 };
49
50 static_assert(sizeof(Header) % 64 == 0,
51 "Header must be aligned with 64 bytes");
52
53 /*
54 * LSN struct, includes lsn and context
55 */
56 struct LSN {
57 uint64_t lsn{0U};
58 std::string lsn_context;
59
60 LSN() = default;
61
62 LSN(uint64_t lsn_val, const std::string &lsn_context_val) {
63 lsn = lsn_val;
64 lsn_context = lsn_context_val;
65 }
66
67 bool operator<(const LSN &other) const {
68 return lsn < other.lsn;
69 }
70
71 bool operator>(const LSN &other) const {
72 return lsn > other.lsn;
73 }
74 };
75
76 public:
77 PROXIMA_DISALLOW_COPY_AND_ASSIGN(LsnStore);
78
79 //! Constructor
80 LsnStore(const std::string &coll_name, const std::string &coll_path)
81 : collection_name_(coll_name), collection_path_(coll_path) {}
82
83 //! Destructor
84 ~LsnStore();
85
86 //! Create instance
87 static LsnStorePtr Create(const std::string &collection_name,
88 const std::string &collection_path);
89
90 //! Create instance and open
91 static int CreateAndOpen(const std::string &collection_name,
92 const std::string &collection_path,
93 const ReadOptions &read_options,
94 LsnStorePtr *lsn_store);
95
96 public:
97 //! Open persist storage and initialize
98 int open(const ReadOptions &read_options);
99
100 //! Flush memory to persist storage
101 int flush();
102
103 //! Close persist storage
104 int close();
105
106 public:
107 //! Append <lsn, lsn_context> pair
108 int append(uint64_t lsn, const std::string &lsn_context);
109
110 //! Shift inner segment
111 int shift();
112
113 //! Get latest lsn and context
114 int get_latest_lsn(uint64_t *lsn, std::string *lsn_context);
115
116 public:
117 //! Return collection name
118 const std::string &collection_name() const {
119 return collection_name_;
120 }
121
122 //! Return index file path
123 const std::string &file_path() const {
124 return file_path_;
125 }
126
127 //! Return stored lsn count
128 size_t count() const {
129 return header_.lsn_count;
130 }
131
132 private:
133 int mount();
134
135 void unmount();
136
137 int update_header();
138
139 private:
140 static constexpr uint64_t kWindowSize = 2000;
141 static constexpr uint64_t kDataBlockCount = 3;
142 static constexpr uint64_t kDataBlockSize = 1UL * 1024UL * 1024UL;
143
144 private:
145 std::string collection_name_{};
146 std::string collection_path_{};
147 std::string file_path_{};
148
149 SnapshotPtr snapshot_{};
150 IndexBlockPtr header_block_{};
151 std::vector<IndexBlockPtr> data_blocks_{};
152 Header header_;
153 ailego::SharedMutex mutex_{};
154
155 bool opened_{false};
156};
157
158
159} // end namespace index
160} // namespace be
161} // end namespace proxima
162