avrocadabra 0.0.1
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 +7 -0
- data/CHANGELOG.md +6 -0
- data/Cargo.lock +923 -0
- data/Cargo.toml +8 -0
- data/LICENSE.txt +21 -0
- data/README.md +131 -0
- data/docs/avro_turf.md +61 -0
- data/docs/licenses/crates/quad-rand-0.2.3/DECLARED-LICENSE.txt +32 -0
- data/docs/licenses/gcc-16.2.0/COPYING +340 -0
- data/docs/licenses/gcc-16.2.0/COPYING.RUNTIME +73 -0
- data/docs/licenses/mingw-w64-14.0.0/AUTHORS +73 -0
- data/docs/licenses/mingw-w64-14.0.0/COPYING +43 -0
- data/docs/licenses/rust-1.99.0/COMPILER-BUILTINS.txt +275 -0
- data/docs/licenses/rust-1.99.0/COPYRIGHT-library.html +29357 -0
- data/docs/licenses/rust-1.99.0/LIBM.txt +258 -0
- data/docs/licenses/rust-1.99.0/LLVM-LIBUNWIND.txt +311 -0
- data/docs/licenses/rust-1.99.0/RUST-LICENSE-APACHE.txt +176 -0
- data/docs/licenses/rust-1.99.0/RUST-LICENSE-MIT.txt +25 -0
- data/docs/licenses/rust-1.99.0/STDLIB-BACKTRACE-MIT.txt +25 -0
- data/docs/licenses/rust-1.99.0/STDLIB-PORTABLE-SIMD-MIT.txt +19 -0
- data/docs/licenses/rust-1.99.0/STDLIB-STDARCH-MIT.txt +25 -0
- data/docs/licenses/rust-1.99.0/licenses/Apache-2.0.txt +73 -0
- data/docs/licenses/rust-1.99.0/licenses/BSD-2-Clause.txt +9 -0
- data/docs/licenses/rust-1.99.0/licenses/CC-BY-SA-4.0.txt +427 -0
- data/docs/licenses/rust-1.99.0/licenses/GCC-exception-3.1.txt +30 -0
- data/docs/licenses/rust-1.99.0/licenses/GPL-2.0-only.txt +133 -0
- data/docs/licenses/rust-1.99.0/licenses/GPL-3.0-or-later.txt +202 -0
- data/docs/licenses/rust-1.99.0/licenses/ISC.txt +7 -0
- data/docs/licenses/rust-1.99.0/licenses/LLVM-exception.txt +15 -0
- data/docs/licenses/rust-1.99.0/licenses/MIT.txt +9 -0
- data/docs/licenses/rust-1.99.0/licenses/NCSA.txt +28 -0
- data/docs/licenses/rust-1.99.0/licenses/OFL-1.1.txt +43 -0
- data/docs/licenses/rust-1.99.0/licenses/Unicode-3.0.txt +39 -0
- data/docs/releasing.md +71 -0
- data/docs/third_party.md +5922 -0
- data/ext/avrocadabra/Cargo.toml +29 -0
- data/ext/avrocadabra/build.rs +4 -0
- data/ext/avrocadabra/extconf.rb +9 -0
- data/ext/avrocadabra/src/big_decimal.rs +107 -0
- data/ext/avrocadabra/src/callback.rs +106 -0
- data/ext/avrocadabra/src/convert.rs +617 -0
- data/ext/avrocadabra/src/decode_value.rs +473 -0
- data/ext/avrocadabra/src/guard.rs +680 -0
- data/ext/avrocadabra/src/lib.rs +670 -0
- data/ext/avrocadabra/src/mapping.rs +63 -0
- data/ext/avrocadabra/src/memory.rs +194 -0
- data/ext/avrocadabra/src/prepare.rs +819 -0
- data/ext/avrocadabra/src/resolution.rs +1932 -0
- data/ext/avrocadabra/src/schema_state.rs +60 -0
- data/ext/avrocadabra/src/validation.rs +174 -0
- data/ext/avrocadabra/src/wire.rs +269 -0
- data/lib/avrocadabra/avro_turf/cache.rb +28 -0
- data/lib/avrocadabra/avro_turf/codec.rb +69 -0
- data/lib/avrocadabra/avro_turf/datum_reader.rb +17 -0
- data/lib/avrocadabra/avro_turf/datum_writer.rb +14 -0
- data/lib/avrocadabra/avro_turf/mapping.rb +48 -0
- data/lib/avrocadabra/avro_turf/messaging.rb +12 -0
- data/lib/avrocadabra/avro_turf/ractor_support.rb +154 -0
- data/lib/avrocadabra/avro_turf/routing.rb +15 -0
- data/lib/avrocadabra/avro_turf/schema_state.rb +70 -0
- data/lib/avrocadabra/avro_turf/validation.rb +33 -0
- data/lib/avrocadabra/avro_turf.rb +25 -0
- data/lib/avrocadabra/logical.rb +71 -0
- data/lib/avrocadabra/schema.rb +48 -0
- data/lib/avrocadabra/version.rb +5 -0
- data/lib/avrocadabra.rb +34 -0
- metadata +183 -0
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
use magnus::{Error, Exception, RArray, RString, Value, prelude::*};
|
|
2
|
+
|
|
3
|
+
#[derive(Clone, Copy)]
|
|
4
|
+
pub struct Mapping {
|
|
5
|
+
context: Value,
|
|
6
|
+
node: RArray,
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
impl Mapping {
|
|
10
|
+
pub fn new(graph: RArray) -> Result<Self, Error> {
|
|
11
|
+
Ok(Self {
|
|
12
|
+
context: graph.entry(0)?,
|
|
13
|
+
node: graph.entry(1)?,
|
|
14
|
+
})
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
pub fn child(self, index: usize) -> Result<Self, Error> {
|
|
18
|
+
let children: RArray = self.node.entry(2)?;
|
|
19
|
+
Ok(Self {
|
|
20
|
+
context: self.context,
|
|
21
|
+
node: children.entry(index as isize)?,
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
pub fn convert(self, method: &str, value: Value) -> Result<Value, Error> {
|
|
26
|
+
let adapter: Value = self.node.entry(1)?;
|
|
27
|
+
if adapter.is_nil() {
|
|
28
|
+
Ok(value)
|
|
29
|
+
} else {
|
|
30
|
+
adapter.funcall(method, (value,))
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
pub fn identity(self) -> Result<bool, Error> {
|
|
35
|
+
Ok(self.node.entry::<Value>(1)?.is_nil())
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
pub fn union_index(self, value: Value, budget: RArray) -> Result<usize, Error> {
|
|
39
|
+
let schema: Value = self.node.entry(0)?;
|
|
40
|
+
self.context.funcall("union_index", (schema, value, budget))
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
pub fn enum_index(self, value: Value) -> Result<Option<usize>, Error> {
|
|
44
|
+
let schema: Value = self.node.entry(0)?;
|
|
45
|
+
let symbols: RArray = schema.funcall_public("symbols", ())?;
|
|
46
|
+
symbols.funcall_public("index", (value,))
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
pub fn default_value(self, name: RString) -> Result<Value, Error> {
|
|
50
|
+
let schema: Value = self.node.entry(0)?;
|
|
51
|
+
self.context.funcall("default_value", (schema, name))
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
pub fn encoding_error(self, value: Value) -> Result<Error, Error> {
|
|
55
|
+
let schema: Value = self.node.entry(0)?;
|
|
56
|
+
let exception: Exception = self.context.funcall("encoding_error", (schema, value))?;
|
|
57
|
+
Ok(exception.into())
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
pub fn child(mapping: Option<Mapping>, index: usize) -> Result<Option<Mapping>, Error> {
|
|
62
|
+
mapping.map(|mapping| mapping.child(index)).transpose()
|
|
63
|
+
}
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
use apache_avro::{
|
|
2
|
+
Schema,
|
|
3
|
+
schema::{Alias, FixedSchema, InnerDecimalSchema, Name, RecordField, UuidSchema},
|
|
4
|
+
types::Value,
|
|
5
|
+
};
|
|
6
|
+
use serde_json::Value as Json;
|
|
7
|
+
use std::collections::{BTreeMap, HashMap};
|
|
8
|
+
|
|
9
|
+
pub trait HeapSize {
|
|
10
|
+
fn heap_size(&self) -> usize;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
impl HeapSize for String {
|
|
14
|
+
fn heap_size(&self) -> usize {
|
|
15
|
+
self.capacity()
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
impl<T: HeapSize> HeapSize for Vec<T> {
|
|
20
|
+
fn heap_size(&self) -> usize {
|
|
21
|
+
self.capacity() * size_of::<T>() + self.iter().map(HeapSize::heap_size).sum::<usize>()
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
impl<T: HeapSize> HeapSize for Option<T> {
|
|
26
|
+
fn heap_size(&self) -> usize {
|
|
27
|
+
self.as_ref().map_or(0, HeapSize::heap_size)
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
impl<T: HeapSize> HeapSize for Box<T> {
|
|
32
|
+
fn heap_size(&self) -> usize {
|
|
33
|
+
size_of::<T>() + (**self).heap_size()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
impl<T> HeapSize for &T {
|
|
38
|
+
fn heap_size(&self) -> usize {
|
|
39
|
+
0
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
impl HeapSize for usize {
|
|
44
|
+
fn heap_size(&self) -> usize {
|
|
45
|
+
0
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
impl<K: HeapSize, V: HeapSize> HeapSize for HashMap<K, V> {
|
|
50
|
+
fn heap_size(&self) -> usize {
|
|
51
|
+
// Account for spare hash buckets and control bytes as well as entries.
|
|
52
|
+
let buckets = if self.capacity() == 0 {
|
|
53
|
+
0
|
|
54
|
+
} else {
|
|
55
|
+
(self.capacity() + 1).next_power_of_two()
|
|
56
|
+
};
|
|
57
|
+
buckets * (size_of::<(K, V)>() + 1)
|
|
58
|
+
+ self
|
|
59
|
+
.iter()
|
|
60
|
+
.map(|(key, value)| key.heap_size() + value.heap_size())
|
|
61
|
+
.sum::<usize>()
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
impl<K: HeapSize, V: HeapSize> HeapSize for BTreeMap<K, V> {
|
|
66
|
+
fn heap_size(&self) -> usize {
|
|
67
|
+
tree_storage::<K, V>(self.len())
|
|
68
|
+
+ self
|
|
69
|
+
.iter()
|
|
70
|
+
.map(|(key, value)| key.heap_size() + value.heap_size())
|
|
71
|
+
.sum::<usize>()
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
pub fn tree_storage<K, V>(length: usize) -> usize {
|
|
76
|
+
// Rust does not expose B-tree node capacities; include spare entries and links.
|
|
77
|
+
length.div_ceil(6) * (11 * size_of::<(K, V)>() + 15 * size_of::<usize>())
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
impl HeapSize for Json {
|
|
81
|
+
fn heap_size(&self) -> usize {
|
|
82
|
+
match self {
|
|
83
|
+
Self::String(value) => value.heap_size(),
|
|
84
|
+
Self::Array(values) => values.heap_size(),
|
|
85
|
+
Self::Object(values) => {
|
|
86
|
+
tree_storage::<String, Json>(values.len())
|
|
87
|
+
+ values
|
|
88
|
+
.iter()
|
|
89
|
+
.map(|(key, value)| key.heap_size() + value.heap_size())
|
|
90
|
+
.sum::<usize>()
|
|
91
|
+
}
|
|
92
|
+
_ => 0,
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
impl HeapSize for Name {
|
|
98
|
+
fn heap_size(&self) -> usize {
|
|
99
|
+
self.name().len() + self.namespace().map_or(0, |namespace| namespace.len() + 1)
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
impl HeapSize for Alias {
|
|
104
|
+
fn heap_size(&self) -> usize {
|
|
105
|
+
self.name().len() + self.namespace().map_or(0, |namespace| namespace.len() + 1)
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
impl HeapSize for FixedSchema {
|
|
110
|
+
fn heap_size(&self) -> usize {
|
|
111
|
+
self.name.heap_size()
|
|
112
|
+
+ self.aliases.heap_size()
|
|
113
|
+
+ self.doc.heap_size()
|
|
114
|
+
+ self.attributes.heap_size()
|
|
115
|
+
}
|
|
116
|
+
}
|
|
117
|
+
|
|
118
|
+
impl HeapSize for RecordField {
|
|
119
|
+
fn heap_size(&self) -> usize {
|
|
120
|
+
self.name.heap_size()
|
|
121
|
+
+ self.doc.heap_size()
|
|
122
|
+
+ self.aliases.heap_size()
|
|
123
|
+
+ self.default.heap_size()
|
|
124
|
+
+ self.schema.heap_size()
|
|
125
|
+
+ self.custom_attributes.heap_size()
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
|
|
129
|
+
impl HeapSize for Schema {
|
|
130
|
+
fn heap_size(&self) -> usize {
|
|
131
|
+
match self {
|
|
132
|
+
Self::Record(record) => {
|
|
133
|
+
record.name.heap_size()
|
|
134
|
+
+ record.aliases.heap_size()
|
|
135
|
+
+ record.doc.heap_size()
|
|
136
|
+
+ record.fields.heap_size()
|
|
137
|
+
+ record.lookup.heap_size()
|
|
138
|
+
+ record.attributes.heap_size()
|
|
139
|
+
}
|
|
140
|
+
Self::Enum(value) => {
|
|
141
|
+
value.name.heap_size()
|
|
142
|
+
+ value.aliases.heap_size()
|
|
143
|
+
+ value.doc.heap_size()
|
|
144
|
+
+ value.symbols.heap_size()
|
|
145
|
+
+ value.default.heap_size()
|
|
146
|
+
+ value.attributes.heap_size()
|
|
147
|
+
}
|
|
148
|
+
Self::Fixed(value) | Self::Duration(value) | Self::Uuid(UuidSchema::Fixed(value)) => {
|
|
149
|
+
value.heap_size()
|
|
150
|
+
}
|
|
151
|
+
Self::Decimal(value) => match &value.inner {
|
|
152
|
+
InnerDecimalSchema::Fixed(fixed) => fixed.heap_size(),
|
|
153
|
+
InnerDecimalSchema::Bytes => 0,
|
|
154
|
+
},
|
|
155
|
+
Self::Array(value) => value.items.heap_size() + value.attributes.heap_size(),
|
|
156
|
+
Self::Map(value) => value.types.heap_size() + value.attributes.heap_size(),
|
|
157
|
+
Self::Union(value) => {
|
|
158
|
+
let variants = value.variants();
|
|
159
|
+
variants.len() * (size_of::<Schema>() + size_of::<usize>())
|
|
160
|
+
+ tree_storage::<apache_avro::schema::SchemaKind, usize>(variants.len())
|
|
161
|
+
+ variants.iter().map(HeapSize::heap_size).sum::<usize>()
|
|
162
|
+
}
|
|
163
|
+
Self::Ref { name } => name.heap_size(),
|
|
164
|
+
_ => 0,
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
impl HeapSize for Value {
|
|
170
|
+
fn heap_size(&self) -> usize {
|
|
171
|
+
match self {
|
|
172
|
+
Self::String(value) | Self::Enum(_, value) => value.heap_size(),
|
|
173
|
+
Self::Bytes(value) | Self::Fixed(_, value) => value.capacity(),
|
|
174
|
+
Self::Array(values) => values.heap_size(),
|
|
175
|
+
Self::Map(values) => values.heap_size(),
|
|
176
|
+
Self::Record(values) => {
|
|
177
|
+
values.capacity() * size_of::<(String, Value)>()
|
|
178
|
+
+ values
|
|
179
|
+
.iter()
|
|
180
|
+
.map(|(name, value)| name.heap_size() + value.heap_size())
|
|
181
|
+
.sum::<usize>()
|
|
182
|
+
}
|
|
183
|
+
Self::Union(_, value) => value.heap_size(),
|
|
184
|
+
Self::Decimal(value) => {
|
|
185
|
+
let value = apache_avro::BigDecimal::new(value.clone().into(), 0);
|
|
186
|
+
(value.as_bigint_and_scale().0.bits().div_ceil(64) * 8) as usize
|
|
187
|
+
}
|
|
188
|
+
Self::BigDecimal(value) => {
|
|
189
|
+
(value.as_bigint_and_scale().0.bits().div_ceil(64) * 8) as usize
|
|
190
|
+
}
|
|
191
|
+
_ => 0,
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
}
|