-
Notifications
You must be signed in to change notification settings - Fork 33
Expand file tree
/
Copy pathQLTypes.h
More file actions
262 lines (211 loc) · 7.39 KB
/
QLTypes.h
File metadata and controls
262 lines (211 loc) · 7.39 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
/*
* QLTypes.h
*
* This source file is part of the FoundationDB open source project
*
* Copyright 2013-2018 Apple Inc. and the FoundationDB project authors
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
#ifndef _QL_TYPES_H_
#define _QL_TYPES_H_
#pragma once
#include "bson.h"
#include "flow/Arena.h"
#include "flow/flow.h"
#include "oid.h"
#include <stdint.h>
#ifdef _MSC_VER
#include "FPUUtils.h"
#include <type_traits>
#pragma pack(push)
#pragma pack(2)
typedef struct LongDouble final {
unsigned char _data[10];
public:
LongDouble() { memset(_data, 0, sizeof(_data)); }
template <typename T>
LongDouble(T value) {
if (std::is_floating_point<T>()) {
double max_var = (double)value;
convert64dto80((unsigned char*)&max_var, _data);
} else {
long long max_var = (long long)value;
convert64ito80((unsigned char*)&max_var, _data);
}
}
template <typename T>
operator T() {
if (std::is_floating_point<T>()) {
double value = 0;
convert80to64d(_data, (unsigned char*)&value);
return T(value);
}
long long value = 0;
convert80to64i(_data, (unsigned char*)&value);
return T(value);
}
LongDouble& operator+=(const LongDouble& value) {
add80to80(_data, value._data, _data);
return *this;
}
LongDouble& operator*=(const LongDouble& value) {
multiply80to80(_data, value._data, _data);
return *this;
}
LongDouble operator+(const LongDouble& value) const { return LongDouble(*this) += value; }
LongDouble operator*(const LongDouble& value) const { return LongDouble(*this) *= value; }
} LongDouble;
#pragma pack(pop)
#else
typedef long double LongDouble;
#endif
// #17: Added decode_bytes and decode_key_part to update explain output with user readable keys
/* In case query has '$gt' or '$lt' operator then field elements are represent in range,
* like '//x01e < x < 1' (for '$lt') and '1 < x < //x01f' (for '$gt'), where //x01e represent.
* To determine those bytes, enable a check for '0x1f' in 'DVTypeCode' as SPL_CHAR,
* for '0x1e' in 'DVTypeCode' already enabled as 'NUMBER'.
*/
enum class DVTypeCode : uint8_t {
MIN_KEY = 0,
NULL_ELEMENT = 20,
NUMBER = 30,
SPL_CHAR = 31, // ASCII value for SPL_CHAR = 31 is '\0x1f'
STRING = 40,
OBJECT = 50,
PACKED_OBJECT = 51,
ARRAY = 60,
PACKED_ARRAY = 61,
BYTES = 70,
OID = 80,
BOOL = 90,
DATE = 100,
REGEX = 110,
MAX_KEY = 255
};
struct DataValue {
DataValue() = default;
DataValue(const uint8_t* bytes, int len, DVTypeCode code);
DataValue(const char* str, DVTypeCode code);
DataValue(const char* str, int len, DVTypeCode code);
DataValue(StringRef str, DVTypeCode code);
explicit DataValue(std::string str);
explicit DataValue(bool p);
explicit DataValue(int n);
explicit DataValue(long long n);
explicit DataValue(double d);
explicit DataValue(bson::OID id);
explicit DataValue(bson::Date_t date);
explicit DataValue(bson::BSONElement el);
explicit DataValue(bson::BSONArray arr);
explicit DataValue(bson::BSONObj obj);
int compare(DataValue const& other) const;
Standalone<StringRef> encode_key_part() const;
StringRef encode_value() const;
static DataValue decode_key_part(StringRef nonNumKey);
static DataValue decode_key_part(StringRef numKey, bson::BSONType numCode);
static DataValue decode_value(StringRef val);
static DataValue arrayOfLength(uint32_t length);
static DataValue subObject();
static DataValue nullValue();
static DataValue firstOfType(const DataValue& other);
static DataValue firstOfnextType(const DataValue& other);
bson::BSONType getBSONType() const;
DVTypeCode getSortType() const;
bool getBool() const;
bson::Date_t getDate() const;
bson::OID getId() const;
std::string getString() const;
StringRef getBinaryData() const;
int32_t getInt() const;
int64_t getLong() const;
double getDouble() const;
int getArraysize() const;
bson::BSONElement getRegExObject() const;
bson::BSONObj getPackedObject() const;
bson::BSONArray getPackedArray() const;
bson::BSONObj wrap(const char* fieldname) const;
std::string toString() const;
bool isSimpleType() const;
inline bool operator==(const DataValue& rhs) const { return compare(rhs) == 0; }
inline bool operator!=(const DataValue& rhs) const { return !operator==(rhs); }
inline bool operator<(const DataValue& rhs) const { return compare(rhs) < 0; }
inline bool operator>(const DataValue& rhs) const { return compare(rhs) > 0; }
inline bool operator<=(const DataValue& rhs) const { return !operator>(rhs); }
inline bool operator>=(const DataValue& rhs) const { return !operator<(rhs); }
private:
explicit DataValue(StringRef rawValue);
Standalone<StringRef> representation;
void init(const uint8_t* bytes, int len, DVTypeCode code);
void init_bindata(bson::BSONElement elem);
void init_int(int n);
void init_double(double d);
void init_long(long long n);
void init_bool(bool b);
void init_date(bson::Date_t date);
void init_id(bson::OID id);
void init_array(uint32_t length);
void init_bare_typecode(DVTypeCode type);
void init_packed_array(const char* arrData, int arrSize);
void init_packed_object(const char* objData, int objSize);
std::string escape_nulls() const;
};
struct DataKey {
DataKey() = default;
static DataKey decode_bytes(Standalone<StringRef> bytes);
static StringRef decode_item(StringRef bytes, int itemNumber);
static StringRef decode_item_rev(StringRef bytes, int itemNumber, int* ptotalItems = nullptr);
DataKey& append(StringRef el) {
offsets.push_back(representation.length());
representation += el.toString();
return *this;
}
DataKey operator+(const DataKey& rhs) {
DataKey ret(*this);
auto offset = ret.representation.size();
for (auto i : rhs.offsets) {
ret.offsets.push_back((i == -1) ? i : i + offset);
}
ret.representation += rhs.representation;
return ret;
}
DataKey(const DataKey&) = default;
DataKey(std::string const& repr, std::vector<int> offsets) : representation(repr), offsets(offsets) {}
DataKey(DataKey&& other) {
representation = std::move(other.representation);
offsets = std::move(other.offsets);
}
DataKey& operator=(DataKey&& other) {
representation = std::move(other.representation);
offsets = std::move(other.offsets);
return *this;
}
// returns the ith item (0-indexed) of this DataKey
Standalone<StringRef> operator[](int i) const;
// returns the first i items (1-indexed)
Standalone<StringRef> prefix(int i) const;
// returns a DataKey holding the first i items (1-indexed) of this one in its own memory
DataKey keyPrefix(int i) const;
// returns the number of items (1-indexed) in this DataKey
int size() const { return offsets.size(); }
int byteSize() const { return representation.size(); }
bool startsWith(DataKey const& other) const;
Standalone<StringRef> bytes(int offset = 0) const { // FIXME: return stringref
return Standalone<StringRef>(representation.substr(offsets[offset]));
}
const std::string& toString() const { return representation; }
private:
std::string representation;
std::vector<int> offsets;
};
#endif /* _QL_TYPES_H_ */