gqlite 1.5.0 → 1.7.0
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.
- checksums.yaml +4 -4
- data/ext/Cargo.toml +12 -6
- data/ext/db-index/Cargo.toml +29 -0
- data/ext/db-index/src/hnsw/error.rs +66 -0
- data/ext/db-index/src/hnsw/graph_store.rs +272 -0
- data/ext/db-index/src/hnsw/id.rs +36 -0
- data/ext/db-index/src/hnsw/implementation.rs +1517 -0
- data/ext/db-index/src/hnsw/kernels.rs +1228 -0
- data/ext/db-index/src/hnsw/metric.rs +244 -0
- data/ext/db-index/src/hnsw/scalar.rs +72 -0
- data/ext/db-index/src/hnsw/simple_store.rs +140 -0
- data/ext/db-index/src/hnsw/store.rs +472 -0
- data/ext/db-index/src/hnsw/vector.rs +105 -0
- data/ext/db-index/src/hnsw/vectors.rs +568 -0
- data/ext/db-index/src/hnsw.rs +42 -0
- data/ext/db-index/src/lib.rs +3 -0
- data/ext/gqlitedb/Cargo.toml +19 -8
- data/ext/gqlitedb/benches/common/pokec.rs +62 -2
- data/ext/gqlitedb/benches/pokec_divan.rs +66 -2
- data/ext/gqlitedb/benches/pokec_iai.rs +60 -3
- data/ext/gqlitedb/release.toml +2 -2
- data/ext/gqlitedb/src/aggregators/arithmetic.rs +3 -1
- data/ext/gqlitedb/src/aggregators/containers.rs +1 -1
- data/ext/gqlitedb/src/aggregators/stats.rs +21 -12
- data/ext/gqlitedb/src/capi.rs +20 -24
- data/ext/gqlitedb/src/compiler/expression_analyser.rs +28 -20
- data/ext/gqlitedb/src/compiler/variables_manager.rs +104 -38
- data/ext/gqlitedb/src/compiler.rs +506 -227
- data/ext/gqlitedb/src/connection.rs +151 -11
- data/ext/gqlitedb/src/consts.rs +1 -2
- data/ext/gqlitedb/src/error.rs +123 -61
- data/ext/gqlitedb/src/functions/common.rs +64 -0
- data/ext/gqlitedb/src/functions/containers.rs +2 -46
- data/ext/gqlitedb/src/functions/edge.rs +1 -1
- data/ext/gqlitedb/src/functions/math.rs +87 -15
- data/ext/gqlitedb/src/functions/node.rs +1 -1
- data/ext/gqlitedb/src/functions/path.rs +48 -11
- data/ext/gqlitedb/src/functions/scalar.rs +47 -4
- data/ext/gqlitedb/src/functions/string.rs +123 -1
- data/ext/gqlitedb/src/functions/value.rs +1 -1
- data/ext/gqlitedb/src/functions.rs +165 -28
- data/ext/gqlitedb/src/graph.rs +1 -9
- data/ext/gqlitedb/src/interpreter/evaluators.rs +968 -130
- data/ext/gqlitedb/src/interpreter/instructions.rs +39 -2
- data/ext/gqlitedb/src/lib.rs +5 -4
- data/ext/gqlitedb/src/parser/gql.pest +1 -1
- data/ext/gqlitedb/src/planner.rs +329 -0
- data/ext/gqlitedb/src/prelude.rs +3 -3
- data/ext/gqlitedb/src/store/pgrx.rs +1 -1
- data/ext/gqlitedb/src/store/postgres.rs +742 -16
- data/ext/gqlitedb/src/store/redb/hnsw_store.rs +702 -0
- data/ext/gqlitedb/src/store/redb/index.rs +274 -0
- data/ext/gqlitedb/src/store/redb.rs +1268 -113
- data/ext/gqlitedb/src/store/sqlbase/sqlmetadata.rs +28 -0
- data/ext/gqlitedb/src/store/sqlbase/sqlstore.rs +103 -0
- data/ext/gqlitedb/src/store/sqlbase.rs +146 -16
- data/ext/gqlitedb/src/store/sqlite.rs +576 -14
- data/ext/gqlitedb/src/store/vector_extract.rs +56 -0
- data/ext/gqlitedb/src/store.rs +140 -29
- data/ext/gqlitedb/src/tests/compiler.rs +207 -10
- data/ext/gqlitedb/src/tests/connection/postgres.rs +38 -3
- data/ext/gqlitedb/src/tests/connection/redb.rs +23 -0
- data/ext/gqlitedb/src/tests/connection/sqlite.rs +31 -0
- data/ext/gqlitedb/src/tests/connection.rs +61 -1
- data/ext/gqlitedb/src/tests/evaluators.rs +162 -7
- data/ext/gqlitedb/src/tests/parser.rs +54 -23
- data/ext/gqlitedb/src/tests/planner.rs +511 -0
- data/ext/gqlitedb/src/tests/store/postgres.rs +7 -0
- data/ext/gqlitedb/src/tests/store/redb.rs +8 -0
- data/ext/gqlitedb/src/tests/store/sqlite.rs +8 -0
- data/ext/gqlitedb/src/tests/store/vector_index/postgres.rs +182 -0
- data/ext/gqlitedb/src/tests/store/vector_index/redb.rs +386 -0
- data/ext/gqlitedb/src/tests/store/vector_index/sqlite.rs +166 -0
- data/ext/gqlitedb/src/tests/store/vector_index.rs +2313 -0
- data/ext/gqlitedb/src/tests/store.rs +78 -14
- data/ext/gqlitedb/src/tests/templates/ast.rs +92 -16
- data/ext/gqlitedb/src/tests/templates/programs.rs +14 -7
- data/ext/gqlitedb/src/tests.rs +15 -9
- data/ext/gqlitedb/src/utils.rs +6 -1
- data/ext/gqlitedb/src/value/compare.rs +61 -3
- data/ext/gqlitedb/src/value.rs +136 -7
- data/ext/gqlitedb/templates/sql/postgres/metadata_delete.sql +1 -0
- data/ext/gqlitedb/templates/sql/postgres/node_select.sql +1 -1
- data/ext/gqlitedb/templates/sql/sqlite/metadata_delete.sql +1 -0
- data/ext/gqliterb/src/lib.rs +53 -8
- data/ext/gqlparser/Cargo.toml +25 -0
- data/ext/gqlparser/README.MD +9 -0
- data/ext/gqlparser/benches/pokec_divan.rs +34 -0
- data/ext/gqlparser/src/common.rs +69 -0
- data/ext/gqlparser/src/gqls/ast.rs +69 -0
- data/ext/gqlparser/src/gqls/constraint.rs +79 -0
- data/ext/gqlparser/src/gqls/error.rs +22 -0
- data/ext/gqlparser/src/gqls/parser.rs +813 -0
- data/ext/gqlparser/src/gqls/prelude.rs +8 -0
- data/ext/gqlparser/src/gqls/properties.rs +115 -0
- data/ext/gqlparser/src/gqls/resolve.rs +207 -0
- data/ext/gqlparser/src/gqls.rs +265 -0
- data/ext/gqlparser/src/lib.rs +7 -0
- data/ext/gqlparser/src/oc/ast.rs +680 -0
- data/ext/gqlparser/src/oc/error.rs +172 -0
- data/ext/gqlparser/src/oc/lexer.rs +429 -0
- data/ext/gqlparser/src/oc/parser/tests.rs +2284 -0
- data/ext/gqlparser/src/oc/parser.rs +2005 -0
- data/ext/gqlparser/src/oc.rs +33 -0
- data/ext/gqlparser/src/prelude.rs +3 -0
- data/ext/graphcore/Cargo.toml +1 -0
- data/ext/graphcore/src/error.rs +26 -0
- data/ext/graphcore/src/graph.rs +177 -51
- data/ext/graphcore/src/lib.rs +4 -2
- data/ext/graphcore/src/open_cypher.rs +12 -0
- data/ext/graphcore/src/table.rs +50 -2
- data/ext/graphcore/src/timestamp.rs +127 -104
- data/ext/graphcore/src/value/tensor.rs +739 -0
- data/ext/graphcore/src/value/value_map.rs +1 -1
- data/ext/graphcore/src/value.rs +343 -19
- metadata +93 -28
- data/ext/gqlitedb/src/parser/ast.rs +0 -604
- data/ext/gqlitedb/src/parser/parser_impl.rs +0 -1213
- data/ext/gqlitedb/src/parser.rs +0 -4
data/ext/graphcore/src/value.rs
CHANGED
|
@@ -5,11 +5,13 @@ use std::{
|
|
|
5
5
|
ops::{Add, Div, Mul, Neg, Rem, Sub},
|
|
6
6
|
};
|
|
7
7
|
|
|
8
|
+
mod tensor;
|
|
8
9
|
mod value_map;
|
|
9
10
|
|
|
10
|
-
pub(crate) use crate::prelude::*;
|
|
11
11
|
use crate::TimeStamp;
|
|
12
|
+
pub(crate) use crate::prelude::*;
|
|
12
13
|
|
|
14
|
+
pub use tensor::{DType, Tensor};
|
|
13
15
|
pub use value_map::ValueMap;
|
|
14
16
|
|
|
15
17
|
/// Represent a value in a properties for a Node or an Edge.
|
|
@@ -38,14 +40,18 @@ pub enum Value
|
|
|
38
40
|
TimeStamp(timestamp::TimeStamp),
|
|
39
41
|
/// Array of values.
|
|
40
42
|
Array(Vec<Value>),
|
|
43
|
+
/// Dense tensor embedding (1D array of floats)
|
|
44
|
+
Tensor(Tensor),
|
|
41
45
|
/// Unordered map of values.
|
|
42
46
|
Map(ValueMap),
|
|
43
47
|
/// A node in the graph.
|
|
44
48
|
Node(graph::Node),
|
|
45
49
|
/// An edge in the graph.
|
|
46
50
|
Edge(graph::Edge),
|
|
51
|
+
/// A single path in the graph.
|
|
52
|
+
SinglePath(Box<graph::SinglePath>),
|
|
47
53
|
/// A path in the graph.
|
|
48
|
-
Path(graph::
|
|
54
|
+
Path(Box<graph::Path>),
|
|
49
55
|
}
|
|
50
56
|
|
|
51
57
|
impl Value
|
|
@@ -75,6 +81,42 @@ impl Value
|
|
|
75
81
|
o => o,
|
|
76
82
|
}
|
|
77
83
|
}
|
|
84
|
+
|
|
85
|
+
/// Optimize a value that has been deserialized from a storage layer.
|
|
86
|
+
/// In particular, convert numeric arrays into native Tensor values.
|
|
87
|
+
pub fn optimize(self) -> Self
|
|
88
|
+
{
|
|
89
|
+
match self
|
|
90
|
+
{
|
|
91
|
+
Value::Array(arr) =>
|
|
92
|
+
{
|
|
93
|
+
let mut out = Vec::with_capacity(arr.len());
|
|
94
|
+
let mut all_numeric = true;
|
|
95
|
+
for v in arr.iter()
|
|
96
|
+
{
|
|
97
|
+
match v
|
|
98
|
+
{
|
|
99
|
+
Value::Float(f) => out.push(*f as f32),
|
|
100
|
+
Value::Integer(i) => out.push(*i as f32),
|
|
101
|
+
_ =>
|
|
102
|
+
{
|
|
103
|
+
all_numeric = false;
|
|
104
|
+
break;
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
if all_numeric
|
|
109
|
+
{
|
|
110
|
+
Value::Tensor(Tensor::from_f32_slice(&out))
|
|
111
|
+
}
|
|
112
|
+
else
|
|
113
|
+
{
|
|
114
|
+
Value::Array(arr.into_iter().map(|v| v.optimize()).collect())
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
other => other,
|
|
118
|
+
}
|
|
119
|
+
}
|
|
78
120
|
}
|
|
79
121
|
impl Hash for Value
|
|
80
122
|
{
|
|
@@ -102,9 +144,25 @@ impl Hash for Value
|
|
|
102
144
|
Value::String(s) => s.hash(state),
|
|
103
145
|
Value::TimeStamp(ts) => ts.hash(state),
|
|
104
146
|
Value::Array(a) => a.hash(state),
|
|
147
|
+
Value::Tensor(t) =>
|
|
148
|
+
{
|
|
149
|
+
for fl in t.iter()
|
|
150
|
+
{
|
|
151
|
+
let bits = if fl.is_nan()
|
|
152
|
+
{
|
|
153
|
+
0x7fc00000u32
|
|
154
|
+
}
|
|
155
|
+
else
|
|
156
|
+
{
|
|
157
|
+
fl.to_bits()
|
|
158
|
+
};
|
|
159
|
+
bits.hash(state);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
105
162
|
Value::Map(m) => m.hash(state),
|
|
106
163
|
Value::Node(n) => n.hash(state),
|
|
107
164
|
Value::Edge(e) => e.hash(state),
|
|
165
|
+
Value::SinglePath(p) => p.hash(state),
|
|
108
166
|
Value::Path(p) => p.hash(state),
|
|
109
167
|
}
|
|
110
168
|
}
|
|
@@ -123,8 +181,68 @@ impl Add for Value
|
|
|
123
181
|
| Value::Edge(..)
|
|
124
182
|
| Value::Map(..)
|
|
125
183
|
| Value::TimeStamp(..)
|
|
184
|
+
| Value::SinglePath(..)
|
|
126
185
|
| Value::Path(..) => Err(Error::InvalidBinaryOperands),
|
|
127
186
|
Value::Null => Ok(Value::Null),
|
|
187
|
+
Self::Tensor(lhs) => match rhs
|
|
188
|
+
{
|
|
189
|
+
Self::Tensor(rhs_v) =>
|
|
190
|
+
{
|
|
191
|
+
if lhs.len() != rhs_v.len()
|
|
192
|
+
{
|
|
193
|
+
Err(Error::InvalidBinaryOperands)
|
|
194
|
+
}
|
|
195
|
+
else
|
|
196
|
+
{
|
|
197
|
+
let res = lhs
|
|
198
|
+
.iter()
|
|
199
|
+
.zip(rhs_v.iter())
|
|
200
|
+
.map(|(a, b)| a + b)
|
|
201
|
+
.collect::<Vec<f32>>();
|
|
202
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
Self::Float(rhs_f) =>
|
|
206
|
+
{
|
|
207
|
+
let scalar = rhs_f as f32;
|
|
208
|
+
let res = lhs.iter().map(|a| a + scalar).collect::<Vec<f32>>();
|
|
209
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
210
|
+
}
|
|
211
|
+
Self::Integer(rhs_i) =>
|
|
212
|
+
{
|
|
213
|
+
let scalar = rhs_i as f32;
|
|
214
|
+
let res = lhs.iter().map(|a| a + scalar).collect::<Vec<f32>>();
|
|
215
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
216
|
+
}
|
|
217
|
+
Self::Array(arr) =>
|
|
218
|
+
{
|
|
219
|
+
let mut rhs_vec = Vec::with_capacity(arr.len());
|
|
220
|
+
for v in arr.iter()
|
|
221
|
+
{
|
|
222
|
+
match v
|
|
223
|
+
{
|
|
224
|
+
Value::Float(f) => rhs_vec.push(*f as f32),
|
|
225
|
+
Value::Integer(i) => rhs_vec.push(*i as f32),
|
|
226
|
+
_ => return Err(Error::InvalidBinaryOperands),
|
|
227
|
+
}
|
|
228
|
+
}
|
|
229
|
+
if rhs_vec.len() != lhs.len()
|
|
230
|
+
{
|
|
231
|
+
Err(Error::InvalidBinaryOperands)
|
|
232
|
+
}
|
|
233
|
+
else
|
|
234
|
+
{
|
|
235
|
+
let res = lhs
|
|
236
|
+
.iter()
|
|
237
|
+
.zip(rhs_vec.iter())
|
|
238
|
+
.map(|(a, b)| a + b)
|
|
239
|
+
.collect::<Vec<f32>>();
|
|
240
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
Self::Null => Ok(Self::Null),
|
|
244
|
+
_ => Err(Error::InvalidBinaryOperands),
|
|
245
|
+
},
|
|
128
246
|
Self::Array(lhs) => match rhs
|
|
129
247
|
{
|
|
130
248
|
Self::Array(rhs) =>
|
|
@@ -144,6 +262,12 @@ impl Add for Value
|
|
|
144
262
|
{
|
|
145
263
|
Self::Float(rhs) => Ok((lhs + rhs).into()),
|
|
146
264
|
Self::Integer(rhs) => Ok((lhs + rhs as f64).into()),
|
|
265
|
+
Self::Tensor(rhs_v) =>
|
|
266
|
+
{
|
|
267
|
+
let scalar = lhs as f32;
|
|
268
|
+
let res = rhs_v.iter().map(|v| scalar + *v).collect::<Vec<f32>>();
|
|
269
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
270
|
+
}
|
|
147
271
|
Self::Null => Ok(Self::Null),
|
|
148
272
|
_ => Err(Error::InvalidBinaryOperands),
|
|
149
273
|
},
|
|
@@ -151,6 +275,12 @@ impl Add for Value
|
|
|
151
275
|
{
|
|
152
276
|
Self::Float(rhs) => Ok((lhs as f64 + rhs).into()),
|
|
153
277
|
Self::Integer(rhs) => Ok((lhs + rhs).into()),
|
|
278
|
+
Self::Tensor(rhs_v) =>
|
|
279
|
+
{
|
|
280
|
+
let scalar = lhs as f32;
|
|
281
|
+
let res = rhs_v.iter().map(|v| scalar + *v).collect::<Vec<f32>>();
|
|
282
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
283
|
+
}
|
|
154
284
|
Self::Null => Ok(Self::Null),
|
|
155
285
|
_ => Err(Error::InvalidBinaryOperands),
|
|
156
286
|
},
|
|
@@ -181,19 +311,72 @@ macro_rules! impl_mdsr {
|
|
|
181
311
|
| Value::Edge(..)
|
|
182
312
|
| Value::Array(..)
|
|
183
313
|
| Value::Map(..)
|
|
314
|
+
| Value::SinglePath(..)
|
|
184
315
|
| Value::Path(..) => Err(Error::InvalidBinaryOperands.into()),
|
|
185
316
|
Value::Null => Ok(Value::Null),
|
|
186
317
|
Self::Float(lhs) => match rhs
|
|
187
318
|
{
|
|
188
319
|
Self::Float(rhs) => Ok(lhs.$op(rhs).into()),
|
|
189
320
|
Self::Integer(rhs) => Ok(lhs.$op(rhs as f64).into()),
|
|
321
|
+
Self::Tensor(rhs_v) =>
|
|
322
|
+
{
|
|
323
|
+
let scalar = lhs as f32;
|
|
324
|
+
let res = rhs_v.iter().map(|v| scalar.$op(*v)).collect::<Vec<f32>>();
|
|
325
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
326
|
+
}
|
|
190
327
|
Self::Null => Ok(Self::Null),
|
|
191
328
|
_ => Err(Error::InvalidBinaryOperands.into()),
|
|
192
329
|
},
|
|
330
|
+
|
|
193
331
|
Self::Integer(lhs) => match rhs
|
|
194
332
|
{
|
|
195
333
|
Self::Float(rhs) => Ok((lhs as f64).$op(rhs).into()),
|
|
196
334
|
Self::Integer(rhs) => Ok(lhs.$op(rhs).into()),
|
|
335
|
+
Self::Tensor(rhs_v) =>
|
|
336
|
+
{
|
|
337
|
+
let scalar = lhs as f32;
|
|
338
|
+
let res = rhs_v.iter().map(|v| scalar.$op(*v)).collect::<Vec<f32>>();
|
|
339
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
340
|
+
}
|
|
341
|
+
Self::Null => Ok(Self::Null),
|
|
342
|
+
_ => Err(Error::InvalidBinaryOperands.into()),
|
|
343
|
+
},
|
|
344
|
+
Self::Tensor(lhs_v) => match rhs
|
|
345
|
+
{
|
|
346
|
+
Self::Tensor(rhs_v) =>
|
|
347
|
+
{
|
|
348
|
+
if lhs_v.len() != rhs_v.len()
|
|
349
|
+
{
|
|
350
|
+
Err(Error::InvalidBinaryOperands.into())
|
|
351
|
+
}
|
|
352
|
+
else
|
|
353
|
+
{
|
|
354
|
+
let res = lhs_v
|
|
355
|
+
.iter()
|
|
356
|
+
.zip(rhs_v.iter())
|
|
357
|
+
.map(|(a, b)| (*a).$op(*b))
|
|
358
|
+
.collect::<Vec<f32>>();
|
|
359
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
360
|
+
}
|
|
361
|
+
}
|
|
362
|
+
Self::Float(rhs) =>
|
|
363
|
+
{
|
|
364
|
+
let rhs_scalar = rhs as f32;
|
|
365
|
+
let res = lhs_v
|
|
366
|
+
.iter()
|
|
367
|
+
.map(|a| (*a).$op(rhs_scalar))
|
|
368
|
+
.collect::<Vec<f32>>();
|
|
369
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
370
|
+
}
|
|
371
|
+
Self::Integer(rhs) =>
|
|
372
|
+
{
|
|
373
|
+
let rhs_scalar = rhs as f32;
|
|
374
|
+
let res = lhs_v
|
|
375
|
+
.iter()
|
|
376
|
+
.map(|a| (*a).$op(rhs_scalar))
|
|
377
|
+
.collect::<Vec<f32>>();
|
|
378
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
379
|
+
}
|
|
197
380
|
Self::Null => Ok(Self::Null),
|
|
198
381
|
_ => Err(Error::InvalidBinaryOperands.into()),
|
|
199
382
|
},
|
|
@@ -223,6 +406,7 @@ impl Value
|
|
|
223
406
|
| Value::Edge(..)
|
|
224
407
|
| Value::Array(..)
|
|
225
408
|
| Value::Map(..)
|
|
409
|
+
| Value::SinglePath(..)
|
|
226
410
|
| Value::Path(..) => Err(Error::InvalidBinaryOperands),
|
|
227
411
|
Value::Null => Ok(Value::Null),
|
|
228
412
|
Self::Float(lhs) => match rhs
|
|
@@ -243,6 +427,43 @@ impl Value
|
|
|
243
427
|
Self::Null => Ok(Self::Null),
|
|
244
428
|
_ => Err(Error::InvalidBinaryOperands),
|
|
245
429
|
},
|
|
430
|
+
Self::Tensor(lhs_v) => match rhs
|
|
431
|
+
{
|
|
432
|
+
Self::Float(rhs) =>
|
|
433
|
+
{
|
|
434
|
+
let res = lhs_v
|
|
435
|
+
.iter()
|
|
436
|
+
.map(|a| a.powf(rhs as f32))
|
|
437
|
+
.collect::<Vec<f32>>();
|
|
438
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
439
|
+
}
|
|
440
|
+
Self::Integer(rhs) =>
|
|
441
|
+
{
|
|
442
|
+
let res = lhs_v
|
|
443
|
+
.iter()
|
|
444
|
+
.map(|a| a.powf(rhs as f32))
|
|
445
|
+
.collect::<Vec<f32>>();
|
|
446
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
447
|
+
}
|
|
448
|
+
Self::Tensor(rhs_v) =>
|
|
449
|
+
{
|
|
450
|
+
if lhs_v.len() != rhs_v.len()
|
|
451
|
+
{
|
|
452
|
+
Err(Error::InvalidBinaryOperands)
|
|
453
|
+
}
|
|
454
|
+
else
|
|
455
|
+
{
|
|
456
|
+
let res = lhs_v
|
|
457
|
+
.iter()
|
|
458
|
+
.zip(rhs_v.iter())
|
|
459
|
+
.map(|(a, b)| a.powf(*b))
|
|
460
|
+
.collect::<Vec<f32>>();
|
|
461
|
+
Ok(Value::Tensor(Tensor::from_f32_slice(&res)))
|
|
462
|
+
}
|
|
463
|
+
}
|
|
464
|
+
Self::Null => Ok(Self::Null),
|
|
465
|
+
_ => Err(Error::InvalidBinaryOperands),
|
|
466
|
+
},
|
|
246
467
|
}
|
|
247
468
|
}
|
|
248
469
|
}
|
|
@@ -256,6 +477,7 @@ impl Neg for Value
|
|
|
256
477
|
{
|
|
257
478
|
Self::Float(fl) => Ok((-fl).into()),
|
|
258
479
|
Self::Integer(i) => Ok((-i).into()),
|
|
480
|
+
Self::Tensor(t) => Ok(Value::Tensor(t.into_iter().map(|x| -x).collect())),
|
|
259
481
|
Value::Null => Ok(Value::Null),
|
|
260
482
|
Value::Boolean(..)
|
|
261
483
|
| Value::Key(..)
|
|
@@ -265,6 +487,7 @@ impl Neg for Value
|
|
|
265
487
|
| Value::TimeStamp(..)
|
|
266
488
|
| Value::Array(..)
|
|
267
489
|
| Value::Map(..)
|
|
490
|
+
| Value::SinglePath(..)
|
|
268
491
|
| Value::Path(..) => Err(Error::InvalidNegationOperands),
|
|
269
492
|
}
|
|
270
493
|
}
|
|
@@ -284,9 +507,11 @@ impl std::fmt::Display for Value
|
|
|
284
507
|
Value::String(s) => write!(f, "{}", s),
|
|
285
508
|
Value::TimeStamp(t) => write!(f, "{}", t),
|
|
286
509
|
Value::Array(v) => write!(f, "[{}]", v.iter().map(|x| x.to_string()).join(", ")),
|
|
510
|
+
Value::Tensor(v) => write!(f, "[{}]", v.iter().map(|x| x.to_string()).join(", ")),
|
|
287
511
|
Value::Map(o) => write!(f, "{}", o),
|
|
288
512
|
Value::Node(n) => write!(f, "{}", n),
|
|
289
513
|
Value::Edge(e) => write!(f, "{}", e),
|
|
514
|
+
Value::SinglePath(p) => write!(f, "{}", p),
|
|
290
515
|
Value::Path(p) => write!(f, "{}", p),
|
|
291
516
|
}
|
|
292
517
|
}
|
|
@@ -331,9 +556,26 @@ pub enum FromValueResult<T>
|
|
|
331
556
|
Invalid(Value),
|
|
332
557
|
}
|
|
333
558
|
|
|
559
|
+
fn identity<T>(t: T) -> T
|
|
560
|
+
{
|
|
561
|
+
t
|
|
562
|
+
}
|
|
563
|
+
fn boxed<T>(t: T) -> Box<T>
|
|
564
|
+
{
|
|
565
|
+
Box::new(t)
|
|
566
|
+
}
|
|
567
|
+
|
|
568
|
+
// Suppression is needed because this function must take a
|
|
569
|
+
// box as argument to be used in the macro bellow
|
|
570
|
+
#[allow(clippy::boxed_local)]
|
|
571
|
+
fn unboxed<T>(t: Box<T>) -> T
|
|
572
|
+
{
|
|
573
|
+
*t
|
|
574
|
+
}
|
|
575
|
+
|
|
334
576
|
macro_rules! impl_from_value {
|
|
335
|
-
($type:ty, $vn:tt, try) => {
|
|
336
|
-
impl_from_value!($type, $vn);
|
|
577
|
+
($type:ty, $vn:tt, $factory: ident, $defactory: ident, try) => {
|
|
578
|
+
impl_from_value!($type, $vn, $factory, $defactory);
|
|
337
579
|
impl TryFrom<Value> for $type
|
|
338
580
|
{
|
|
339
581
|
type Error = Error;
|
|
@@ -341,7 +583,7 @@ macro_rules! impl_from_value {
|
|
|
341
583
|
{
|
|
342
584
|
match value
|
|
343
585
|
{
|
|
344
|
-
Value::$vn(v) => Ok(v),
|
|
586
|
+
Value::$vn(v) => Ok($defactory(v)),
|
|
345
587
|
_ => Err(
|
|
346
588
|
Error::InvalidValueCast {
|
|
347
589
|
value: Box::new(value),
|
|
@@ -358,18 +600,18 @@ macro_rules! impl_from_value {
|
|
|
358
600
|
{
|
|
359
601
|
match value
|
|
360
602
|
{
|
|
361
|
-
Value::$vn(v) => FromValueResult::Ok(v),
|
|
603
|
+
Value::$vn(v) => FromValueResult::Ok($defactory(v)),
|
|
362
604
|
_ => FromValueResult::Invalid(value),
|
|
363
605
|
}
|
|
364
606
|
}
|
|
365
607
|
}
|
|
366
608
|
};
|
|
367
|
-
($type:ty, $vn:tt) => {
|
|
609
|
+
($type:ty, $vn:tt, $factory: ident, $defactory: ident) => {
|
|
368
610
|
impl From<$type> for Value
|
|
369
611
|
{
|
|
370
612
|
fn from(v: $type) -> Value
|
|
371
613
|
{
|
|
372
|
-
Value::$vn(v)
|
|
614
|
+
Value::$vn($factory(v))
|
|
373
615
|
}
|
|
374
616
|
}
|
|
375
617
|
|
|
@@ -432,17 +674,99 @@ macro_rules! impl_from_value {
|
|
|
432
674
|
};
|
|
433
675
|
}
|
|
434
676
|
|
|
435
|
-
impl_from_value!(graph::Key, Key, try);
|
|
436
|
-
impl_from_value!(bool, Boolean, try);
|
|
437
|
-
impl_from_value!(i64, Integer, try);
|
|
438
|
-
impl_from_value!(f64, Float);
|
|
439
|
-
impl_from_value!(String, String, try);
|
|
440
|
-
impl_from_value!(TimeStamp, TimeStamp);
|
|
441
|
-
impl_from_value!(graph::Node, Node, try);
|
|
442
|
-
impl_from_value!(graph::Edge, Edge, try);
|
|
443
|
-
impl_from_value!(graph::SinglePath,
|
|
444
|
-
impl_from_value!(
|
|
445
|
-
impl_from_value!(
|
|
677
|
+
impl_from_value!(graph::Key, Key, identity, identity, try);
|
|
678
|
+
impl_from_value!(bool, Boolean, identity, identity, try);
|
|
679
|
+
impl_from_value!(i64, Integer, identity, identity, try);
|
|
680
|
+
impl_from_value!(f64, Float, identity, identity);
|
|
681
|
+
impl_from_value!(String, String, identity, identity, try);
|
|
682
|
+
impl_from_value!(TimeStamp, TimeStamp, identity, identity);
|
|
683
|
+
impl_from_value!(graph::Node, Node, identity, identity, try);
|
|
684
|
+
impl_from_value!(graph::Edge, Edge, identity, identity, try);
|
|
685
|
+
impl_from_value!(graph::SinglePath, SinglePath, boxed, unboxed, try);
|
|
686
|
+
impl_from_value!(graph::Path, Path, boxed, unboxed, try);
|
|
687
|
+
impl_from_value!(Vec<Value>, Array, identity, identity, try);
|
|
688
|
+
impl_from_value!(ValueMap, Map, identity, identity, try);
|
|
689
|
+
impl_from_value!(Tensor, Tensor, identity, identity);
|
|
690
|
+
|
|
691
|
+
impl TryFrom<Value> for Tensor
|
|
692
|
+
{
|
|
693
|
+
type Error = Error;
|
|
694
|
+
fn try_from(value: Value) -> Result<Tensor, Self::Error>
|
|
695
|
+
{
|
|
696
|
+
match value
|
|
697
|
+
{
|
|
698
|
+
Value::Tensor(v) => Ok(v),
|
|
699
|
+
Value::Array(arr) =>
|
|
700
|
+
{
|
|
701
|
+
let mut out = Vec::with_capacity(arr.len());
|
|
702
|
+
for v in arr.iter()
|
|
703
|
+
{
|
|
704
|
+
match v
|
|
705
|
+
{
|
|
706
|
+
Value::Float(f) => out.push(*f as f32),
|
|
707
|
+
Value::Integer(i) => out.push(*i as f32),
|
|
708
|
+
_ =>
|
|
709
|
+
{
|
|
710
|
+
return Err(Error::InvalidValueCast {
|
|
711
|
+
value: Box::new(Value::Array(arr.clone())),
|
|
712
|
+
typename: "Vec<f32>",
|
|
713
|
+
});
|
|
714
|
+
}
|
|
715
|
+
}
|
|
716
|
+
}
|
|
717
|
+
Ok(Tensor::from_f32_slice(&out))
|
|
718
|
+
}
|
|
719
|
+
_ => Err(Error::InvalidValueCast {
|
|
720
|
+
value: Box::new(value),
|
|
721
|
+
typename: "Vec<f32>",
|
|
722
|
+
}),
|
|
723
|
+
}
|
|
724
|
+
}
|
|
725
|
+
}
|
|
726
|
+
|
|
727
|
+
impl TryFrom<Value> for Vec<f32>
|
|
728
|
+
{
|
|
729
|
+
type Error = Error;
|
|
730
|
+
fn try_from(value: Value) -> Result<Vec<f32>, Self::Error>
|
|
731
|
+
{
|
|
732
|
+
match value
|
|
733
|
+
{
|
|
734
|
+
Value::Tensor(t) => Ok(t.to_f32_vec()),
|
|
735
|
+
Value::Array(arr) =>
|
|
736
|
+
{
|
|
737
|
+
let mut out = Vec::with_capacity(arr.len());
|
|
738
|
+
for v in arr.iter()
|
|
739
|
+
{
|
|
740
|
+
match v
|
|
741
|
+
{
|
|
742
|
+
Value::Float(f) => out.push(*f as f32),
|
|
743
|
+
Value::Integer(i) => out.push(*i as f32),
|
|
744
|
+
_ =>
|
|
745
|
+
{
|
|
746
|
+
return Err(Error::InvalidValueCast {
|
|
747
|
+
value: Box::new(Value::Array(arr.clone())),
|
|
748
|
+
typename: "Vec<f32>",
|
|
749
|
+
});
|
|
750
|
+
}
|
|
751
|
+
}
|
|
752
|
+
}
|
|
753
|
+
Ok(out)
|
|
754
|
+
}
|
|
755
|
+
_ => Err(Error::InvalidValueCast {
|
|
756
|
+
value: Box::new(value),
|
|
757
|
+
typename: "Vec<f32>",
|
|
758
|
+
}),
|
|
759
|
+
}
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
|
|
763
|
+
impl From<Vec<f32>> for Value
|
|
764
|
+
{
|
|
765
|
+
fn from(v: Vec<f32>) -> Value
|
|
766
|
+
{
|
|
767
|
+
Value::Tensor(Tensor::from(v))
|
|
768
|
+
}
|
|
769
|
+
}
|
|
446
770
|
|
|
447
771
|
impl TryFrom<Value> for f64
|
|
448
772
|
{
|