OmniSciDB  a5dc49c757
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
LockMgr.h
Go to the documentation of this file.
1 /*
2  * Copyright 2022 HEAVY.AI, Inc.
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 
17 #pragma once
18 
19 #include "LockMgr/LegacyLockMgr.h"
20 #include "LockMgr/LockMgrImpl.h"
21 
22 #include <map>
23 #include <memory>
24 #include <string>
25 
26 #include "Catalog/Catalog.h"
28 #include "Shared/types.h"
29 
30 namespace lockmgr {
31 
38 class TableSchemaLockMgr : public TableLockMgrImpl<TableSchemaLockMgr> {
39  public:
41  static TableSchemaLockMgr table_lock_mgr;
42  return table_lock_mgr;
43  }
44 
45  private:
47  static inline constexpr std::string_view kind = "schema";
48 };
49 
56 class InsertDataLockMgr : public TableLockMgrImpl<InsertDataLockMgr> {
57  public:
59  static InsertDataLockMgr insert_data_lock_mgr;
60  return insert_data_lock_mgr;
61  }
62 
63  protected:
65  static inline constexpr std::string_view kind = "insert";
66 };
67 
76 class TableDataLockMgr : public TableLockMgrImpl<TableDataLockMgr> {
77  public:
79  static TableDataLockMgr data_lock_mgr;
80  return data_lock_mgr;
81  }
82 
83  protected:
85  static inline constexpr std::string_view kind = "data";
86 };
87 
88 template <typename LOCK_TYPE>
90  : public LockContainerImpl<const TableDescriptor*, LOCK_TYPE> {
91  static_assert(std::is_same<LOCK_TYPE, ReadLock>::value ||
92  std::is_same<LOCK_TYPE, WriteLock>::value);
93 
94  public:
95  TableSchemaLockContainer(const TableSchemaLockContainer&) = delete; // non-copyable
96 };
97 
100  const std::string& table_name,
101  const bool populate_fragmenter) {
102  auto td_postlock = cat.getMetadataForTable(table_name, populate_fragmenter);
103  if (td_prelock != td_postlock) {
104  if (td_postlock == nullptr) {
106  cat.getCurrentDB().dbName);
107  } else {
108  // This should be very unusual case where a table has moved
109  // read DROP, CREATE kind of pattern
110  // but kept same name
111  // it is not safe to proceed here as the locking was based on the old
112  // chunk attributes of the table, which could belong to a different table now
114  table_name,
115  cat.getCurrentDB().dbName,
116  " Changed whilst attempting to acquire table lock");
117  }
118  }
119 }
120 
121 template <>
123  : public LockContainerImpl<const TableDescriptor*, ReadLock> {
124  public:
126  const std::string& table_name,
127  const bool populate_fragmenter = true) {
128  VLOG(1) << "Acquiring Table Schema Read Lock for table: " << table_name;
129  auto lock = TableSchemaLockMgr::getReadLockForTable(cat, table_name);
131  cat.getMetadataForTable(table_name, populate_fragmenter), std::move(lock));
132  validate_table_descriptor_after_lock(ret(), cat, table_name, populate_fragmenter);
133  return ret;
134  }
135 
137  const int table_id) {
138  const auto table_name = cat.getTableName(table_id);
139  if (!table_name.has_value()) {
141  cat.getCurrentDB().dbName,
142  " Cannot acquire read lock");
143  }
144  return acquireTableDescriptor(cat, table_name.value());
145  }
146 
147  private:
149  : LockContainerImpl<const TableDescriptor*, ReadLock>(obj, std::move(lock)) {}
150 };
151 
152 template <>
154  : public LockContainerImpl<const TableDescriptor*, WriteLock> {
155  public:
157  const std::string& table_name,
158  const bool populate_fragmenter = true) {
159  VLOG(1) << "Acquiring Table Schema Write Lock for table: " << table_name;
160  auto lock = TableSchemaLockMgr::getWriteLockForTable(cat, table_name);
162  cat.getMetadataForTable(table_name, populate_fragmenter), std::move(lock));
163  validate_table_descriptor_after_lock(ret(), cat, table_name, populate_fragmenter);
164  return ret;
165  }
166 
168  const int table_id) {
169  const auto table_name = cat.getTableName(table_id);
170  if (!table_name.has_value()) {
172  cat.getCurrentDB().dbName,
173  " Cannot acquire write lock");
174  }
175  return acquireTableDescriptor(cat, table_name.value());
176  }
177 
178  private:
181 };
182 
183 template <typename LOCK_TYPE>
185  : public LockContainerImpl<const TableDescriptor*, LOCK_TYPE> {
186  static_assert(std::is_same<LOCK_TYPE, ReadLock>::value ||
187  std::is_same<LOCK_TYPE, WriteLock>::value);
188 
189  public:
190  TableDataLockContainer(const TableDataLockContainer&) = delete; // non-copyable
191 };
192 
193 template <>
195  : public LockContainerImpl<const TableDescriptor*, WriteLock> {
196  public:
197  static auto acquire(const int db_id, const TableDescriptor* td) {
198  CHECK(td);
199  ChunkKey chunk_key{db_id, td->tableId};
200  VLOG(1) << "Acquiring Table Data Write Lock for table: " << td->tableName;
203  }
204 
205  private:
208 };
209 
210 template <>
212  : public LockContainerImpl<const TableDescriptor*, ReadLock> {
213  public:
214  static auto acquire(const int db_id, const TableDescriptor* td) {
215  CHECK(td);
216  ChunkKey chunk_key{db_id, td->tableId};
217  VLOG(1) << "Acquiring Table Data Read Lock for table: " << td->tableName;
220  }
221 
222  private:
224  : LockContainerImpl<const TableDescriptor*, ReadLock>(obj, std::move(lock)) {}
225 };
226 
227 template <typename LOCK_TYPE>
229  : public LockContainerImpl<const TableDescriptor*, LOCK_TYPE> {
230  static_assert(std::is_same<LOCK_TYPE, ReadLock>::value ||
231  std::is_same<LOCK_TYPE, WriteLock>::value);
232 
233  public:
234  TableInsertLockContainer(const TableInsertLockContainer&) = delete; // non-copyable
235 };
236 
237 template <>
239  : public LockContainerImpl<const TableDescriptor*, WriteLock> {
240  public:
241  static auto acquire(const int db_id, const TableDescriptor* td) {
242  CHECK(td);
243  ChunkKey chunk_key{db_id, td->tableId};
244  VLOG(1) << "Acquiring Table Insert Write Lock for table: " << td->tableName;
247  }
248 
249  private:
252 };
253 
254 template <>
256  : public LockContainerImpl<const TableDescriptor*, ReadLock> {
257  public:
258  static auto acquire(const int db_id, const TableDescriptor* td) {
259  CHECK(td);
260  ChunkKey chunk_key{db_id, td->tableId};
261  VLOG(1) << "Acquiring Table Insert Read Lock for table: " << td->tableName;
264  }
265 
266  private:
268  : LockContainerImpl<const TableDescriptor*, ReadLock>(obj, std::move(lock)) {}
269 };
270 
272  std::vector<std::unique_ptr<lockmgr::AbstractLockContainer<const TableDescriptor*>>>;
273 
274 } // namespace lockmgr
std::vector< int > ChunkKey
Definition: types.h:36
std::vector< std::unique_ptr< lockmgr::AbstractLockContainer< const TableDescriptor * >>> LockedTableDescriptors
Definition: LockMgr.h:272
Locks protecting a physical table object returned from the catalog. Table Metadata Locks prevent inco...
Definition: LockMgr.h:38
static TableSchemaLockMgr & instance()
Definition: LockMgr.h:40
static constexpr std::string_view kind
Definition: LockMgr.h:65
std::string cat(Ts &&...args)
static auto acquireTableDescriptor(Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter=true)
Definition: LockMgr.h:156
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:143
Locks protecting table data. Read queries take a read lock, while write queries (update, delete) obtain a write lock. Note that insert queries do not currently take a write lock (to allow concurrent inserts). Instead, insert queries obtain a write lock on the table metadata to allow existing read queries to finish (and block new ones) before flushing the inserted data to disk.
Definition: LockMgr.h:76
TableInsertLockContainer(const TableInsertLockContainer &)=delete
std::string tableName
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:197
static auto acquireTableDescriptor(Catalog_Namespace::Catalog &cat, const int table_id)
Definition: LockMgr.h:167
static constexpr std::string_view kind
Definition: LockMgr.h:85
static TableDataLockMgr & instance()
Definition: LockMgr.h:78
std::string to_string(char const *&&v)
void validate_table_descriptor_after_lock(const TableDescriptor *td_prelock, const Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter)
Definition: LockMgr.h:98
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:214
This file contains the class specification and related data structures for Catalog.
const DBMetadata & getCurrentDB() const
Definition: Catalog.h:265
static auto acquireTableDescriptor(Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter=true)
Definition: LockMgr.h:125
static auto acquireTableDescriptor(Catalog_Namespace::Catalog &cat, const int table_id)
Definition: LockMgr.h:136
TableDataLockContainer(const TableDataLockContainer &)=delete
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
#define CHECK(condition)
Definition: Logger.h:291
static constexpr std::string_view kind
Definition: LockMgr.h:47
std::optional< std::string > getTableName(int32_t table_id) const
Definition: Catalog.cpp:1872
TableSchemaLockContainer(const TableSchemaLockContainer &)=delete
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:241
static InsertDataLockMgr & instance()
Definition: LockMgr.h:58
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:258
const TableDescriptor * getMetadataForTable(const std::string &tableName, const bool populateFragmenter=true) const
Returns a pointer to a const TableDescriptor struct matching the provided tableName.
Prevents simultaneous inserts into the same table. To allow concurrent Insert/Select queries...
Definition: LockMgr.h:56
static ReadLock getReadLockForTable(Catalog_Namespace::Catalog &cat, const std::string &table_name)
#define VLOG(n)
Definition: Logger.h:388