quasardb 3.14.2.dev1__cp312-cp312-macosx_11_0_arm64.whl → 3.14.2.dev4__cp312-cp312-macosx_11_0_arm64.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/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- quasardb/Makefile +20 -20
- quasardb/__init__.py +33 -4
- quasardb/cmake_install.cmake +7 -1
- quasardb/date/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- quasardb/date/CMakeFiles/Export/a52b05f964b070ee926bcad51d3288af/dateTargets.cmake +13 -13
- quasardb/date/Makefile +20 -20
- quasardb/date/cmake_install.cmake +7 -1
- quasardb/date/dateConfigVersion.cmake +9 -2
- quasardb/date/dateTargets.cmake +4 -8
- quasardb/libqdb_api.dylib +0 -0
- quasardb/numpy/__init__.py +58 -10
- quasardb/pandas/__init__.py +58 -102
- quasardb/pybind11/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- quasardb/pybind11/Makefile +20 -20
- quasardb/pybind11/cmake_install.cmake +7 -1
- quasardb/quasardb.cpython-312-darwin.so +0 -0
- quasardb/range-v3/CMakeFiles/CMakeDirectoryInformation.cmake +1 -1
- quasardb/range-v3/CMakeFiles/Export/d94ef200eca10a819b5858b33e808f5b/range-v3-targets.cmake +13 -13
- quasardb/range-v3/CMakeFiles/range.v3.headers.dir/DependInfo.cmake +6 -2
- quasardb/range-v3/CMakeFiles/range.v3.headers.dir/build.make +7 -4
- quasardb/range-v3/Makefile +20 -20
- quasardb/range-v3/cmake_install.cmake +19 -1
- quasardb/range-v3/range-v3-config-version.cmake +9 -2
- quasardb/range-v3/range-v3-config.cmake +4 -8
- {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/METADATA +15 -10
- quasardb-3.14.2.dev4.dist-info/RECORD +45 -0
- {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/WHEEL +1 -1
- quasardb/CMakeLists.txt +0 -510
- quasardb/batch_column.hpp +0 -80
- quasardb/batch_inserter.hpp +0 -248
- quasardb/blob.hpp +0 -150
- quasardb/cluster.cpp +0 -89
- quasardb/cluster.hpp +0 -551
- quasardb/concepts.hpp +0 -278
- quasardb/continuous.cpp +0 -149
- quasardb/continuous.hpp +0 -106
- quasardb/convert/array.hpp +0 -282
- quasardb/convert/point.hpp +0 -330
- quasardb/convert/range.hpp +0 -282
- quasardb/convert/unicode.hpp +0 -598
- quasardb/convert/util.hpp +0 -22
- quasardb/convert/value.hpp +0 -711
- quasardb/convert.hpp +0 -38
- quasardb/detail/qdb_resource.hpp +0 -129
- quasardb/detail/ts_column.hpp +0 -224
- quasardb/direct_blob.hpp +0 -108
- quasardb/direct_handle.hpp +0 -83
- quasardb/direct_integer.hpp +0 -94
- quasardb/dispatch.hpp +0 -157
- quasardb/double.hpp +0 -87
- quasardb/entry.hpp +0 -273
- quasardb/error.hpp +0 -318
- quasardb/handle.cpp +0 -29
- quasardb/handle.hpp +0 -98
- quasardb/integer.hpp +0 -88
- quasardb/logger.cpp +0 -106
- quasardb/logger.hpp +0 -228
- quasardb/masked_array.hpp +0 -651
- quasardb/metrics.cpp +0 -103
- quasardb/metrics.hpp +0 -112
- quasardb/module.cpp +0 -76
- quasardb/module.hpp +0 -24
- quasardb/node.hpp +0 -123
- quasardb/numpy.cpp +0 -6
- quasardb/numpy.hpp +0 -489
- quasardb/object_tracker.hpp +0 -283
- quasardb/options.hpp +0 -244
- quasardb/perf.hpp +0 -336
- quasardb/pytypes.hpp +0 -221
- quasardb/query.cpp +0 -420
- quasardb/query.hpp +0 -92
- quasardb/reader/ts_row.hpp +0 -281
- quasardb/reader/ts_value.hpp +0 -245
- quasardb/remove_cvref.hpp +0 -31
- quasardb/string.hpp +0 -160
- quasardb/table.cpp +0 -289
- quasardb/table.hpp +0 -325
- quasardb/table_reader.hpp +0 -220
- quasardb/tag.hpp +0 -77
- quasardb/timestamp.hpp +0 -97
- quasardb/traits.hpp +0 -619
- quasardb/ts_iterator.hpp +0 -193
- quasardb/utils/blob_deque.hpp +0 -96
- quasardb/utils/ostream.hpp +0 -17
- quasardb/utils/permutation.hpp +0 -50
- quasardb/utils/stable_sort.hpp +0 -25
- quasardb/utils/unzip_view.hpp +0 -89
- quasardb/utils.cpp +0 -28
- quasardb/utils.hpp +0 -174
- quasardb/writer.cpp +0 -534
- quasardb/writer.hpp +0 -396
- quasardb-3.14.2.dev1.dist-info/RECORD +0 -109
- {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/LICENSE.md +0 -0
- {quasardb-3.14.2.dev1.dist-info → quasardb-3.14.2.dev4.dist-info}/top_level.txt +0 -0
quasardb/concepts.hpp
DELETED
|
@@ -1,278 +0,0 @@
|
|
|
1
|
-
#pragma once
|
|
2
|
-
|
|
3
|
-
#include "traits.hpp" // We include traits.hpp only for static_asserts below
|
|
4
|
-
#include <pybind11/numpy.h>
|
|
5
|
-
#include <range/v3/range/concepts.hpp>
|
|
6
|
-
#include <range/v3/range/traits.hpp>
|
|
7
|
-
#include <iterator>
|
|
8
|
-
#include <type_traits>
|
|
9
|
-
|
|
10
|
-
namespace qdb::concepts
|
|
11
|
-
{
|
|
12
|
-
|
|
13
|
-
template <typename R, typename T>
|
|
14
|
-
concept range_t =
|
|
15
|
-
// Ensure we are a range
|
|
16
|
-
ranges::range<R> &&
|
|
17
|
-
|
|
18
|
-
std::is_same_v<ranges::range_value_t<R>, T>;
|
|
19
|
-
|
|
20
|
-
template <typename R, typename T>
|
|
21
|
-
concept input_range_t =
|
|
22
|
-
// Ensure we are an input range
|
|
23
|
-
ranges::input_range<R>
|
|
24
|
-
|
|
25
|
-
// Ensure the range carries the correct type.
|
|
26
|
-
&& range_t<R, T>;
|
|
27
|
-
|
|
28
|
-
template <typename R, typename T>
|
|
29
|
-
concept forward_range_t =
|
|
30
|
-
// Ensure we are a forward range
|
|
31
|
-
ranges::forward_range<R>
|
|
32
|
-
|
|
33
|
-
// And delegate the rest of the checks
|
|
34
|
-
&& input_range_t<R, T>;
|
|
35
|
-
|
|
36
|
-
template <typename R, typename T>
|
|
37
|
-
concept sized_range_t =
|
|
38
|
-
// Ensure we are a sized range
|
|
39
|
-
ranges::sized_range<R>
|
|
40
|
-
|
|
41
|
-
// And delegate the rest of the checks
|
|
42
|
-
&& range_t<R, T>;
|
|
43
|
-
|
|
44
|
-
namespace py = pybind11;
|
|
45
|
-
|
|
46
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
47
|
-
//
|
|
48
|
-
// QuasarDB value types
|
|
49
|
-
//
|
|
50
|
-
// Verifies a "type" of QuasarDB value we're dealing with.
|
|
51
|
-
//
|
|
52
|
-
///////////////////
|
|
53
|
-
|
|
54
|
-
template <typename T>
|
|
55
|
-
concept qdb_point =
|
|
56
|
-
// Check for the boolean flag
|
|
57
|
-
traits::qdb_value<T>::is_qdb_point &&
|
|
58
|
-
|
|
59
|
-
// Every point should have a "primitive" counterpart, for which we do a
|
|
60
|
-
// basic 'is_qdb_primitive' assessment.
|
|
61
|
-
traits::qdb_value<typename traits::qdb_value<T>::primitive_type>::is_qdb_primitive
|
|
62
|
-
|
|
63
|
-
;
|
|
64
|
-
|
|
65
|
-
template <typename T>
|
|
66
|
-
concept qdb_primitive =
|
|
67
|
-
|
|
68
|
-
// Check for the boolean flag
|
|
69
|
-
traits::qdb_value<T>::is_qdb_primitive &&
|
|
70
|
-
|
|
71
|
-
// Every primitive has a null representation
|
|
72
|
-
std::is_same_v<decltype(traits::null_value<T>()), T> &&
|
|
73
|
-
|
|
74
|
-
// Every primitive should be able to check for null validity
|
|
75
|
-
std::is_same_v<decltype(traits::is_null<T>(T{})), bool> &&
|
|
76
|
-
|
|
77
|
-
// And every primitive should have its "point" counterpart, which must
|
|
78
|
-
// be a valid qdb_point.
|
|
79
|
-
qdb_point<typename traits::qdb_value<T>::point_type>;
|
|
80
|
-
|
|
81
|
-
// XXX(leon): could be enabled for debug-only, but we don't build Debug in CI,
|
|
82
|
-
// and these checks are cheap.
|
|
83
|
-
|
|
84
|
-
static_assert(qdb_primitive<qdb_int_t>);
|
|
85
|
-
static_assert(qdb_primitive<double>);
|
|
86
|
-
static_assert(qdb_primitive<qdb_timespec_t>);
|
|
87
|
-
static_assert(qdb_primitive<qdb_string_t>);
|
|
88
|
-
static_assert(qdb_primitive<qdb_blob_t>);
|
|
89
|
-
|
|
90
|
-
static_assert(not qdb_point<qdb_int_t>);
|
|
91
|
-
static_assert(not qdb_point<double>);
|
|
92
|
-
static_assert(not qdb_point<qdb_timespec_t>);
|
|
93
|
-
static_assert(not qdb_point<qdb_string_t>);
|
|
94
|
-
static_assert(not qdb_point<qdb_blob_t>);
|
|
95
|
-
|
|
96
|
-
static_assert(qdb_point<qdb_ts_double_point>);
|
|
97
|
-
static_assert(qdb_point<qdb_ts_int64_point>);
|
|
98
|
-
static_assert(qdb_point<qdb_ts_timestamp_point>);
|
|
99
|
-
static_assert(qdb_point<qdb_ts_blob_point>);
|
|
100
|
-
static_assert(qdb_point<qdb_ts_string_point>);
|
|
101
|
-
|
|
102
|
-
static_assert(not qdb_primitive<qdb_ts_double_point>);
|
|
103
|
-
static_assert(not qdb_primitive<qdb_ts_int64_point>);
|
|
104
|
-
static_assert(not qdb_primitive<qdb_ts_timestamp_point>);
|
|
105
|
-
static_assert(not qdb_primitive<qdb_ts_blob_point>);
|
|
106
|
-
static_assert(not qdb_primitive<qdb_ts_string_point>);
|
|
107
|
-
|
|
108
|
-
////////////////////////////////////////////////////////////////////////////////
|
|
109
|
-
//
|
|
110
|
-
// Numpy / DType concepts
|
|
111
|
-
//
|
|
112
|
-
///////////////////
|
|
113
|
-
|
|
114
|
-
template <typename Dtype>
|
|
115
|
-
concept dtype = std::is_base_of_v<traits::dtype<Dtype::kind>, Dtype>
|
|
116
|
-
|
|
117
|
-
&& std::is_enum_v<decltype(Dtype::kind)>
|
|
118
|
-
|
|
119
|
-
;
|
|
120
|
-
|
|
121
|
-
template <typename Dtype>
|
|
122
|
-
concept fixed_width_dtype = dtype<Dtype>
|
|
123
|
-
|
|
124
|
-
// Check base class
|
|
125
|
-
&& std::is_base_of_v<traits::fixed_width_dtype<Dtype::kind, Dtype::size>, Dtype>;
|
|
126
|
-
|
|
127
|
-
// Test dtypes against their size
|
|
128
|
-
template <typename Dtype, py::ssize_t Size>
|
|
129
|
-
concept dtype_of_width = fixed_width_dtype<Dtype> && Dtype::size == Size;
|
|
130
|
-
|
|
131
|
-
// 64bit dtype
|
|
132
|
-
template <typename Dtype>
|
|
133
|
-
concept dtype64 = dtype_of_width<Dtype, 8>;
|
|
134
|
-
|
|
135
|
-
// 32bit dtype
|
|
136
|
-
template <typename Dtype>
|
|
137
|
-
concept dtype32 = dtype_of_width<Dtype, 4>;
|
|
138
|
-
|
|
139
|
-
// 16bit dtype
|
|
140
|
-
template <typename Dtype>
|
|
141
|
-
concept dtype16 = dtype_of_width<Dtype, 2>;
|
|
142
|
-
|
|
143
|
-
// 8bit dtype
|
|
144
|
-
template <typename Dtype>
|
|
145
|
-
concept dtype8 = dtype_of_width<Dtype, 1>;
|
|
146
|
-
|
|
147
|
-
template <typename Dtype>
|
|
148
|
-
concept datetime64_dtype = fixed_width_dtype<Dtype>
|
|
149
|
-
|
|
150
|
-
// Verify base class is datetime64_dtype
|
|
151
|
-
&& std::is_base_of_v<traits::datetime64_dtype<Dtype::precision>, Dtype>
|
|
152
|
-
|
|
153
|
-
// datetime64 is always a 64bit object
|
|
154
|
-
&& dtype64<Dtype>
|
|
155
|
-
|
|
156
|
-
// It needs to have a precision
|
|
157
|
-
&& std::is_enum_v<decltype(Dtype::precision)>;
|
|
158
|
-
|
|
159
|
-
template <typename Dtype>
|
|
160
|
-
concept variable_width_dtype =
|
|
161
|
-
dtype<Dtype>
|
|
162
|
-
|
|
163
|
-
// Verify base class
|
|
164
|
-
&& std::is_base_of_v<
|
|
165
|
-
traits::variable_width_dtype<Dtype::kind, typename Dtype::stride_type, Dtype::code_point_size>,
|
|
166
|
-
Dtype>
|
|
167
|
-
|
|
168
|
-
// Verify we have a "stride_type", which is the type used to represent a single stride.
|
|
169
|
-
&& Dtype::code_point_size == sizeof(typename Dtype::stride_type::value_type)
|
|
170
|
-
|
|
171
|
-
;
|
|
172
|
-
|
|
173
|
-
template <typename Dtype>
|
|
174
|
-
concept object_dtype = dtype<Dtype>
|
|
175
|
-
|
|
176
|
-
// Objects are always fixed width (64-bit pointers, effectively)
|
|
177
|
-
&& fixed_width_dtype<Dtype>
|
|
178
|
-
|
|
179
|
-
// Verify base class
|
|
180
|
-
&& std::is_base_of_v<traits::object_dtype<typename Dtype::value_type>, Dtype>;
|
|
181
|
-
|
|
182
|
-
// Trivial dtypes are useful for deciding whether you can use fast memcpy-based
|
|
183
|
-
// conversions, e.g. when numpy's int64 has the exact same representation as
|
|
184
|
-
// qdb_int_t.
|
|
185
|
-
template <typename Dtype>
|
|
186
|
-
concept trivial_dtype =
|
|
187
|
-
// Trivial dtypes are *always* fixed width
|
|
188
|
-
fixed_width_dtype<Dtype>
|
|
189
|
-
|
|
190
|
-
// The low-level numpy representation needs to be trivial; e.g. numpy represents
|
|
191
|
-
// something as int32.
|
|
192
|
-
&& std::is_trivial<typename Dtype::value_type>::value
|
|
193
|
-
|
|
194
|
-
// Needs to have a quasardb representation of this type as well (e.g.
|
|
195
|
-
// dtype('int64') mapping to qdb_int_t
|
|
196
|
-
&& std::is_trivial<typename Dtype::qdb_value>::value
|
|
197
|
-
|
|
198
|
-
// Sanity check: the trivial qdb_value needs to be a qdb_primitive -- if this fails,
|
|
199
|
-
// it hints at a misconfigured dtype specification.
|
|
200
|
-
&& qdb_primitive<typename Dtype::qdb_value>
|
|
201
|
-
|
|
202
|
-
// Last but not least (and most important one): both the dtype's low level
|
|
203
|
-
// representation and quasardb's representation need to be equivalent.
|
|
204
|
-
&& std::is_same_v<typename Dtype::value_type, typename Dtype::qdb_value>
|
|
205
|
-
|
|
206
|
-
;
|
|
207
|
-
|
|
208
|
-
template <typename Dtype>
|
|
209
|
-
using delegate_from_type_t = typename Dtype::value_type;
|
|
210
|
-
|
|
211
|
-
template <typename Dtype>
|
|
212
|
-
using delegate_to_type_t = typename Dtype::delegate_type::value_type;
|
|
213
|
-
|
|
214
|
-
template <typename Dtype>
|
|
215
|
-
concept delegate_dtype =
|
|
216
|
-
// Delegates are always dtypes
|
|
217
|
-
dtype<Dtype>
|
|
218
|
-
|
|
219
|
-
// And delegates have a delegate that is also a proper dtype
|
|
220
|
-
&& dtype<typename Dtype::delegate_type>
|
|
221
|
-
|
|
222
|
-
// And conversion between these types should be possible (nothrow could be
|
|
223
|
-
// left away, but that comes with certain performance disadvantages).
|
|
224
|
-
//
|
|
225
|
-
// Note that this only checks for <From, To>, e.g. if int32_t is a delegate
|
|
226
|
-
// to int64_t, it only checks whether int32_t is convertible to int64_t, not the
|
|
227
|
-
// other way around. This is intentional, because the other way around leads to
|
|
228
|
-
// loss of precision, and as such can be argued is *not* convertible, at the
|
|
229
|
-
// very least nothrow_convertible.
|
|
230
|
-
&& std::is_nothrow_convertible_v<delegate_from_type_t<Dtype>, delegate_to_type_t<Dtype>>;
|
|
231
|
-
|
|
232
|
-
// Assertions
|
|
233
|
-
static_assert(dtype<traits::unicode_dtype>);
|
|
234
|
-
|
|
235
|
-
static_assert(variable_width_dtype<traits::unicode_dtype>);
|
|
236
|
-
static_assert(fixed_width_dtype<traits::pyobject_dtype>);
|
|
237
|
-
static_assert(datetime64_dtype<traits::datetime64_ns_dtype>);
|
|
238
|
-
static_assert(not fixed_width_dtype<traits::unicode_dtype>);
|
|
239
|
-
static_assert(not variable_width_dtype<traits::pyobject_dtype>);
|
|
240
|
-
|
|
241
|
-
static_assert(not trivial_dtype<traits::datetime64_ns_dtype>);
|
|
242
|
-
static_assert(not trivial_dtype<traits::pyobject_dtype>);
|
|
243
|
-
static_assert(not trivial_dtype<traits::unicode_dtype>);
|
|
244
|
-
static_assert(not trivial_dtype<traits::bytestring_dtype>);
|
|
245
|
-
static_assert(trivial_dtype<traits::float64_dtype>);
|
|
246
|
-
|
|
247
|
-
static_assert(dtype_of_width<traits::int64_dtype, 8>);
|
|
248
|
-
static_assert(dtype_of_width<traits::int32_dtype, 4>);
|
|
249
|
-
static_assert(dtype_of_width<traits::int16_dtype, 2>);
|
|
250
|
-
|
|
251
|
-
static_assert(dtype64<traits::int64_dtype>);
|
|
252
|
-
static_assert(dtype32<traits::int32_dtype>);
|
|
253
|
-
static_assert(dtype16<traits::int16_dtype>);
|
|
254
|
-
|
|
255
|
-
static_assert(fixed_width_dtype<traits::int64_dtype>);
|
|
256
|
-
static_assert(fixed_width_dtype<traits::int32_dtype>);
|
|
257
|
-
static_assert(fixed_width_dtype<traits::int16_dtype>);
|
|
258
|
-
|
|
259
|
-
static_assert(trivial_dtype<traits::int64_dtype>);
|
|
260
|
-
// Not trivial because they don't have a qdb-native representation, so
|
|
261
|
-
// they're not trivial in the sense of how we should handle them.
|
|
262
|
-
static_assert(not trivial_dtype<traits::int32_dtype>);
|
|
263
|
-
static_assert(not trivial_dtype<traits::int16_dtype>);
|
|
264
|
-
|
|
265
|
-
static_assert(not delegate_dtype<traits::int64_dtype>);
|
|
266
|
-
static_assert(delegate_dtype<traits::int32_dtype>);
|
|
267
|
-
|
|
268
|
-
static_assert(dtype_of_width<traits::float64_dtype, 8>);
|
|
269
|
-
static_assert(dtype_of_width<traits::float32_dtype, 4>);
|
|
270
|
-
|
|
271
|
-
static_assert(trivial_dtype<traits::float64_dtype>);
|
|
272
|
-
// Not trivial because they don't have a qdb-native representation, so
|
|
273
|
-
// they're not trivial in the sense of how we should handle them.
|
|
274
|
-
static_assert(not trivial_dtype<traits::float32_dtype>);
|
|
275
|
-
|
|
276
|
-
static_assert(fixed_width_dtype<traits::float64_dtype>);
|
|
277
|
-
static_assert(fixed_width_dtype<traits::float32_dtype>);
|
|
278
|
-
}; // namespace qdb::concepts
|
quasardb/continuous.cpp
DELETED
|
@@ -1,149 +0,0 @@
|
|
|
1
|
-
#include "continuous.hpp"
|
|
2
|
-
|
|
3
|
-
namespace qdb
|
|
4
|
-
{
|
|
5
|
-
|
|
6
|
-
query_continuous::query_continuous(qdb::handle_ptr h,
|
|
7
|
-
qdb_query_continuous_mode_type_t mode,
|
|
8
|
-
std::chrono::milliseconds pace,
|
|
9
|
-
const std::string & query_string,
|
|
10
|
-
const py::object & bools)
|
|
11
|
-
: _handle{h}
|
|
12
|
-
, _callback{&query_continuous::continuous_callback}
|
|
13
|
-
, _cont_handle{nullptr}
|
|
14
|
-
, _parse_bools{bools}
|
|
15
|
-
, _previous_watermark{0}
|
|
16
|
-
, _watermark{0}
|
|
17
|
-
, _last_error{qdb_e_uninitialized}
|
|
18
|
-
{
|
|
19
|
-
qdb::qdb_throw_if_error(
|
|
20
|
-
*_handle, qdb_query_continuous(*_handle, query_string.c_str(), mode,
|
|
21
|
-
static_cast<unsigned>(pace.count()), _callback, this, &_cont_handle));
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
query_continuous::~query_continuous()
|
|
25
|
-
{
|
|
26
|
-
stop();
|
|
27
|
-
release_results();
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
void query_continuous::release_results()
|
|
31
|
-
{
|
|
32
|
-
if (_results)
|
|
33
|
-
{
|
|
34
|
-
qdb_release(*_handle, _results);
|
|
35
|
-
_results = nullptr;
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
qdb_error_t query_continuous::copy_results(const qdb_query_result_t * res)
|
|
40
|
-
{
|
|
41
|
-
// release whatever results we may be holding before, if we don't have any it does nothing
|
|
42
|
-
release_results();
|
|
43
|
-
if (!res) return qdb_e_ok;
|
|
44
|
-
return qdb_query_copy_results(*_handle, res, &_results);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
int query_continuous::continuous_callback(void * p, qdb_error_t err, const qdb_query_result_t * res)
|
|
48
|
-
{
|
|
49
|
-
auto pthis = static_cast<query_continuous *>(p);
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
std::unique_lock<std::mutex> lock{pthis->_results_mutex};
|
|
53
|
-
|
|
54
|
-
++pthis->_watermark;
|
|
55
|
-
|
|
56
|
-
pthis->_last_error = err;
|
|
57
|
-
if (QDB_FAILURE(pthis->_last_error))
|
|
58
|
-
{
|
|
59
|
-
// signal the error, if processing end, we will get a qdb_e_interrupted which is handled in
|
|
60
|
-
// the results function
|
|
61
|
-
lock.unlock();
|
|
62
|
-
pthis->_results_cond.notify_all();
|
|
63
|
-
return 0;
|
|
64
|
-
}
|
|
65
|
-
|
|
66
|
-
// copy the results using the API convenience function
|
|
67
|
-
// there are two traps to avoid
|
|
68
|
-
// 1. we are within the context of a thread owned by the quasardb C API, calling Python
|
|
69
|
-
// functions could results in deadlocks
|
|
70
|
-
// 2. the results are valid only in the context of the callback, if we want to work on them
|
|
71
|
-
// outside we need to copy them
|
|
72
|
-
pthis->_last_error = pthis->copy_results(res);
|
|
73
|
-
if (QDB_FAILURE(pthis->_last_error))
|
|
74
|
-
{
|
|
75
|
-
pthis->release_results();
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
pthis->_results_cond.notify_all();
|
|
80
|
-
|
|
81
|
-
return 0;
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
dict_query_result_t query_continuous::unsafe_results()
|
|
85
|
-
{
|
|
86
|
-
// when we return from the condition variable we own the mutex
|
|
87
|
-
_previous_watermark.store(_watermark.load());
|
|
88
|
-
|
|
89
|
-
if (_last_error == qdb_e_interrupted) throw py::stop_iteration{};
|
|
90
|
-
|
|
91
|
-
// throw an error, user may decide to resume iteration
|
|
92
|
-
qdb::qdb_throw_if_error(*_handle, _last_error);
|
|
93
|
-
|
|
94
|
-
// safe and quick to call if _results is nullptr
|
|
95
|
-
auto res = convert_query_results(_results, _parse_bools);
|
|
96
|
-
|
|
97
|
-
release_results();
|
|
98
|
-
|
|
99
|
-
return res;
|
|
100
|
-
}
|
|
101
|
-
|
|
102
|
-
dict_query_result_t query_continuous::results()
|
|
103
|
-
{
|
|
104
|
-
std::unique_lock<std::mutex> lock{_results_mutex};
|
|
105
|
-
|
|
106
|
-
// you need an additional mechanism to check if you need to do something with the results
|
|
107
|
-
// because condition variables can have spurious calls
|
|
108
|
-
while (_watermark == _previous_watermark)
|
|
109
|
-
{
|
|
110
|
-
// entering the condition variables releases the mutex
|
|
111
|
-
// the callback can update the values when needed
|
|
112
|
-
// every second we are going to check if the user didn't do CTRL-C
|
|
113
|
-
if (_results_cond.wait_for(lock, std::chrono::seconds{1}) == std::cv_status::timeout)
|
|
114
|
-
{
|
|
115
|
-
// if we don't do this, it will be impossible to interrupt the Python program while we wait
|
|
116
|
-
// for results
|
|
117
|
-
if (PyErr_CheckSignals() != 0) throw py::error_already_set();
|
|
118
|
-
}
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
return unsafe_results();
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
// the difference with the call above is that we're returning immediately if there's no change
|
|
125
|
-
dict_query_result_t query_continuous::probe_results()
|
|
126
|
-
{
|
|
127
|
-
std::unique_lock<std::mutex> lock{_results_mutex};
|
|
128
|
-
|
|
129
|
-
// check if there's a new value
|
|
130
|
-
if (_watermark == _previous_watermark)
|
|
131
|
-
{
|
|
132
|
-
// nope return empty, don't wait, don't acquire the condition variable
|
|
133
|
-
return dict_query_result_t{};
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// yes, return the value
|
|
137
|
-
return unsafe_results();
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
void query_continuous::stop()
|
|
141
|
-
{
|
|
142
|
-
if (_handle && _cont_handle)
|
|
143
|
-
{
|
|
144
|
-
qdb_release(*_handle, _cont_handle);
|
|
145
|
-
_cont_handle = nullptr;
|
|
146
|
-
}
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
} // namespace qdb
|
quasardb/continuous.hpp
DELETED
|
@@ -1,106 +0,0 @@
|
|
|
1
|
-
/*
|
|
2
|
-
*
|
|
3
|
-
* Official Python API
|
|
4
|
-
*
|
|
5
|
-
* Copyright (c) 2009-2024, 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 "query.hpp"
|
|
34
|
-
#include <atomic>
|
|
35
|
-
#include <condition_variable>
|
|
36
|
-
#include <memory>
|
|
37
|
-
|
|
38
|
-
namespace py = pybind11;
|
|
39
|
-
|
|
40
|
-
namespace qdb
|
|
41
|
-
{
|
|
42
|
-
|
|
43
|
-
class query_continuous : public std::enable_shared_from_this<query_continuous>
|
|
44
|
-
{
|
|
45
|
-
public:
|
|
46
|
-
query_continuous(qdb::handle_ptr h,
|
|
47
|
-
qdb_query_continuous_mode_type_t mode,
|
|
48
|
-
std::chrono::milliseconds pace,
|
|
49
|
-
const std::string & query_string,
|
|
50
|
-
const py::object & bools);
|
|
51
|
-
query_continuous(const qdb::query_continuous & /*other*/) = delete;
|
|
52
|
-
~query_continuous();
|
|
53
|
-
|
|
54
|
-
private:
|
|
55
|
-
void release_results();
|
|
56
|
-
qdb_error_t copy_results(const qdb_query_result_t * res);
|
|
57
|
-
static int continuous_callback(void * p, qdb_error_t err, const qdb_query_result_t * res);
|
|
58
|
-
|
|
59
|
-
private:
|
|
60
|
-
dict_query_result_t unsafe_results();
|
|
61
|
-
|
|
62
|
-
public:
|
|
63
|
-
// returns the results (blocking)
|
|
64
|
-
dict_query_result_t results();
|
|
65
|
-
// returns the results (non-blocking), empty if no results available yet
|
|
66
|
-
// needed to be able to interface with other framework that can't wait for results to be available
|
|
67
|
-
// in that case you would poll probe_results(), the cost is low because it doesn't result in a
|
|
68
|
-
// remote call just acquiring the mutex and see if results have been updated
|
|
69
|
-
dict_query_result_t probe_results();
|
|
70
|
-
void stop();
|
|
71
|
-
|
|
72
|
-
private:
|
|
73
|
-
qdb::handle_ptr _handle;
|
|
74
|
-
qdb_query_cont_callback_t _callback;
|
|
75
|
-
qdb_query_cont_handle_t _cont_handle;
|
|
76
|
-
|
|
77
|
-
py::object _parse_bools;
|
|
78
|
-
|
|
79
|
-
mutable std::condition_variable _results_cond;
|
|
80
|
-
mutable std::mutex _results_mutex;
|
|
81
|
-
std::atomic<size_t> _previous_watermark;
|
|
82
|
-
std::atomic<size_t> _watermark;
|
|
83
|
-
qdb_error_t _last_error;
|
|
84
|
-
|
|
85
|
-
qdb_query_result_t * _results;
|
|
86
|
-
};
|
|
87
|
-
|
|
88
|
-
template <typename Module>
|
|
89
|
-
static inline void register_continuous(Module & m)
|
|
90
|
-
{
|
|
91
|
-
namespace py = pybind11;
|
|
92
|
-
|
|
93
|
-
py::class_<qdb::query_continuous, std::shared_ptr<qdb::query_continuous>>{m, "QueryContinuous"} //
|
|
94
|
-
.def(py::init<qdb::handle_ptr, qdb_query_continuous_mode_type_t, std::chrono::milliseconds,
|
|
95
|
-
const std::string &,
|
|
96
|
-
const py::object &>()) //
|
|
97
|
-
.def("results", &qdb::query_continuous::results) //
|
|
98
|
-
.def("probe_results", &qdb::query_continuous::probe_results) //
|
|
99
|
-
.def("stop", &qdb::query_continuous::stop) //
|
|
100
|
-
|
|
101
|
-
// required interface to use query_continuous as an iterator
|
|
102
|
-
.def("__iter__", [](const std::shared_ptr<qdb::query_continuous> & cont) { return cont; }) //
|
|
103
|
-
.def("__next__", &qdb::query_continuous::results); //
|
|
104
|
-
}
|
|
105
|
-
|
|
106
|
-
} // namespace qdb
|