1 /**
2  * @file   open_array.cc
3  *
4  * @section LICENSE
5  *
6  * The MIT License
7  *
8  * @copyright Copyright (c) 2017-2021 TileDB, Inc.
9  * @copyright Copyright (c) 2016 MIT and Intel Corporation
10  *
11  * Permission is hereby granted, free of charge, to any person obtaining a copy
12  * of this software and associated documentation files (the "Software"), to deal
13  * in the Software without restriction, including without limitation the rights
14  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
15  * copies of the Software, and to permit persons to whom the Software is
16  * furnished to do so, subject to the following conditions:
17  *
18  * The above copyright notice and this permission notice shall be included in
19  * all copies or substantial portions of the Software.
20  *
21  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
22  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
23  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
24  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
25  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
26  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
27  * THE SOFTWARE.
28  *
29  * @section DESCRIPTION
30  *
31  * This file implements the OpenArray class.
32  */
33 
34 #include "tiledb/sm/storage_manager/open_array.h"
35 #include "tiledb/sm/array_schema/array_schema.h"
36 #include "tiledb/sm/filesystem/vfs.h"
37 #include "tiledb/sm/misc/constants.h"
38 
39 #include <cassert>
40 
41 using namespace tiledb::common;
42 
43 namespace tiledb {
44 namespace sm {
45 
46 /* ****************************** */
47 /*   CONSTRUCTORS & DESTRUCTORS   */
48 /* ****************************** */
49 
OpenArray(const URI & array_uri,QueryType query_type)50 OpenArray::OpenArray(const URI& array_uri, QueryType query_type)
51     : array_uri_(array_uri)
52     , query_type_(query_type) {
53   array_schema_latest_ = nullptr;
54   cnt_ = 0;
55   filelock_ = INVALID_FILELOCK;
56 }
57 
~OpenArray()58 OpenArray::~OpenArray() {
59   tdb_delete(array_schema_latest_);
60   fragment_metadata_.clear();
61 }
62 
63 /* ****************************** */
64 /*               API              */
65 /* ****************************** */
66 
array_schema_latest() const67 ArraySchema* OpenArray::array_schema_latest() const {
68   return array_schema_latest_;
69 }
70 
71 const std::unordered_map<std::string, tdb_shared_ptr<ArraySchema>>&
array_schemas_all()72 OpenArray::array_schemas_all() {
73   return array_schemas_all_;
74 }
75 
set_array_schemas_all(const std::unordered_map<std::string,tdb_shared_ptr<ArraySchema>> & array_schemas)76 void OpenArray::set_array_schemas_all(
77     const std::unordered_map<std::string, tdb_shared_ptr<ArraySchema>>&
78         array_schemas) {
79   array_schemas_all_ = array_schemas;
80 }
81 
get_array_schema(const std::string & schema_name,tdb_shared_ptr<ArraySchema> * array_schema)82 Status OpenArray::get_array_schema(
83     const std::string& schema_name, tdb_shared_ptr<ArraySchema>* array_schema) {
84   (*array_schema) =
85       (array_schemas_all_.find(schema_name) == array_schemas_all_.end()) ?
86           tdb_shared_ptr<ArraySchema>(nullptr) :
87           array_schemas_all_[schema_name];
88   return Status::Ok();
89 }
90 
array_uri() const91 const URI& OpenArray::array_uri() const {
92   return array_uri_;
93 }
94 
set_encryption_key(const EncryptionKey & encryption_key)95 Status OpenArray::set_encryption_key(const EncryptionKey& encryption_key) {
96   return key_validation_.check_encryption_key(encryption_key);
97 }
98 
cnt() const99 uint64_t OpenArray::cnt() const {
100   return cnt_;
101 }
102 
cnt_decr()103 void OpenArray::cnt_decr() {
104   --cnt_;
105 }
106 
cnt_incr()107 void OpenArray::cnt_incr() {
108   ++cnt_;
109 }
110 
is_empty(uint64_t timestamp) const111 bool OpenArray::is_empty(uint64_t timestamp) const {
112   std::lock_guard<std::mutex> lock(local_mtx_);
113   return fragment_metadata_.empty() ||
114          (*fragment_metadata_.cbegin())->first_timestamp() > timestamp;
115 }
116 
file_lock(VFS * vfs)117 Status OpenArray::file_lock(VFS* vfs) {
118   auto uri = array_uri_.join_path(constants::filelock_name);
119   if (filelock_ == INVALID_FILELOCK)
120     RETURN_NOT_OK(vfs->filelock_lock(uri, &filelock_, true));
121 
122   return Status::Ok();
123 }
124 
file_unlock(VFS * vfs)125 Status OpenArray::file_unlock(VFS* vfs) {
126   auto uri = array_uri_.join_path(constants::filelock_name);
127   if (filelock_ != INVALID_FILELOCK)
128     RETURN_NOT_OK(vfs->filelock_unlock(uri));
129   filelock_ = INVALID_FILELOCK;
130 
131   return Status::Ok();
132 }
133 
fragment_metadata(const URI & uri) const134 tdb_shared_ptr<FragmentMetadata> OpenArray::fragment_metadata(
135     const URI& uri) const {
136   std::lock_guard<std::mutex> lock(local_mtx_);
137   auto it = fragment_metadata_set_.find(uri.to_string());
138   return (it == fragment_metadata_set_.end()) ? nullptr : it->second;
139 }
140 
memory_tracker()141 OpenArrayMemoryTracker* OpenArray::memory_tracker() {
142   return &memory_tracker_;
143 }
144 
array_metadata(const URI & uri) const145 tdb_shared_ptr<Buffer> OpenArray::array_metadata(const URI& uri) const {
146   std::lock_guard<std::mutex> lock(local_mtx_);
147   auto it = array_metadata_.find(uri.to_string());
148   return (it == array_metadata_.end()) ? nullptr : it->second;
149 }
150 
mtx_lock()151 void OpenArray::mtx_lock() {
152   mtx_.lock();
153 }
154 
mtx_unlock()155 void OpenArray::mtx_unlock() {
156   mtx_.unlock();
157 }
158 
query_type() const159 QueryType OpenArray::query_type() const {
160   return query_type_;
161 }
162 
set_array_schema(ArraySchema * array_schema)163 void OpenArray::set_array_schema(ArraySchema* array_schema) {
164   array_schema_latest_ = array_schema;
165 }
166 
insert_fragment_metadata(tdb_shared_ptr<FragmentMetadata> metadata)167 void OpenArray::insert_fragment_metadata(
168     tdb_shared_ptr<FragmentMetadata> metadata) {
169   std::lock_guard<std::mutex> lock(local_mtx_);
170   assert(metadata != nullptr);
171   fragment_metadata_.insert(metadata);
172   fragment_metadata_set_[metadata->fragment_uri().to_string()] = metadata;
173 }
174 
insert_array_metadata(const URI & uri,const tdb_shared_ptr<Buffer> & metadata)175 void OpenArray::insert_array_metadata(
176     const URI& uri, const tdb_shared_ptr<Buffer>& metadata) {
177   std::lock_guard<std::mutex> lock(local_mtx_);
178   assert(metadata != nullptr);
179   array_metadata_[uri.to_string()] = metadata;
180 }
181 
182 /* ****************************** */
183 /*        PRIVATE METHODS         */
184 /* ****************************** */
185 
186 }  // namespace sm
187 }  // namespace tiledb
188