quasardb 3.14.1.dev4__cp36-cp36m-win_amd64.whl → 3.14.1.dev6__cp36-cp36m-win_amd64.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of quasardb might be problematic. Click here for more details.

quasardb/CMakeLists.txt CHANGED
@@ -325,6 +325,7 @@ set(QDB_FILES
325
325
  batch_inserter.hpp
326
326
  blob.hpp
327
327
  cluster.hpp
328
+ cluster.cpp
328
329
  concepts.hpp
329
330
  continuous.cpp
330
331
  continuous.hpp
@@ -333,9 +334,12 @@ set(QDB_FILES
333
334
  error.hpp
334
335
  entry.hpp
335
336
  handle.hpp
337
+ handle.cpp
336
338
  logger.hpp
337
339
  logger.cpp
338
340
  masked_array.hpp
341
+ metrics.hpp
342
+ metrics.cpp
339
343
  module.hpp
340
344
  module.cpp
341
345
  node.hpp
quasardb/cluster.cpp ADDED
@@ -0,0 +1,89 @@
1
+ #include "cluster.hpp"
2
+ #include "metrics.hpp"
3
+ #include <chrono>
4
+ #include <thread>
5
+
6
+ namespace qdb
7
+ {
8
+
9
+ cluster::cluster(const std::string & uri,
10
+ const std::string & user_name,
11
+ const std::string & user_private_key,
12
+ const std::string & cluster_public_key,
13
+ const std::string & user_security_file,
14
+ const std::string & cluster_public_key_file,
15
+ std::chrono::milliseconds timeout,
16
+ bool do_version_check)
17
+ : _uri{uri}
18
+ , _handle{make_handle_ptr()}
19
+ , _json_loads{pybind11::module::import("json").attr("loads")}
20
+ , _logger("quasardb.cluster")
21
+ {
22
+ if (do_version_check == true)
23
+ {
24
+ _logger.warn(
25
+ "do_version_check parameter has been deprecated and a no-op. It will be removed from a "
26
+ "future release");
27
+ }
28
+
29
+ options().apply_credentials(user_name, user_private_key, cluster_public_key, //
30
+ user_security_file, cluster_public_key_file);
31
+
32
+ options().set_timeout(timeout);
33
+
34
+ // HACKS(leon): we need to ensure there is always one callback active
35
+ // for qdb. Callbacks can be lost when the last active session
36
+ // gets closed. As such, the most pragmatic place to 'check'
37
+ // for this callback is when establishing a new connection.
38
+ qdb::native::swap_callback();
39
+
40
+ _logger.info("Connecting to cluster %s", _uri);
41
+ _handle->connect(_uri);
42
+ }
43
+
44
+ void cluster::close()
45
+ {
46
+ _logger.info("Closing connection to cluster");
47
+
48
+ try
49
+ {
50
+ if (is_open() == true) [[likely]]
51
+ {
52
+ _handle->close();
53
+ }
54
+ }
55
+ catch (qdb::invalid_handle_exception const & e)
56
+ {
57
+ // This can happen if, for example, we call close() after an error occured; in those
58
+ // circumstances, we fully expect the connection to already be invalid, and we should
59
+ // not care if this specific exception is raised.
60
+ _logger.warn("Connection already closed");
61
+ }
62
+
63
+ _handle.reset();
64
+
65
+ assert(is_open() == false);
66
+ }
67
+
68
+ void cluster::wait_for_compaction()
69
+ {
70
+
71
+ // We define this function in the .cpp file so we can avoid including chrono and thread
72
+ // in the header file.
73
+
74
+ using namespace std::chrono_literals;
75
+
76
+ for (;;)
77
+ {
78
+ std::uint64_t progress = compact_progress();
79
+
80
+ if (progress == 0) [[unlikely]]
81
+ {
82
+ break;
83
+ }
84
+
85
+ std::this_thread::sleep_for(100ms);
86
+ }
87
+ }
88
+
89
+ }; // namespace qdb
quasardb/cluster.hpp CHANGED
@@ -57,6 +57,7 @@
57
57
  #include <pybind11/operators.h>
58
58
  #include <pybind11/stl.h>
59
59
  #include <chrono>
60
+ #include <iostream>
60
61
 
61
62
  namespace qdb
62
63
  {
@@ -71,39 +72,30 @@ public:
71
72
  const std::string & user_security_file = {},
72
73
  const std::string & cluster_public_key_file = {},
73
74
  std::chrono::milliseconds timeout = std::chrono::minutes{1},
74
- bool do_version_check = false)
75
- : _uri{uri}
76
- , _handle{make_handle_ptr()}
77
- , _json_loads{pybind11::module::import("json").attr("loads")}
78
- , _logger("quasardb.cluster")
79
- {
80
- if (do_version_check == true)
81
- {
82
- _logger.warn(
83
- "do_version_check parameter has been deprecated and a no-op. It will be removed from a "
84
- "future release");
85
- }
86
-
87
- options().apply_credentials(user_name, user_private_key, cluster_public_key, //
88
- user_security_file, cluster_public_key_file);
75
+ bool do_version_check = false);
89
76
 
90
- options().set_timeout(timeout);
91
-
92
- // HACKS(leon): we need to ensure there is always one callback active
93
- // for qdb. Callbacks can be lost when the last active session
94
- // gets closed. As such, the most pragmatic place to 'check'
95
- // for this callback is when establishing a new connection.
96
- qdb::native::swap_callback();
77
+ public:
78
+ void close();
97
79
 
98
- _logger.info("Connecting to cluster %s", _uri);
99
- _handle->connect(_uri);
80
+ bool is_open() const
81
+ {
82
+ return _handle.get() != nullptr && _handle->is_open();
100
83
  }
101
84
 
102
- public:
103
- void close()
85
+ /**
86
+ * Throws exception if the connection is not open. Should be invoked before any operation
87
+ * is done on the handle, as the QuasarDB C API only checks for a canary presence in the
88
+ * handle's memory arena. If a compiler is optimizing enough, the handle can be closed but
89
+ * the canary still present in memory, so it's UB.
90
+ *
91
+ * As such, we should check on a higher level.
92
+ */
93
+ void check_open() const
104
94
  {
105
- _logger.info("Closing connection to cluster");
106
- _handle.reset();
95
+ if (is_open() == false) [[unlikely]]
96
+ {
97
+ throw qdb::invalid_handle_exception{};
98
+ }
107
99
  }
108
100
 
109
101
  void tidy_memory()
@@ -153,11 +145,6 @@ public:
153
145
  return *this;
154
146
  }
155
147
 
156
- bool is_open() const
157
- {
158
- return _handle.get() != nullptr;
159
- }
160
-
161
148
  void exit(pybind11::object type, pybind11::object value, pybind11::object traceback)
162
149
  {
163
150
  return close();
@@ -165,6 +152,8 @@ public:
165
152
 
166
153
  pybind11::object node_config(const std::string & uri)
167
154
  {
155
+ check_open();
156
+
168
157
  const char * content = nullptr;
169
158
  qdb_size_t content_length = 0;
170
159
 
@@ -176,6 +165,8 @@ public:
176
165
 
177
166
  pybind11::object node_status(const std::string & uri)
178
167
  {
168
+ check_open();
169
+
179
170
  const char * content = nullptr;
180
171
  qdb_size_t content_length = 0;
181
172
 
@@ -187,6 +178,8 @@ public:
187
178
 
188
179
  pybind11::object node_topology(const std::string & uri)
189
180
  {
181
+ check_open();
182
+
190
183
  const char * content = nullptr;
191
184
  qdb_size_t content_length = 0;
192
185
 
@@ -199,64 +192,88 @@ public:
199
192
  public:
200
193
  qdb::tag tag(const std::string & alias)
201
194
  {
195
+ check_open();
196
+
202
197
  return qdb::tag{_handle, alias};
203
198
  }
204
199
 
205
200
  qdb::blob_entry blob(const std::string & alias)
206
201
  {
202
+ check_open();
203
+
207
204
  return qdb::blob_entry{_handle, alias};
208
205
  }
209
206
 
210
207
  qdb::string_entry string(const std::string & alias)
211
208
  {
209
+ check_open();
210
+
212
211
  return qdb::string_entry{_handle, alias};
213
212
  }
214
213
 
215
214
  qdb::integer_entry integer(const std::string & alias)
216
215
  {
216
+ check_open();
217
+
217
218
  return qdb::integer_entry{_handle, alias};
218
219
  }
219
220
 
220
221
  qdb::double_entry double_(const std::string & alias)
221
222
  {
223
+ check_open();
224
+
222
225
  return qdb::double_entry{_handle, alias};
223
226
  }
224
227
 
225
228
  qdb::timestamp_entry timestamp(const std::string & alias)
226
229
  {
230
+ check_open();
231
+
227
232
  return qdb::timestamp_entry{_handle, alias};
228
233
  }
229
234
 
230
235
  qdb::table table(const std::string & alias)
231
236
  {
237
+ check_open();
238
+
232
239
  return qdb::table{_handle, alias};
233
240
  }
234
241
 
235
242
  // the batch_inserter_ptr is non-copyable
236
243
  qdb::batch_inserter_ptr inserter(const std::vector<batch_column_info> & ci)
237
244
  {
245
+ check_open();
246
+
238
247
  return std::make_unique<qdb::batch_inserter>(_handle, ci);
239
248
  }
240
249
 
241
250
  // the batch_inserter_ptr is non-copyable
242
251
  qdb::writer_ptr writer()
243
252
  {
253
+ check_open();
254
+
244
255
  return std::make_unique<qdb::writer>(_handle);
245
256
  }
246
257
 
247
258
  // the batch_inserter_ptr is non-copyable
248
259
  qdb::writer_ptr pinned_writer()
249
260
  {
261
+ check_open();
262
+
250
263
  return writer();
251
264
  }
252
265
 
253
266
  qdb::options options()
254
267
  {
268
+ check_open();
269
+
255
270
  return qdb::options{_handle};
256
271
  }
257
272
 
258
273
  qdb::perf perf()
259
274
  {
275
+ check_open();
276
+
260
277
  return qdb::perf{_handle};
261
278
  }
262
279
 
@@ -268,6 +285,8 @@ public:
268
285
  public:
269
286
  std::vector<std::string> prefix_get(const std::string & prefix, qdb_int_t max_count)
270
287
  {
288
+ check_open();
289
+
271
290
  const char ** result = nullptr;
272
291
  size_t count = 0;
273
292
 
@@ -283,6 +302,8 @@ public:
283
302
 
284
303
  qdb_uint_t prefix_count(const std::string & prefix)
285
304
  {
305
+ check_open();
306
+
286
307
  qdb_uint_t count = 0;
287
308
 
288
309
  const qdb_error_t err = qdb_prefix_count(*_handle, prefix.c_str(), &count);
@@ -294,22 +315,30 @@ public:
294
315
  public:
295
316
  qdb::find_query find(const std::string & query_string)
296
317
  {
318
+ check_open();
319
+
297
320
  return qdb::find_query{_handle, query_string};
298
321
  }
299
322
 
300
323
  py::object query(const std::string & query_string, const py::object & blobs)
301
324
  {
325
+ check_open();
326
+
302
327
  return py::cast(qdb::dict_query(_handle, query_string, blobs));
303
328
  }
304
329
 
305
330
  py::object query_numpy(const std::string & query_string)
306
331
  {
332
+ check_open();
333
+
307
334
  return py::cast(qdb::numpy_query(_handle, query_string));
308
335
  }
309
336
 
310
337
  std::shared_ptr<qdb::query_continuous> query_continuous_full(
311
338
  const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
312
339
  {
340
+ check_open();
341
+
313
342
  return std::make_shared<qdb::query_continuous>(
314
343
  _handle, qdb_query_continuous_full, pace, query_string, blobs);
315
344
  }
@@ -317,6 +346,8 @@ public:
317
346
  std::shared_ptr<qdb::query_continuous> query_continuous_new_values(
318
347
  const std::string & query_string, std::chrono::milliseconds pace, const py::object & blobs)
319
348
  {
349
+ check_open();
350
+
320
351
  return std::make_shared<qdb::query_continuous>(
321
352
  _handle, qdb_query_continuous_new_values_only, pace, query_string, blobs);
322
353
  }
@@ -324,6 +355,8 @@ public:
324
355
  public:
325
356
  std::vector<std::string> suffix_get(const std::string & suffix, qdb_int_t max_count)
326
357
  {
358
+ check_open();
359
+
327
360
  const char ** result = nullptr;
328
361
  size_t count = 0;
329
362
 
@@ -339,6 +372,8 @@ public:
339
372
 
340
373
  qdb_uint_t suffix_count(const std::string & suffix)
341
374
  {
375
+ check_open();
376
+
342
377
  qdb_uint_t count = 0;
343
378
 
344
379
  const qdb_error_t err = qdb_suffix_count(*_handle, suffix.c_str(), &count);
@@ -350,31 +385,72 @@ public:
350
385
  public:
351
386
  void purge_all(std::chrono::milliseconds timeout_ms)
352
387
  {
388
+ check_open();
389
+
353
390
  qdb::qdb_throw_if_error(
354
391
  *_handle, qdb_purge_all(*_handle, static_cast<int>(timeout_ms.count())));
355
392
  }
356
393
 
357
394
  void purge_cache(std::chrono::milliseconds timeout_ms)
358
395
  {
396
+ check_open();
397
+
359
398
  qdb::qdb_throw_if_error(
360
399
  *_handle, qdb_purge_cache(*_handle, static_cast<int>(timeout_ms.count())));
361
400
  }
362
401
 
363
402
  void wait_for_stabilization(std::chrono::milliseconds timeout_ms)
364
403
  {
404
+ check_open();
405
+
365
406
  qdb::qdb_throw_if_error(
366
407
  *_handle, qdb_wait_for_stabilization(*_handle, static_cast<int>(timeout_ms.count())));
367
408
  }
368
409
 
369
410
  void trim_all(std::chrono::milliseconds pause_ms, std::chrono::milliseconds timeout_ms)
370
411
  {
412
+ check_open();
413
+
371
414
  qdb::qdb_throw_if_error(*_handle, qdb_trim_all(*_handle, static_cast<int>(pause_ms.count()),
372
415
  static_cast<int>(timeout_ms.count())));
373
416
  }
374
417
 
418
+ void compact_full()
419
+ {
420
+ check_open();
421
+
422
+ qdb_compact_params_t params{};
423
+ params.options = qdb_compact_full;
424
+
425
+ qdb::qdb_throw_if_error(*_handle, qdb_cluster_compact(*_handle, &params));
426
+ }
427
+
428
+ // Returns 0 when finished / no compaction running
429
+ std::uint64_t compact_progress()
430
+ {
431
+ check_open();
432
+
433
+ std::uint64_t progress;
434
+
435
+ qdb::qdb_throw_if_error(*_handle, qdb_cluster_get_compact_progress(*_handle, &progress));
436
+
437
+ return progress;
438
+ }
439
+
440
+ void compact_abort()
441
+ {
442
+ check_open();
443
+
444
+ qdb::qdb_throw_if_error(*_handle, qdb_cluster_abort_compact(*_handle));
445
+ }
446
+
447
+ void wait_for_compaction();
448
+
375
449
  public:
376
450
  std::vector<std::string> endpoints()
377
451
  {
452
+ check_open();
453
+
378
454
  qdb_remote_node_t * endpoints = nullptr;
379
455
  qdb_size_t count = 0;
380
456
 
@@ -465,6 +541,10 @@ static inline void register_cluster(Module & m)
465
541
  .def("purge_all", &qdb::cluster::purge_all) //
466
542
  .def("trim_all", &qdb::cluster::trim_all) //
467
543
  .def("purge_cache", &qdb::cluster::purge_cache) //
544
+ .def("compact_full", &qdb::cluster::compact_full) //
545
+ .def("compact_progress", &qdb::cluster::compact_progress) //
546
+ .def("compact_abort", &qdb::cluster::compact_abort) //
547
+ .def("wait_for_compaction", &qdb::cluster::wait_for_compaction) //
468
548
  .def("endpoints", &qdb::cluster::endpoints); //
469
549
  }
470
550
 
quasardb/error.hpp CHANGED
@@ -78,6 +78,17 @@ public:
78
78
  {}
79
79
  };
80
80
 
81
+ class invalid_handle_exception : public exception
82
+ {
83
+ public:
84
+ invalid_handle_exception() noexcept
85
+ : exception(qdb_e_invalid_handle,
86
+ std::string("Invalid handle: the connection to the cluster has been closed. Please "
87
+ "re-establish a new connection"
88
+ "with the QuasarDB cluster."))
89
+ {}
90
+ };
91
+
81
92
  class incompatible_type_exception : public exception
82
93
  {
83
94
  public:
@@ -218,7 +229,15 @@ inline void qdb_throw_if_error(
218
229
  {
219
230
  // Error context returned is not the same, which means this thread already made
220
231
  // another call to the QDB API, or the QDB API itself
221
- throw qdb::exception{err, qdb_error(err)};
232
+
233
+ switch (err)
234
+ {
235
+ case qdb_e_not_connected:
236
+ case qdb_e_invalid_handle:
237
+ throw qdb::invalid_handle_exception{};
238
+ default:
239
+ throw qdb::exception{err, qdb_error(err)};
240
+ }
222
241
  }
223
242
  assert(err_ == err);
224
243
  assert(msg_ != nullptr);
@@ -233,6 +252,10 @@ inline void qdb_throw_if_error(
233
252
  case qdb_e_invalid_query:
234
253
  throw qdb::invalid_query_exception{msg_data_};
235
254
 
255
+ case qdb_e_not_connected:
256
+ case qdb_e_invalid_handle:
257
+ throw qdb::invalid_handle_exception{};
258
+
236
259
  case qdb_e_alias_already_exists:
237
260
  throw qdb::alias_already_exists_exception{msg_data_};
238
261
 
@@ -289,6 +312,7 @@ static inline void register_errors(Module & m)
289
312
  py::register_exception<qdb::internal_local_exception>(m, "InternalLocalError", base_class);
290
313
  py::register_exception<qdb::invalid_argument_exception>(m, "InvalidArgumentError", base_class);
291
314
  py::register_exception<qdb::invalid_query_exception>(m, "InvalidQueryError", base_class);
315
+ py::register_exception<qdb::invalid_handle_exception>(m, "InvalidHandleError", base_class);
292
316
  }
293
317
 
294
318
  } // namespace qdb
quasardb/handle.cpp ADDED
@@ -0,0 +1,29 @@
1
+ #include "handle.hpp"
2
+ #include "metrics.hpp"
3
+
4
+ namespace qdb
5
+ {
6
+
7
+ void handle::connect(const std::string & uri)
8
+ {
9
+ qdb_error_t err;
10
+ {
11
+ metrics::scoped_capture{"qdb_connect"};
12
+ err = qdb_connect(handle_, uri.c_str());
13
+ }
14
+ qdb::qdb_throw_if_error(handle_, err);
15
+ }
16
+
17
+ void handle::close()
18
+ {
19
+ if (handle_ != nullptr)
20
+ {
21
+ metrics::scoped_capture{"qdb_close"};
22
+ qdb_close(handle_);
23
+ handle_ = nullptr;
24
+ }
25
+
26
+ assert(handle_ == nullptr);
27
+ }
28
+
29
+ }; // namespace qdb
quasardb/handle.hpp CHANGED
@@ -42,33 +42,50 @@ class handle
42
42
  {
43
43
  public:
44
44
  handle() noexcept
45
+ : handle_{nullptr}
45
46
  {}
46
47
 
47
48
  explicit handle(qdb_handle_t h) noexcept
48
- : _handle{h}
49
+ : handle_{h}
49
50
  {}
50
51
 
51
52
  ~handle()
52
53
  {
53
- if (_handle)
54
- {
55
- qdb_close(_handle);
56
- _handle = nullptr;
57
- }
54
+ close();
58
55
  }
59
56
 
60
- void connect(const std::string & uri)
57
+ void connect(const std::string & uri);
58
+
59
+ operator qdb_handle_t() const noexcept
61
60
  {
62
- qdb::qdb_throw_if_error(_handle, qdb_connect(_handle, uri.c_str()));
61
+ return handle_;
63
62
  }
64
63
 
65
- operator qdb_handle_t() const noexcept
64
+ void close();
65
+
66
+ constexpr inline bool is_open() const
66
67
  {
67
- return _handle;
68
+ return handle_ != nullptr;
69
+ }
70
+
71
+ /**
72
+ * Throws exception if the connection is not open. Should be invoked before any operation
73
+ * is done on the handle, as the QuasarDB C API only checks for a canary presence in the
74
+ * handle's memory arena. If a compiler is optimizing enough, the handle can be closed but
75
+ * the canary still present in memory, so it's UB.
76
+ *
77
+ * As such, we should check on a higher level.
78
+ */
79
+ inline void check_open() const
80
+ {
81
+ if (is_open() == false) [[unlikely]]
82
+ {
83
+ throw qdb::invalid_handle_exception{};
84
+ }
68
85
  }
69
86
 
70
87
  private:
71
- qdb_handle_t _handle{nullptr};
88
+ qdb_handle_t handle_{nullptr};
72
89
  };
73
90
 
74
91
  using handle_ptr = std::shared_ptr<handle>;
quasardb/logger.cpp CHANGED
@@ -11,6 +11,8 @@ void qdb::native::swap_callback()
11
11
  {
12
12
  // Potential race condition avoidance!
13
13
  std::lock_guard<std::mutex> guard(_buffer_lock);
14
+
15
+ #ifndef NDEBUG
14
16
  qdb_error_t error;
15
17
 
16
18
  error = qdb_log_remove_callback(local_callback_id);
@@ -26,6 +28,7 @@ void qdb::native::swap_callback()
26
28
  // fprintf(stderr, "unable to add new callback: %s (%#x)\n", qdb_error(error), error);
27
29
  // fflush(stderr);
28
30
  }
31
+ #endif
29
32
 
30
33
  _logger = qdb::logger("quasardb.native");
31
34
  }
quasardb/metrics.cpp ADDED
@@ -0,0 +1,103 @@
1
+ #include "metrics.hpp"
2
+ #include <mutex>
3
+
4
+ namespace qdb
5
+ {
6
+
7
+ static metrics_container_t metrics_totals_ = metrics_container_t{};
8
+ static std::mutex metrics_lock_ = std::mutex{};
9
+
10
+ metrics::scoped_capture::~scoped_capture()
11
+ {
12
+ using std::chrono::nanoseconds;
13
+
14
+ time_point_t stop = clock_t::now();
15
+
16
+ auto duration = std::chrono::duration_cast<nanoseconds>(stop - start_);
17
+
18
+ metrics::record(test_id_, duration.count());
19
+ }
20
+
21
+ metrics::measure::measure()
22
+ : start_{metrics::totals()}
23
+ {}
24
+
25
+ metrics_container_t metrics::measure::get() const
26
+ {
27
+ metrics_container_t cur = metrics::totals();
28
+
29
+ metrics_container_t ret{};
30
+
31
+ for (auto i : cur)
32
+ {
33
+ assert(ret.find(i.first) == ret.end());
34
+
35
+ metrics_container_t::const_iterator prev = start_.find(i.first);
36
+
37
+ if (prev == start_.end())
38
+ {
39
+ // Previously, metric didn't exist yet, as such it's entirely new
40
+ // and all accumulated time was within the scope.
41
+ ret.emplace(i.first, i.second);
42
+ }
43
+ else if (i.second > prev->second)
44
+ {
45
+ // Accumulated time actually increased, record difference
46
+ ret.emplace(i.first, i.second - prev->second);
47
+ }
48
+ else
49
+ {
50
+ // Integrity check: we can only increase totals over time, never decrease
51
+ assert(i.second == prev->second);
52
+ }
53
+ };
54
+
55
+ return ret;
56
+ };
57
+
58
+ /* static */ void metrics::record(std::string const & test_id, std::uint64_t nsec)
59
+ {
60
+ std::lock_guard<std::mutex> guard(metrics_lock_);
61
+
62
+ metrics_container_t::iterator pos = metrics_totals_.lower_bound(test_id);
63
+
64
+ if (pos == metrics_totals_.end() || pos->first != test_id) [[unlikely]]
65
+ {
66
+ pos = metrics_totals_.emplace_hint(pos, test_id, 0);
67
+
68
+ assert(pos->second == 0);
69
+ }
70
+
71
+ assert(pos->first == test_id);
72
+ pos->second += nsec;
73
+ }
74
+
75
+ /* static */ metrics_container_t metrics::totals()
76
+ {
77
+ std::lock_guard<std::mutex> guard(metrics_lock_);
78
+ return metrics_totals_;
79
+ }
80
+
81
+ /* static */ void metrics::clear()
82
+ {
83
+ std::lock_guard<std::mutex> guard(metrics_lock_);
84
+ metrics_totals_.clear();
85
+ }
86
+
87
+ void register_metrics(py::module_ & m)
88
+ {
89
+
90
+ py::module_ metrics_module =
91
+ m.def_submodule("metrics", "Keep track of low-level performance metrics")
92
+ .def("totals", &qdb::metrics::totals)
93
+ .def("clear", &qdb::metrics::clear);
94
+
95
+ auto metrics_measure = py::class_<qdb::metrics::measure>(
96
+ metrics_module, "Measure", "Track all metrics within a block of code")
97
+ .def(py::init())
98
+ .def("__enter__", &qdb::metrics::measure::enter)
99
+ .def("__exit__", &qdb::metrics::measure::exit)
100
+ .def("get", &qdb::metrics::measure::get);
101
+ };
102
+
103
+ }; // namespace qdb
quasardb/metrics.hpp ADDED
@@ -0,0 +1,112 @@
1
+ /*
2
+ *
3
+ * Official Python API
4
+ *
5
+ * Copyright (c) 2009-2023, quasardb SAS. All rights reserved.
6
+ * All rights reserved.
7
+ *
8
+ * Redistribution and use in source and binary forms, with or without
9
+ * modification, are permitted provided that the following conditions are met:
10
+ *
11
+ * * Redistributions of source code must retain the above copyright
12
+ * notice, this list of conditions and the following disclaimer.
13
+ * * Redistributions in binary form must reproduce the above copyright
14
+ * notice, this list of conditions and the following disclaimer in the
15
+ * documentation and/or other materials provided with the distribution.
16
+ * * Neither the name of quasardb nor the names of its contributors may
17
+ * be used to endorse or promote products derived from this software
18
+ * without specific prior written permission.
19
+ *
20
+ * THIS SOFTWARE IS PROVIDED BY QUASARDB AND CONTRIBUTORS ``AS IS'' AND ANY
21
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
22
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
23
+ * DISCLAIMED. IN NO EVENT SHALL THE REGENTS AND CONTRIBUTORS BE LIABLE FOR ANY
24
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
25
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
26
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
28
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
29
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30
+ */
31
+ #pragma once
32
+
33
+ #include <pybind11/pybind11.h>
34
+ #include <pybind11/stl.h>
35
+ #include <cassert>
36
+ #include <chrono>
37
+ #include <map>
38
+ #include <string>
39
+
40
+ namespace qdb
41
+ {
42
+ namespace py = pybind11;
43
+ using metrics_container_t = std::map<std::string, std::uint64_t>;
44
+
45
+ class metrics
46
+ {
47
+ private:
48
+ public:
49
+ /**
50
+ * Utility fixture that automatically records timings for a certain block of code.
51
+ * This is intended to be used from native C++ code only.
52
+ */
53
+ class scoped_capture
54
+ {
55
+ using clock_t = std::chrono::high_resolution_clock;
56
+ using time_point_t = std::chrono::time_point<clock_t>;
57
+
58
+ public:
59
+ scoped_capture(std::string const & test_id) noexcept
60
+ : test_id_{test_id}
61
+ , start_{clock_t::now()} {};
62
+ ~scoped_capture();
63
+
64
+ private:
65
+ std::string test_id_;
66
+ time_point_t start_;
67
+ };
68
+
69
+ /**
70
+ * Utility class that's exposed to Python which can be used to record metrics in
71
+ * a scope. It makes it easy to track the difference between the beginning and end
72
+ * of execution.
73
+ */
74
+ class measure
75
+ {
76
+ public:
77
+ measure();
78
+ ~measure(){};
79
+
80
+ public:
81
+ measure enter()
82
+ {
83
+ // No-op, all initialization is done in the constructor.
84
+ return *this;
85
+ }
86
+
87
+ void exit(py::object /* type */, py::object /* value */, py::object /* traceback */)
88
+ {}
89
+
90
+ metrics_container_t get() const;
91
+
92
+ private:
93
+ metrics_container_t start_;
94
+ };
95
+
96
+ public:
97
+ metrics() noexcept {};
98
+
99
+ ~metrics() noexcept {};
100
+
101
+ public:
102
+ static void record(std::string const & test_id, std::uint64_t nsec);
103
+
104
+ static metrics_container_t totals();
105
+ static void clear();
106
+
107
+ private:
108
+ };
109
+
110
+ void register_metrics(py::module_ & m);
111
+
112
+ } // namespace qdb
quasardb/module.cpp CHANGED
@@ -1,5 +1,6 @@
1
1
  #include "module.hpp"
2
2
  #include "cluster.hpp"
3
+ #include "metrics.hpp"
3
4
  #include "node.hpp"
4
5
  #include "writer.hpp"
5
6
  #include <functional>
@@ -62,6 +63,7 @@ PYBIND11_MODULE(quasardb, m)
62
63
  qdb::register_table_reader(m);
63
64
  qdb::register_masked_array(m);
64
65
  qdb::register_writer(m);
66
+ qdb::register_metrics(m);
65
67
 
66
68
  qdb::detail::register_ts_column(m);
67
69
  qdb::reader::register_ts_value(m);
quasardb/options.hpp CHANGED
@@ -184,6 +184,18 @@ public:
184
184
  return max_parallelism;
185
185
  }
186
186
 
187
+ void set_query_max_length(size_t query_max_length)
188
+ {
189
+ qdb::qdb_throw_if_error(*_handle, qdb_option_set_query_max_length(*_handle, query_max_length));
190
+ }
191
+
192
+ size_t get_query_max_length()
193
+ {
194
+ size_t query_max_length = 0;
195
+ qdb::qdb_throw_if_error(*_handle, qdb_option_get_query_max_length(*_handle, &query_max_length));
196
+ return query_max_length;
197
+ }
198
+
187
199
  private:
188
200
  qdb::handle_ptr _handle;
189
201
  };
@@ -221,6 +233,9 @@ static inline void register_options(Module & m)
221
233
  .def("set_client_max_parallelism", &qdb::options::set_client_max_parallelism, //
222
234
  py::arg("parallelism")) //
223
235
  .def("get_client_max_parallelism", &qdb::options::get_client_max_parallelism) //
236
+ .def("set_query_max_length", &qdb::options::set_query_max_length, //
237
+ py::arg("query_max_length")) //
238
+ .def("get_query_max_length", &qdb::options::get_query_max_length) //
224
239
  .def("set_client_soft_memory_limit", &qdb::options::set_client_soft_memory_limit, //
225
240
  py::arg("limit")) //
226
241
  ;
quasardb/qdb_api.dll CHANGED
Binary file
Binary file
quasardb/query.cpp CHANGED
@@ -31,6 +31,7 @@
31
31
 
32
32
  #include "query.hpp"
33
33
  #include "masked_array.hpp"
34
+ #include "metrics.hpp"
34
35
  #include "numpy.hpp"
35
36
  #include "traits.hpp"
36
37
  #include "utils.hpp"
@@ -390,7 +391,12 @@ numpy_query_result_t numpy_query_results(const qdb_query_result_t * r)
390
391
  dict_query_result_t dict_query(qdb::handle_ptr h, const std::string & q, const py::object & blobs)
391
392
  {
392
393
  detail::qdb_resource<qdb_query_result_t> r{*h};
393
- qdb_error_t err = qdb_query(*h, q.c_str(), &r);
394
+
395
+ qdb_error_t err;
396
+ {
397
+ metrics::scoped_capture capture{"qdb_query"};
398
+ err = qdb_query(*h, q.c_str(), &r);
399
+ }
394
400
 
395
401
  qdb::qdb_throw_if_query_error(*h, err, r.get());
396
402
 
@@ -400,7 +406,12 @@ dict_query_result_t dict_query(qdb::handle_ptr h, const std::string & q, const p
400
406
  numpy_query_result_t numpy_query(qdb::handle_ptr h, const std::string & q)
401
407
  {
402
408
  detail::qdb_resource<qdb_query_result_t> r{*h};
403
- qdb_error_t err = qdb_query(*h, q.c_str(), &r);
409
+
410
+ qdb_error_t err;
411
+ {
412
+ metrics::scoped_capture capture{"qdb_query"};
413
+ err = qdb_query(*h, q.c_str(), &r);
414
+ }
404
415
  qdb::qdb_throw_if_query_error(*h, err, r.get());
405
416
 
406
417
  return numpy_query_results(r);
quasardb/table.cpp CHANGED
@@ -1,5 +1,6 @@
1
1
  #include "table.hpp"
2
2
  #include "dispatch.hpp"
3
+ #include "metrics.hpp"
3
4
  #include "object_tracker.hpp"
4
5
  #include "table_reader.hpp"
5
6
  #include "traits.hpp"
@@ -29,6 +30,8 @@ struct column_inserter;
29
30
  pybind11::array const & timestamps, \
30
31
  qdb::masked_array const & values) \
31
32
  { \
33
+ handle->check_open(); \
34
+ \
32
35
  qdb::object_tracker::scoped_repository ctx{}; \
33
36
  qdb::object_tracker::scoped_capture capture{ctx}; \
34
37
  numpy::array::ensure<traits::datetime64_ns_dtype>(timestamps); \
@@ -66,9 +69,36 @@ inline void insert_column_dispatch(handle_ptr handle,
66
69
 
67
70
  }; // namespace detail
68
71
 
72
+ void table::_cache_columns() const
73
+ {
74
+ _handle->check_open();
75
+
76
+ detail::qdb_resource<qdb_ts_column_info_ex_t> columns{*_handle};
77
+ qdb_size_t count = 0;
78
+
79
+ qdb_error_t err;
80
+
81
+ {
82
+ metrics::scoped_capture("qdb_ts_list_columns");
83
+ err = qdb_ts_list_columns_ex(*_handle, _alias.c_str(), &columns, &count);
84
+ }
85
+
86
+ if (err == qdb_e_alias_not_found) [[unlikely]]
87
+ {
88
+ // Can happen if table does not yet exist, do nothing.
89
+ return;
90
+ }
91
+
92
+ qdb::qdb_throw_if_error(*_handle, err);
93
+
94
+ _columns = detail::convert_columns(columns.get(), count);
95
+ }
96
+
69
97
  py::object table::reader(
70
98
  const std::vector<std::string> & columns, py::object ranges, bool dict_mode) const
71
99
  {
100
+ _handle->check_open();
101
+
72
102
  auto ranges_ = qdb::convert_ranges(ranges);
73
103
 
74
104
  std::vector<detail::column_info> c_columns;
@@ -102,6 +132,8 @@ py::object table::reader(
102
132
 
103
133
  qdb_uint_t table::erase_ranges(const std::string & column, py::object ranges)
104
134
  {
135
+ _handle->check_open();
136
+
105
137
  auto ranges_ = qdb::convert_ranges(ranges);
106
138
 
107
139
  qdb_uint_t erased_count = 0;
@@ -149,6 +181,8 @@ void table::timestamp_insert(
149
181
  std::pair<pybind11::array, masked_array> table::blob_get_ranges(
150
182
  const std::string & column, py::object ranges)
151
183
  {
184
+ _handle->check_open();
185
+
152
186
  qdb_ts_blob_point * points = nullptr;
153
187
  qdb_size_t count = 0;
154
188
 
@@ -167,6 +201,8 @@ std::pair<pybind11::array, masked_array> table::blob_get_ranges(
167
201
  std::pair<pybind11::array, masked_array> table::string_get_ranges(
168
202
  const std::string & column, py::object ranges)
169
203
  {
204
+ _handle->check_open();
205
+
170
206
  qdb_ts_string_point * points = nullptr;
171
207
  qdb_size_t count = 0;
172
208
 
@@ -185,6 +221,8 @@ std::pair<pybind11::array, masked_array> table::string_get_ranges(
185
221
  std::pair<pybind11::array, masked_array> table::double_get_ranges(
186
222
  const std::string & column, py::object ranges)
187
223
  {
224
+ _handle->check_open();
225
+
188
226
  qdb_ts_double_point * points = nullptr;
189
227
  qdb_size_t count = 0;
190
228
 
@@ -203,6 +241,8 @@ std::pair<pybind11::array, masked_array> table::double_get_ranges(
203
241
  std::pair<pybind11::array, masked_array> table::int64_get_ranges(
204
242
  const std::string & column, py::object ranges)
205
243
  {
244
+ _handle->check_open();
245
+
206
246
  qdb_ts_int64_point * points = nullptr;
207
247
  qdb_size_t count = 0;
208
248
 
@@ -221,6 +261,8 @@ std::pair<pybind11::array, masked_array> table::int64_get_ranges(
221
261
  std::pair<pybind11::array, masked_array> table::timestamp_get_ranges(
222
262
  const std::string & column, py::object ranges)
223
263
  {
264
+ _handle->check_open();
265
+
224
266
  qdb_ts_timestamp_point * points = nullptr;
225
267
  qdb_size_t count = 0;
226
268
 
quasardb/table.hpp CHANGED
@@ -40,7 +40,7 @@ namespace qdb
40
40
  class table : public entry
41
41
  {
42
42
  public:
43
- table(handle_ptr h, std::string a) noexcept
43
+ table(handle_ptr h, std::string a)
44
44
  : entry{h, a}
45
45
  , _has_indexed_columns(false)
46
46
  {
@@ -64,13 +64,17 @@ public:
64
64
  void create(const std::vector<detail::column_info> & columns,
65
65
  std::chrono::milliseconds shard_size = std::chrono::hours{24})
66
66
  {
67
+ _handle->check_open();
68
+
67
69
  const auto c_columns = detail::convert_columns_ex(columns);
68
70
  qdb::qdb_throw_if_error(*_handle, qdb_ts_create_ex(*_handle, _alias.c_str(), shard_size.count(),
69
- c_columns.data(), c_columns.size()));
71
+ c_columns.data(), c_columns.size(), qdb_ttl_disabled));
70
72
  }
71
73
 
72
74
  void insert_columns(const std::vector<detail::column_info> & columns)
73
75
  {
76
+ _handle->check_open();
77
+
74
78
  const auto c_columns = detail::convert_columns_ex(columns);
75
79
  qdb::qdb_throw_if_error(*_handle,
76
80
  qdb_ts_insert_columns_ex(*_handle, _alias.c_str(), c_columns.data(), c_columns.size()));
@@ -152,23 +156,7 @@ private:
152
156
  /**
153
157
  * Loads column info / metadata from server and caches it locally.
154
158
  */
155
- void _cache_columns() const
156
- {
157
- detail::qdb_resource<qdb_ts_column_info_ex_t> columns{*_handle};
158
- qdb_size_t count = 0;
159
-
160
- auto err = qdb_ts_list_columns_ex(*_handle, _alias.c_str(), &columns, &count);
161
-
162
- if (err == qdb_e_alias_not_found) [[unlikely]]
163
- {
164
- // Can happen if table does not yet exist, do nothing.
165
- return;
166
- }
167
-
168
- qdb::qdb_throw_if_error(*_handle, err);
169
-
170
- _columns = detail::convert_columns(columns.get(), count);
171
- }
159
+ void _cache_columns() const;
172
160
 
173
161
  /**
174
162
  * Loads column info / metadata from server if not yet cached locally.
quasardb/table_reader.hpp CHANGED
@@ -88,8 +88,10 @@ public:
88
88
  return _the_row;
89
89
  }
90
90
 
91
- table_reader_iterator & operator++() noexcept
91
+ table_reader_iterator & operator++()
92
92
  {
93
+ _handle->check_open();
94
+
93
95
  qdb_error_t err = qdb_ts_table_next_row(_local_table, &_the_row.mutable_timestamp());
94
96
 
95
97
  if (err == qdb_e_iterator_end)
@@ -144,6 +146,8 @@ public:
144
146
  , _columns{c}
145
147
  , _local_table{nullptr}
146
148
  {
149
+ _handle->check_open();
150
+
147
151
  auto c_columns = convert_columns(c);
148
152
 
149
153
  qdb::qdb_throw_if_error(*_handle, qdb_ts_local_table_init(*_handle, t.c_str(), c_columns.data(),
quasardb/writer.cpp CHANGED
@@ -1,6 +1,7 @@
1
1
  #include "writer.hpp"
2
2
  #include "concepts.hpp"
3
3
  #include "dispatch.hpp"
4
+ #include "metrics.hpp"
4
5
  #include "numpy.hpp"
5
6
  #include "traits.hpp"
6
7
  #include "convert/array.hpp"
@@ -460,6 +461,8 @@ void writer::_push_impl(writer::staged_tables_t & staged_tables,
460
461
  detail::deduplicate_options deduplicate_options,
461
462
  qdb_ts_range_t * ranges)
462
463
  {
464
+ _handle->check_open();
465
+
463
466
  if (staged_tables.empty())
464
467
  {
465
468
  throw qdb::invalid_argument_exception{"No data written to batch writer."};
@@ -489,6 +492,9 @@ void writer::_push_impl(writer::staged_tables_t & staged_tables,
489
492
  batch_table.data.column_count, table_name);
490
493
  }
491
494
 
495
+ // Make sure to measure the time it takes to do the actual push
496
+ qdb::metrics::scoped_capture capture{"qdb_batch_push"};
497
+
492
498
  qdb::qdb_throw_if_error(
493
499
  *_handle, qdb_exp_batch_push(*_handle, mode, batch.data(), nullptr, batch.size()));
494
500
  }
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: quasardb
3
- Version: 3.14.1.dev4
3
+ Version: 3.14.1.dev6
4
4
  Summary: Python API for quasardb
5
5
  Home-page: https://www.quasardb.net/
6
6
  Author: quasardb SAS
@@ -1,12 +1,12 @@
1
- quasardb/CMakeLists.txt,sha256=jnXrpKZ--3pw62Vp2jY5k9xy0y407cUGO2prou4AwJc,15178
1
+ quasardb/CMakeLists.txt,sha256=Rdpd6_7EfVD7F81k7OgxH57cVFIGZzz57O2haCTSrs8,15237
2
2
  quasardb/INSTALL.vcxproj,sha256=182b6MkUQhDypzDzByrRqbjkltx4G9GczSkozHR71oQ,10356
3
3
  quasardb/INSTALL.vcxproj.filters,sha256=NcxObaNv9yKkWKYVcp7WmIr95luPm6XoSiTy3Gy_pxw,557
4
4
  quasardb/__init__.py,sha256=S5HGH9idLoUES_9XSqHnEixEC6VKwzcubJlnVvWi22E,3801
5
- quasardb/add_boost_test.cmake,sha256=A-r1WMqPO12BwWA1N-nGwtdemRWBNIOmH_eBy0pLn6w,1208
6
5
  quasardb/batch_column.hpp,sha256=txW9kYMgQzJiJlM5nD7LIVuAZpyidpS4MopPGKE95u0,3388
7
6
  quasardb/batch_inserter.hpp,sha256=bM73Z-IKow89GqoYaxDLDd0YuaN5Il4C5TjIVx9bI-Y,9803
8
7
  quasardb/blob.hpp,sha256=PObdSJxKNLIihBCLBxQHHH20t7VOmZG02wOfy8rB1-w,5846
9
- quasardb/cluster.hpp,sha256=f_8UKUdIBBaGBsBJUEMNRQYbAgHtOeLdcoAWexNMZp8,18107
8
+ quasardb/cluster.cpp,sha256=ytPCLRZVA7eTZgqIbLWKsmiugYLq80v9rSuoksKTE3c,2500
9
+ quasardb/cluster.hpp,sha256=AYZY2myVI1eeG3Cxe7yCPb7Kmlh1Ij_go4ryZdIEJHc,19405
10
10
  quasardb/cmake_install.cmake,sha256=tFc2NunSdAJjFCfrOX-O2bU3DONolbMjimQ6dEKf2kg,1479
11
11
  quasardb/concepts.hpp,sha256=Ao-UKFVjh7kRqeqsYXioV1LXiKXBR_1l54hRvUCjxKU,9574
12
12
  quasardb/continuous.cpp,sha256=18-VX7BZA60wkUq75ADU7yfgmwzT_CkG_tEAKxAVkLU,4566
@@ -18,41 +18,44 @@ quasardb/direct_integer.hpp,sha256=jHwNnAcB9wodgju8SBOsyPKWlifM094kENKSwySrSb8,3
18
18
  quasardb/dispatch.hpp,sha256=YWqTq9ehXWpphJ9piWwrKUzy3IgA5d9An0loAYQsUlg,5508
19
19
  quasardb/double.hpp,sha256=SW1z9QW09mC_8ggvleMZolivu2BHjF157IVKT_Jw638,3239
20
20
  quasardb/entry.hpp,sha256=IE6uL341x6U5dos40LhVKSJPuYZwod-oRy4PoF5a_80,9451
21
- quasardb/error.hpp,sha256=0Wkkw6se9MLbHBHFO9hHsuG2u2z473ZEPLySGXUv3Pk,9994
21
+ quasardb/error.hpp,sha256=b3BvBn0wYqHlrkH48pZod6CMjtxFu6l7SQjt88zXlwc,10807
22
22
  quasardb/firehose.py,sha256=DHYsew-aL1j5PKZonH30CrhXnwHEX1XIAhGbPrzd4PY,3593
23
- quasardb/handle.hpp,sha256=Sv8ICG6795uVz4h5b6V94Lryd08QQ1Qo6QMmvR7wCUA,2498
23
+ quasardb/handle.cpp,sha256=oyhzAj1k8UFhpLhwU5RL4cbdqt82KZexWacMFz5uXA0,536
24
+ quasardb/handle.hpp,sha256=o26dxmrXtfbxgj66QgKjW8wviUPbcZvmIAZ4L4CcdoQ,3051
24
25
  quasardb/integer.hpp,sha256=H5x8SEqlyI2nQZL9iv4GnCL0uWYuq8l8YYUzI83t0aE,3304
25
- quasardb/logger.cpp,sha256=TK5W1xIwIoXy7pLeCXkq2PEU8x6O8xXQ8w4GWDbmPbU,3030
26
+ quasardb/logger.cpp,sha256=UThEO2V6UI-tbpG9suud7olmMjIMfHr3tNt-nM48DIE,3056
26
27
  quasardb/logger.hpp,sha256=4trngfo31-OizuEkQUoYob77PVeXC283tPGaX3JRpPY,7278
27
28
  quasardb/masked_array.hpp,sha256=nfuvkFZnNoGqqtJzBZ95h4e4PguhIr5kj3tVO4y8W4U,18988
28
- quasardb/module.cpp,sha256=LzTi_RQNTakymc2rCkH9PqywW_0phl7R7A3lAS65ytg,2181
29
+ quasardb/metrics.cpp,sha256=NuEBVYlIHQRgmPy4g9Eosq1Q28Z1jySSZHKDAMLURIA,2942
30
+ quasardb/metrics.hpp,sha256=oz_XDbcMCJ9fiaYi043rFakM-mmzsuONskDfMPDf4_U,3533
31
+ quasardb/module.cpp,sha256=Nx0d3xyqCb2Red1WgsGUotaXxX6NHoDCcp9PnUzmcB0,2236
29
32
  quasardb/module.hpp,sha256=-zRcQ_lgVz4IEP3tokX4AeA33DYJ3jsq8vWX6OnE0Ic,604
30
33
  quasardb/node.hpp,sha256=_rcwUA9mOFW7b7I3B3Ll3aaBO0RoKV3LS19JITaIi6A,4771
31
34
  quasardb/numpy.cpp,sha256=0brRs6lnIpsCNvpu3twIcjizy3lMOvCBT0O4rjKAn0I,189
32
35
  quasardb/numpy.hpp,sha256=j2xGIFn98L4AAirxnkF6JaAwUBL1McfUBNsf4tlKPA0,15668
33
36
  quasardb/object_tracker.hpp,sha256=m0S0vp3WX2kFsr6cE8iPmXXO-3qRo4lcVc6TgFa-MbM,7709
34
- quasardb/options.hpp,sha256=T-Wy4PYSQv7LQY2R2-93ay4NVbNgsn2iIzOP3bbIpbk,9470
37
+ quasardb/options.hpp,sha256=hXNBVTQdrDwWkxGyFBOuRGYyJoD_IpqpitJPbDnabi0,10158
35
38
  quasardb/perf.hpp,sha256=C7dM0ZZZ4Ln5pDnZpvvUMgdwLUp4Tom51JuZICSYGGI,11364
36
39
  quasardb/pool.py,sha256=lqVZPFejmNHU7EdyeoPkl7yy_-N3BRyuLhNTzIdtg8g,8743
37
40
  quasardb/pytypes.hpp,sha256=YTc6xdmxMGMWtrZHitAl3vudZxYctOX1NwL-QDuzz1g,6894
38
- quasardb/qdb_api.dll,sha256=X8WDNYJm4guBpzqBRgdrr2vrCm33dt1bjZBolRKPc5g,14224384
39
- quasardb/quasardb.cp36-win_amd64.pyd,sha256=s1rVDCYrMfLsURLrj9Jwh3IpZMlbVa99Clr06C8A7aw,1307648
40
- quasardb/query.cpp,sha256=s3T2eaNBgJ93hEEOQbEx21sLabg16mMSuUQMwHXar7g,12558
41
+ quasardb/qdb_api.dll,sha256=JZRkdNtMmCDpr7_ZSkHYX1PWi3N5fH74SSh0D-7RWMk,15067136
42
+ quasardb/quasardb.cp36-win_amd64.pyd,sha256=-RVosWZzLQNymDbpZamuBozq3JLrJ5y4uCZzp_FUCBY,1421312
43
+ quasardb/query.cpp,sha256=FhsA93s-mXqw6WnzQgYLooy02P-haTEHkTMpdgMbdKw,12752
41
44
  quasardb/query.hpp,sha256=dBFJ0FVNJN-WdCwbHU1iNbEzDHarGGDQaZ5gto-xwkY,3357
42
45
  quasardb/remove_cvref.hpp,sha256=vKUecNoA2-BIiZeP8NuO3GgBOMF-OVSn_43LJCuDozA,611
43
46
  quasardb/stats.py,sha256=LDV4F5KTpEXa5sS_syFo_TYn9_W2X1D32Eb43GLutOs,7620
44
47
  quasardb/string.hpp,sha256=xgvRf1TXy3nl45WeCHHhtO8toUYZ2Zo7RuvTAntIgZM,6071
45
- quasardb/table.cpp,sha256=MJkgJ4I9cmORDMgD4lmuOu6UhsqKwI2x33ah3ZllfB8,9689
46
- quasardb/table.hpp,sha256=ynFnBXFPeiR2d0e4UWa_uNzt8vm-amaRxXR04qZd2bw,11361
48
+ quasardb/table.cpp,sha256=_LAltQoycIzkqg4Id4u5MHN9Uy4OD-wWZMtdxzReMDs,10725
49
+ quasardb/table.hpp,sha256=bu3n9jjNW_dH01vbXkCbl4TmwfbyQS_0a4_fitbcrUI,10941
47
50
  quasardb/table_cache.py,sha256=t7FFQkms7pFlYDkOhCcLnLS8bWglZjlzX3Qs6gyBG6Q,1559
48
- quasardb/table_reader.hpp,sha256=VpfHxecDa10n3VSoUAoLRaGgrsAvZSuWe_UHZhgUK3E,6882
51
+ quasardb/table_reader.hpp,sha256=UYqpLtdMFr4MKho0A9y6sKb1-KoNLtYPdypl6zOrwm0,6941
49
52
  quasardb/tag.hpp,sha256=gIs8LDa4o0JJBGuSQXsnyVeORax7KH0jHCyt0Zx6JMs,2732
50
53
  quasardb/timestamp.hpp,sha256=f2TLql7D-gTQbJMUdC9QKbHpbnkMPoDi0dHAF2IVrqc,3889
51
54
  quasardb/traits.hpp,sha256=RLSJBeZbFsWRQAsZSm6GbV2a2-5jounsJ_TX0iSvyHI,16383
52
55
  quasardb/ts_iterator.hpp,sha256=faP1HVGYbWubKr98yhkS6gqvyMiKWkl3tgedJfj2u1E,4395
53
56
  quasardb/utils.cpp,sha256=PkuVxrj1cQfeVujA-kefx9-P0B6IJNtYDQzedCAMjKY,634
54
57
  quasardb/utils.hpp,sha256=ZedlY9Ahdphyi8tm2CySYb2k1RJTaDFqDBy3dvg-rJ8,4724
55
- quasardb/writer.cpp,sha256=n1PZg9oxRwKqZu9Lrac-3D2U2xrGbI6oDLTXm69l7zU,19385
58
+ quasardb/writer.cpp,sha256=5jPLFvOcJydiyBSbbtB-SDspKVoXcV9squEOQLuOvp0,19571
56
59
  quasardb/writer.hpp,sha256=08S7HDgdCajNSwro4i0i1lzyvUkHFh6M1vn8TJpAz_A,12933
57
60
  quasardb/CMakeFiles/generate.stamp,sha256=MC9-mgyGPAS3QAZa3gHSQ8dYfXJy_Hn7AChwEoqVWOs,55
58
61
  quasardb/CMakeFiles/generate.stamp.depend,sha256=uY8FV-ceJ2Kk-6JfOnsIesDV7jKoUNfkKHNY2Nf7_E8,117
@@ -108,8 +111,8 @@ quasardb/utils/ostream.hpp,sha256=KYFwqXuZoxuZblHUM-z5xrd74P2Y5zWJqVpaQ9oedAo,39
108
111
  quasardb/utils/permutation.hpp,sha256=BwJzgZmpS4G-oS7249GvnUFj_cmqSAbF2Fzb8wuihLo,1552
109
112
  quasardb/utils/stable_sort.hpp,sha256=luIK9T76mT0NyDxpLxXjTt1eSSKEOY29jRANJNysJCo,489
110
113
  quasardb/utils/unzip_view.hpp,sha256=nn6BSAI_cGsKgBh8WXhAUJ6Zzn3N0AnhtE6ePmhPeQM,2476
111
- quasardb-3.14.1.dev4.dist-info/LICENSE.md,sha256=yqGeNifkwT_AQEPv0TwLxEdD9TgORqUjS01rgzG5EGY,1477
112
- quasardb-3.14.1.dev4.dist-info/METADATA,sha256=wxvkP8SKVdl-tDxH0vpUqOeX7zqXZOUdjFY39aNq-h8,1488
113
- quasardb-3.14.1.dev4.dist-info/WHEEL,sha256=zukbZftcRdNfJ55Q_RYV9JZ3uVyqWKyq-wDJbmszs_U,101
114
- quasardb-3.14.1.dev4.dist-info/top_level.txt,sha256=wlprix4hCywuF1PkgKWYdZeJKq_kgJOqkAvukm_sZQ8,9
115
- quasardb-3.14.1.dev4.dist-info/RECORD,,
114
+ quasardb-3.14.1.dev6.dist-info/LICENSE.md,sha256=yqGeNifkwT_AQEPv0TwLxEdD9TgORqUjS01rgzG5EGY,1477
115
+ quasardb-3.14.1.dev6.dist-info/METADATA,sha256=B2mBS8rYkpdLSo2ngi2GSJNoO8wdGvGCJLagRnkSYkc,1488
116
+ quasardb-3.14.1.dev6.dist-info/WHEEL,sha256=zukbZftcRdNfJ55Q_RYV9JZ3uVyqWKyq-wDJbmszs_U,101
117
+ quasardb-3.14.1.dev6.dist-info/top_level.txt,sha256=wlprix4hCywuF1PkgKWYdZeJKq_kgJOqkAvukm_sZQ8,9
118
+ quasardb-3.14.1.dev6.dist-info/RECORD,,
@@ -1,43 +0,0 @@
1
- function(add_boost_test_executable NAME COMPONENT)
2
- add_executable(${NAME}
3
- ${ARGN}
4
- )
5
-
6
- # set_target_properties(${NAME} PROPERTIES
7
- # DEBUG_POSTFIX ${CMAKE_DEBUG_POSTFIX})
8
-
9
- target_link_libraries(${NAME}
10
- boost_unit_test_framework
11
- )
12
-
13
- if($<CONFIG:SanitizeValgrind>)
14
- add_test(
15
- NAME ${NAME}
16
- COMMAND
17
- valgrind>
18
- $<$<PLATFORM_ID:Darwin>:--dsymutil=yes>
19
- --gen-suppressions=all
20
- ./${NAME}
21
- --log_level=test_suite
22
- --report_level=detailed
23
- --build_info=yes
24
- --detect_memory_leaks=0
25
- )
26
- else()
27
- add_test(
28
- NAME ${NAME}
29
- COMMAND
30
- ${NAME}
31
- --log_level=test_suite
32
- --report_level=detailed
33
- --build_info=yes
34
- --detect_memory_leaks=0
35
- )
36
- endif()
37
-
38
- install(TARGETS ${NAME}
39
- RUNTIME DESTINATION bin COMPONENT ${COMPONENT}
40
- LIBRARY DESTINATION lib COMPONENT ${COMPONENT}
41
- ARCHIVE DESTINATION lib COMPONENT ${COMPONENT}
42
- )
43
- endfunction()