teptris 0.2.47-s390x-linux → 0.2.49-s390x-linux
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/teptris_ext/materialize.c +107 -13
- data/lib/teptris/3.3/teptris_ext.so +0 -0
- data/lib/teptris/3.4/teptris_ext.so +0 -0
- data/lib/teptris/4.0/teptris_ext.so +0 -0
- data/lib/teptris/version.rb +1 -1
- metadata +2 -2
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: b72e68daff45d9c5b094bc8c97eee29afb76f286f55a30f4d2278f1d7a1fe6f8
|
|
4
|
+
data.tar.gz: e4a01e1194bfbf77a97b1810bf8e164c36e6cf691842cdf5a59374b4392f0237
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 22400c9c1875b61c2ee3663870f87a2b204638a3911f9b3164d9ea53ee5f88c5f555b9be0b6d28c8d95fff491016ee3803ed35e6e1283e71e5de7f24baaff51a
|
|
7
|
+
data.tar.gz: 52b10b4d490f0fa604a535f13ef0e46fb646692315e2d8460b46e1b59d2c983b4322438264809cf6be7289f35e57e7835e2fe65e7bdf1c463a603cd9a9a4a974
|
|
@@ -41,11 +41,16 @@ static VALUE time_from_dt(const teptris_datetime *d, bool has_offset) {
|
|
|
41
41
|
}
|
|
42
42
|
return rb_time_num_new(num, INT2FIX(d->offset_seconds));
|
|
43
43
|
}
|
|
44
|
+
/* whole seconds skip the Rational: Time.local normalizes
|
|
45
|
+
* Rational(s * 1e9, 1e9) to exactly s, so an Integer is the same
|
|
46
|
+
* result without the allocation or the rational path */
|
|
47
|
+
VALUE sec = (d->nanosecond != 0)
|
|
48
|
+
? rb_Rational(LL2NUM((int64_t)d->second * 1000000000 +
|
|
49
|
+
d->nanosecond),
|
|
50
|
+
LL2NUM(1000000000))
|
|
51
|
+
: INT2FIX(d->second);
|
|
44
52
|
VALUE args[6] = {INT2FIX(d->year), INT2FIX(d->month), INT2FIX(d->day),
|
|
45
|
-
INT2FIX(d->hour), INT2FIX(d->minute),
|
|
46
|
-
rb_Rational(LL2NUM((int64_t)d->second * 1000000000 +
|
|
47
|
-
d->nanosecond),
|
|
48
|
-
LL2NUM(1000000000))};
|
|
53
|
+
INT2FIX(d->hour), INT2FIX(d->minute), sec};
|
|
49
54
|
return rb_funcallv(rb_cTime, rb_intern("local"), 6, args);
|
|
50
55
|
}
|
|
51
56
|
|
|
@@ -89,7 +94,87 @@ static VALUE dt_string(const teptris_datetime *d, int kind) {
|
|
|
89
94
|
return rb_enc_str_new(buf, l, rb_utf8_encoding());
|
|
90
95
|
}
|
|
91
96
|
|
|
92
|
-
|
|
97
|
+
/* ---- per-load table-key cache ------------------------------------------------
|
|
98
|
+
* TOML keys repeat within a document and across a batch; a fresh String
|
|
99
|
+
* per occurrence costs an allocation and a full Hash re-hash each time.
|
|
100
|
+
* This cache maps key CONTENT to one frozen String, shared everywhere:
|
|
101
|
+
* repeated keys become a single GC-pinned object with its hash already
|
|
102
|
+
* computed. It is document-local (dies with the load call), capped at
|
|
103
|
+
* KC_CAP entries so unique-key corpora pay only a cheap failed probe
|
|
104
|
+
* after the cap, and never touches the VM's global fstring table (the
|
|
105
|
+
* intern-always attempt regressed there — teptris-ruby#122: unique
|
|
106
|
+
* keys make the intern table pure overhead). Strings are frozen so the
|
|
107
|
+
* sharing cannot alias a mutation. NULL cache = fresh strings (the
|
|
108
|
+
* low-volume schema-RAW path). */
|
|
109
|
+
|
|
110
|
+
#define KC_CAP 4096
|
|
111
|
+
#define KC_SLOTS (KC_CAP * 2) /* stays <=50% full: probes stay ~2 */
|
|
112
|
+
|
|
113
|
+
typedef struct {
|
|
114
|
+
VALUE str; /* Qfalse = empty slot */
|
|
115
|
+
} kc_slot;
|
|
116
|
+
|
|
117
|
+
typedef struct {
|
|
118
|
+
VALUE keep; /* Ruby Array pinning every cached String */
|
|
119
|
+
kc_slot *slots;
|
|
120
|
+
size_t used;
|
|
121
|
+
} keycache;
|
|
122
|
+
|
|
123
|
+
static uint64_t kc_hash(const char *p, size_t len)
|
|
124
|
+
{
|
|
125
|
+
uint64_t h = 1469598103934665603ULL;
|
|
126
|
+
for (size_t i = 0; i < len; i++) {
|
|
127
|
+
h ^= (unsigned char)p[i];
|
|
128
|
+
h *= 1099511628211ULL;
|
|
129
|
+
}
|
|
130
|
+
return h;
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
static void kc_init(keycache *kc)
|
|
134
|
+
{
|
|
135
|
+
kc->keep = rb_ary_new_capa(64);
|
|
136
|
+
kc->slots = calloc(KC_SLOTS, sizeof(kc_slot)); /* zero = Qfalse empty */
|
|
137
|
+
if (kc->slots == NULL) {
|
|
138
|
+
/* no cache is a correctness-preserving fallback */
|
|
139
|
+
kc->keep = Qnil;
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
kc->used = 0;
|
|
143
|
+
}
|
|
144
|
+
|
|
145
|
+
static void kc_free(keycache *kc)
|
|
146
|
+
{
|
|
147
|
+
free(kc->slots);
|
|
148
|
+
kc->slots = NULL;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
static VALUE kc_key(keycache *kc, const char *p, size_t len)
|
|
152
|
+
{
|
|
153
|
+
if (kc == NULL || kc->slots == NULL) {
|
|
154
|
+
return rb_enc_str_new(p, (long)len, rb_utf8_encoding());
|
|
155
|
+
}
|
|
156
|
+
size_t mask = KC_SLOTS - 1;
|
|
157
|
+
size_t slot = (size_t)kc_hash(p, len) & mask;
|
|
158
|
+
while (kc->slots[slot].str != Qfalse) {
|
|
159
|
+
VALUE s = kc->slots[slot].str;
|
|
160
|
+
if ((size_t)RSTRING_LEN(s) == len &&
|
|
161
|
+
memcmp(RSTRING_PTR(s), p, len) == 0) {
|
|
162
|
+
return s; /* hit: one shared object, hash already cached */
|
|
163
|
+
}
|
|
164
|
+
slot = (slot + 1) & mask;
|
|
165
|
+
}
|
|
166
|
+
VALUE fresh = rb_enc_str_new(p, (long)len, rb_utf8_encoding());
|
|
167
|
+
rb_obj_freeze(fresh);
|
|
168
|
+
rb_ary_push(kc->keep, fresh); /* GC pin before it enters the slots */
|
|
169
|
+
if (kc->used < KC_CAP) {
|
|
170
|
+
kc->slots[slot].str = fresh;
|
|
171
|
+
kc->used++;
|
|
172
|
+
}
|
|
173
|
+
return fresh;
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
static VALUE obj_from_node(const teptris_node *n, unsigned flags,
|
|
177
|
+
keycache *kc) {
|
|
93
178
|
switch (teptris_node_kind(n)) {
|
|
94
179
|
case TEPTRIS_TABLE: {
|
|
95
180
|
size_t len = teptris_node_table_length(n);
|
|
@@ -97,9 +182,8 @@ static VALUE obj_from_node(const teptris_node *n, unsigned flags) {
|
|
|
97
182
|
for (size_t i = 0; i < len; i++) {
|
|
98
183
|
teptris_view key;
|
|
99
184
|
const teptris_node *v = teptris_node_table_at(n, i, &key);
|
|
100
|
-
rb_hash_aset(h,
|
|
101
|
-
|
|
102
|
-
obj_from_node(v, flags));
|
|
185
|
+
rb_hash_aset(h, kc_key(kc, key.ptr, (size_t)key.len),
|
|
186
|
+
obj_from_node(v, flags, kc));
|
|
103
187
|
}
|
|
104
188
|
return h;
|
|
105
189
|
}
|
|
@@ -107,7 +191,7 @@ static VALUE obj_from_node(const teptris_node *n, unsigned flags) {
|
|
|
107
191
|
size_t len = teptris_node_array_length(n);
|
|
108
192
|
VALUE a = rb_ary_new_capa((long)len);
|
|
109
193
|
for (size_t i = 0; i < len; i++)
|
|
110
|
-
rb_ary_push(a, obj_from_node(teptris_node_array_at(n, i), flags));
|
|
194
|
+
rb_ary_push(a, obj_from_node(teptris_node_array_at(n, i), flags, kc));
|
|
111
195
|
return a;
|
|
112
196
|
}
|
|
113
197
|
case TEPTRIS_STRING: {
|
|
@@ -176,7 +260,10 @@ static VALUE ext_load(int argc, VALUE *argv, VALUE self) {
|
|
|
176
260
|
if (RTEST(fd)) flags |= FMT_FORBID_DATE;
|
|
177
261
|
}
|
|
178
262
|
teptris_document *doc = parse_or_raise(str);
|
|
179
|
-
|
|
263
|
+
keycache kc;
|
|
264
|
+
kc_init(&kc);
|
|
265
|
+
VALUE out = obj_from_node(teptris_document_root(doc), flags, &kc);
|
|
266
|
+
kc_free(&kc);
|
|
180
267
|
teptris_document_free(doc);
|
|
181
268
|
return out;
|
|
182
269
|
}
|
|
@@ -526,7 +613,7 @@ static VALUE asm_rows(const teptris_plan *p, const teptris_plan_result *res,
|
|
|
526
613
|
case TEPTRIS_PLAN_RAW_RESULT: {
|
|
527
614
|
const teptris_node *raw = teptris_plan_result_raw_at(res, i);
|
|
528
615
|
if (raw != NULL) {
|
|
529
|
-
val = obj_from_node(raw, 0);
|
|
616
|
+
val = obj_from_node(raw, 0, NULL);
|
|
530
617
|
}
|
|
531
618
|
break;
|
|
532
619
|
}
|
|
@@ -780,7 +867,11 @@ static VALUE lazy_dig(int argc, VALUE *argv, VALUE self) {
|
|
|
780
867
|
/* full materialization: the eager path, owned */
|
|
781
868
|
static VALUE lazy_to(VALUE self) {
|
|
782
869
|
lazy_value *v = lazy_self(self);
|
|
783
|
-
|
|
870
|
+
keycache kc;
|
|
871
|
+
kc_init(&kc);
|
|
872
|
+
VALUE out = obj_from_node(v->node, 0, &kc);
|
|
873
|
+
kc_free(&kc);
|
|
874
|
+
return out;
|
|
784
875
|
}
|
|
785
876
|
|
|
786
877
|
/* ---------------------------------------------------------------- batch --
|
|
@@ -936,11 +1027,14 @@ static VALUE ext_load_batch(int argc, VALUE *argv, VALUE self) {
|
|
|
936
1027
|
rb_exc_raise(ex);
|
|
937
1028
|
}
|
|
938
1029
|
VALUE out = rb_ary_new_capa(n);
|
|
1030
|
+
keycache kc;
|
|
1031
|
+
kc_init(&kc); /* one cache across the batch: keys repeat across docs */
|
|
939
1032
|
for (long i = 0; i < n; i++) {
|
|
940
1033
|
const teptris_node *root = teptris_document_root(s->docs[i]);
|
|
941
|
-
rb_ary_store(out, i, obj_from_node(root, flags));
|
|
1034
|
+
rb_ary_store(out, i, obj_from_node(root, flags, &kc));
|
|
942
1035
|
teptris_document_free(s->docs[i]);
|
|
943
1036
|
}
|
|
1037
|
+
kc_free(&kc);
|
|
944
1038
|
batch_scratch_free(s);
|
|
945
1039
|
return out;
|
|
946
1040
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
data/lib/teptris/version.rb
CHANGED
metadata
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: teptris
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.2.
|
|
4
|
+
version: 0.2.49
|
|
5
5
|
platform: s390x-linux
|
|
6
6
|
authors:
|
|
7
7
|
- teptris contributors
|
|
8
8
|
autorequire:
|
|
9
9
|
bindir: bin
|
|
10
10
|
cert_chain: []
|
|
11
|
-
date: 2026-09-
|
|
11
|
+
date: 2026-09-26 00:00:00.000000000 Z
|
|
12
12
|
dependencies: []
|
|
13
13
|
description: A native C extension over libteptris, a C99 TOML 1.1 parser/emitter.
|
|
14
14
|
API shape mirrors the tomlib gem.
|