OmniSciDB  085a039ca4
 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 2020 OmniSci, 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 };
48 
55 class InsertDataLockMgr : public TableLockMgrImpl<InsertDataLockMgr> {
56  public:
58  static InsertDataLockMgr insert_data_lock_mgr;
59  return insert_data_lock_mgr;
60  }
61 
62  protected:
64 };
65 
74 class TableDataLockMgr : public TableLockMgrImpl<TableDataLockMgr> {
75  public:
77  static TableDataLockMgr data_lock_mgr;
78  return data_lock_mgr;
79  }
80 
81  protected:
83 };
84 
85 template <typename LOCK_TYPE>
87  : public LockContainerImpl<const TableDescriptor*, LOCK_TYPE> {
88  static_assert(std::is_same<LOCK_TYPE, ReadLock>::value ||
89  std::is_same<LOCK_TYPE, WriteLock>::value);
90 
91  public:
92  TableSchemaLockContainer(const TableSchemaLockContainer&) = delete; // non-copyable
93 };
94 
97  const std::string& table_name,
98  const bool populate_fragmenter) {
99  auto td_postlock = cat.getMetadataForTable(table_name, populate_fragmenter);
100  if (td_prelock != td_postlock) {
101  if (td_postlock == nullptr) {
102  throw std::runtime_error("Table/View ID " + table_name + " for catalog " +
103  cat.getCurrentDB().dbName + " does not exist");
104  } else {
105  // This should be very unusual case where a table has moved
106  // read DROP, CREATE kind of pattern
107  // but kept same name
108  // it is not safe to proceed here as the locking was based on the old
109  // chunk attributes of the table, which could belong to a different table now
110  throw std::runtime_error("Table/View ID " + table_name + " for catalog " +
111  cat.getCurrentDB().dbName +
112  " changed whilst attempting to acquire table lock");
113  }
114  }
115 }
116 
117 template <>
119  : public LockContainerImpl<const TableDescriptor*, ReadLock> {
120  public:
122  const std::string& table_name,
123  const bool populate_fragmenter = true) {
124  VLOG(1) << "Acquiring Table Schema Read Lock for table: " << table_name;
126  cat.getMetadataForTable(table_name, populate_fragmenter),
127  TableSchemaLockMgr::getReadLockForTable(cat, table_name));
128  validate_table_descriptor_after_lock(ret(), cat, table_name, populate_fragmenter);
129  return ret;
130  }
131 
133  const int table_id) {
134  const auto table_name = cat.getTableName(table_id);
135  if (!table_name.has_value()) {
136  throw std::runtime_error("Table/View ID " + std::to_string(table_id) +
137  " for catalog " + cat.getCurrentDB().dbName +
138  " does not exist. Cannot aquire read lock");
139  }
140  return acquireTableDescriptor(cat, table_name.value());
141  }
142 
143  private:
145  : LockContainerImpl<const TableDescriptor*, ReadLock>(obj, std::move(lock)) {}
146 };
147 
148 template <>
150  : public LockContainerImpl<const TableDescriptor*, WriteLock> {
151  public:
153  const std::string& table_name,
154  const bool populate_fragmenter = true) {
155  VLOG(1) << "Acquiring Table Schema Write Lock for table: " << table_name;
157  cat.getMetadataForTable(table_name, populate_fragmenter),
159  validate_table_descriptor_after_lock(ret(), cat, table_name, populate_fragmenter);
160  return ret;
161  }
162 
164  const int table_id) {
165  const auto table_name = cat.getTableName(table_id);
166  if (!table_name.has_value()) {
167  throw std::runtime_error("Table/View ID " + std::to_string(table_id) +
168  " for catalog " + cat.getCurrentDB().dbName +
169  " does not exist. Cannot aquire write lock");
170  }
171  return acquireTableDescriptor(cat, table_name.value());
172  }
173 
174  private:
177 };
178 
179 template <typename LOCK_TYPE>
181  : public LockContainerImpl<const TableDescriptor*, LOCK_TYPE> {
182  static_assert(std::is_same<LOCK_TYPE, ReadLock>::value ||
183  std::is_same<LOCK_TYPE, WriteLock>::value);
184 
185  public:
186  TableDataLockContainer(const TableDataLockContainer&) = delete; // non-copyable
187 };
188 
189 template <>
191  : public LockContainerImpl<const TableDescriptor*, WriteLock> {
192  public:
193  static auto acquire(const int db_id, const TableDescriptor* td) {
194  CHECK(td);
195  ChunkKey chunk_key{db_id, td->tableId};
196  VLOG(1) << "Acquiring Table Data Write Lock for table: " << td->tableName;
199  }
200 
201  private:
204 };
205 
206 template <>
208  : public LockContainerImpl<const TableDescriptor*, ReadLock> {
209  public:
210  static auto acquire(const int db_id, const TableDescriptor* td) {
211  CHECK(td);
212  ChunkKey chunk_key{db_id, td->tableId};
213  VLOG(1) << "Acquiring Table Data Read Lock for table: " << td->tableName;
216  }
217 
218  private:
220  : LockContainerImpl<const TableDescriptor*, ReadLock>(obj, std::move(lock)) {}
221 };
222 
223 template <typename LOCK_TYPE>
225  : public LockContainerImpl<const TableDescriptor*, LOCK_TYPE> {
226  static_assert(std::is_same<LOCK_TYPE, ReadLock>::value ||
227  std::is_same<LOCK_TYPE, WriteLock>::value);
228 
229  public:
230  TableInsertLockContainer(const TableInsertLockContainer&) = delete; // non-copyable
231 };
232 
233 template <>
235  : public LockContainerImpl<const TableDescriptor*, WriteLock> {
236  public:
237  static auto acquire(const int db_id, const TableDescriptor* td) {
238  CHECK(td);
239  ChunkKey chunk_key{db_id, td->tableId};
240  VLOG(1) << "Acquiring Table Insert Write Lock for table: " << td->tableName;
243  }
244 
245  private:
248 };
249 
250 template <>
252  : public LockContainerImpl<const TableDescriptor*, ReadLock> {
253  public:
254  static auto acquire(const int db_id, const TableDescriptor* td) {
255  CHECK(td);
256  ChunkKey chunk_key{db_id, td->tableId};
257  VLOG(1) << "Acquiring Table Insert Read Lock for table: " << td->tableName;
260  }
261 
262  private:
264  : LockContainerImpl<const TableDescriptor*, ReadLock>(obj, std::move(lock)) {}
265 };
266 
268  std::vector<std::unique_ptr<lockmgr::AbstractLockContainer<const TableDescriptor*>>>;
269 
270 } // namespace lockmgr
std::vector< int > ChunkKey
Definition: types.h:37
std::vector< std::unique_ptr< lockmgr::AbstractLockContainer< const TableDescriptor * >>> LockedTableDescriptors
Definition: LockMgr.h:268
static ReadLock getReadLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:164
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
std::string cat(Ts &&...args)
class for a per-database catalog. also includes metadata for the current database and the current use...
Definition: Catalog.h:114
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:74
TableInsertLockContainer(const TableInsertLockContainer &)=delete
std::string tableName
static WriteLock getWriteLockForTable(const Catalog_Namespace::Catalog &cat, const std::string &table_name)
Definition: LockMgrImpl.h:155
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:193
static auto acquireTableDescriptor(const Catalog_Namespace::Catalog &cat, const int table_id)
Definition: LockMgr.h:163
static TableDataLockMgr & instance()
Definition: LockMgr.h:76
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:95
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:210
This file contains the class specification and related data structures for Catalog.
static auto acquireTableDescriptor(const Catalog_Namespace::Catalog &cat, const int table_id)
Definition: LockMgr.h:132
static auto acquireTableDescriptor(const Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter=true)
Definition: LockMgr.h:152
const DBMetadata & getCurrentDB() const
Definition: Catalog.h:228
static auto acquireTableDescriptor(const Catalog_Namespace::Catalog &cat, const std::string &table_name, const bool populate_fragmenter=true)
Definition: LockMgr.h:121
TableDataLockContainer(const TableDataLockContainer &)=delete
#define CHECK(condition)
Definition: Logger.h:223
std::optional< std::string > getTableName(int32_t table_id) const
Definition: Catalog.cpp:1638
TableSchemaLockContainer(const TableSchemaLockContainer &)=delete
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:237
static InsertDataLockMgr & instance()
Definition: LockMgr.h:57
static auto acquire(const int db_id, const TableDescriptor *td)
Definition: LockMgr.h:254
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:55
#define VLOG(n)
Definition: Logger.h:317