File Coverage

xs/i16.xs
Criterion Covered Total %
statement 93 328 28.3
branch 121 672 18.0
condition n/a
subroutine n/a
pod n/a
total 214 1000 21.4


line stmt bran cond sub pod time code
1             MODULE = Data::HashMap::Shared PACKAGE = Data::HashMap::Shared::I16
2             PROTOTYPES: DISABLE
3              
4             SV*
5             new(char* class, SV* path_sv, UV max_entries, UV lru_max = 0, UV ttl_default = 0, UV lru_skip = 0)
6             CODE:
7 6 50         char errbuf[SHM_ERR_BUFLEN]; const char* path = SvOK(path_sv) ? SvPV_nolen(path_sv) : NULL; ShmHandle* map = shm_i16_create(path, (uint32_t)max_entries, (uint32_t)lru_max, (uint32_t)ttl_default, (uint32_t)lru_skip, errbuf);
8 6 50         if (!map) croak("Data::HashMap::Shared::I16: %s", errbuf[0] ? errbuf : "unknown error");
    0          
9 6           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
10             OUTPUT:
11             RETVAL
12              
13             SV*
14             new_sharded(char* class, SV* path_prefix_sv, UV num_shards, UV max_entries, UV lru_max = 0, UV ttl_default = 0, UV lru_skip = 0)
15             CODE:
16 0 0         const char* path_prefix = SvOK(path_prefix_sv) ? SvPV_nolen(path_prefix_sv) : NULL;
17 0           char errbuf[SHM_ERR_BUFLEN]; ShmHandle* map = shm_i16_create_sharded(path_prefix, (uint32_t)num_shards, (uint32_t)max_entries, (uint32_t)lru_max, (uint32_t)ttl_default, (uint32_t)lru_skip, errbuf);
18 0 0         if (!map) croak("Data::HashMap::Shared::I16: %s", errbuf[0] ? errbuf : "unknown error");
    0          
19 0           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
20             OUTPUT:
21             RETVAL
22              
23              
24             SV*
25             new_memfd(char* class, SV* name_sv, UV max_entries, UV lru_max = 0, UV ttl_default = 0, UV lru_skip = 0)
26             CODE:
27             char errbuf[SHM_ERR_BUFLEN];
28 0 0         const char* name = SvOK(name_sv) ? SvPV_nolen(name_sv) : NULL;
29 0           ShmHandle* map = shm_i16_create_memfd(name, (uint32_t)max_entries, (uint32_t)lru_max, (uint32_t)ttl_default, (uint32_t)lru_skip, errbuf);
30 0 0         if (!map) croak("Data::HashMap::Shared::I16: %s", errbuf[0] ? errbuf : "unknown error");
    0          
31 0           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
32             OUTPUT:
33             RETVAL
34              
35             SV*
36             new_from_fd(char* class, int fd)
37             CODE:
38             char errbuf[SHM_ERR_BUFLEN];
39 0           ShmHandle* map = shm_i16_open_fd(fd, errbuf);
40 0 0         if (!map) croak("Data::HashMap::Shared::I16: %s", errbuf[0] ? errbuf : "unknown error");
    0          
41 0           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
42             OUTPUT:
43             RETVAL
44              
45             IV
46             memfd(SV* self_sv)
47             CODE:
48 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
49 0 0         RETVAL = h->backing_fd;
50             OUTPUT:
51             RETVAL
52              
53              
54             void
55             sync(SV* self_sv)
56             CODE:
57 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
58 0 0         if (shm_msync(h) != 0) croak("Data::HashMap::Shared::I16 sync: %s", strerror(errno));
59              
60             void
61             DESTROY(SV* self_sv)
62             CODE:
63 6 50         if (!SvROK(self_sv)) return;
64 6           ShmHandle* h = INT2PTR(ShmHandle*, SvIV(SvRV(self_sv)));
65 6 50         if (!h) return;
66 6           sv_setiv(SvRV(self_sv), 0);
67 6           shm_close_map(h);
68              
69             bool
70             put(SV* self_sv, int16_t key, int16_t value)
71             CODE:
72 12 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
73 12 50         RETVAL = shm_i16_put(h, key, value);
74             OUTPUT:
75             RETVAL
76              
77             SV*
78             get(SV* self_sv, int16_t key)
79             CODE:
80 11 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
81             int16_t value;
82 11 100         if (!shm_i16_get(h, key, &value)) XSRETURN_UNDEF;
83 10           RETVAL = newSViv(value);
84             OUTPUT:
85             RETVAL
86              
87             bool
88             remove(SV* self_sv, int16_t key)
89             CODE:
90 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
91 1 50         RETVAL = shm_i16_remove(h, key);
92             OUTPUT:
93             RETVAL
94              
95             bool
96             exists(SV* self_sv, int16_t key)
97             CODE:
98 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
99 2 100         RETVAL = shm_i16_exists(h, key);
100             OUTPUT:
101             RETVAL
102              
103             SV*
104             incr(SV* self_sv, int16_t key)
105             CODE:
106 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
107             int ok;
108 2           int16_t val = shm_i16_incr_by(h, key, 1, &ok);
109 2 50         if (!ok) croak("Data::HashMap::Shared::I16: increment failed");
110 2           RETVAL = newSViv(val);
111             OUTPUT:
112             RETVAL
113              
114             SV*
115             decr(SV* self_sv, int16_t key)
116             CODE:
117 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
118             int ok;
119 1           int16_t val = shm_i16_incr_by(h, key, -1, &ok);
120 1 50         if (!ok) croak("Data::HashMap::Shared::I16: decrement failed");
121 1           RETVAL = newSViv(val);
122             OUTPUT:
123             RETVAL
124              
125             SV*
126             incr_by(SV* self_sv, int16_t key, int16_t delta)
127             CODE:
128 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
129             int ok;
130 1           int16_t val = shm_i16_incr_by(h, key, delta, &ok);
131 1 50         if (!ok) croak("Data::HashMap::Shared::I16: incr_by failed");
132 1           RETVAL = newSViv(val);
133             OUTPUT:
134             RETVAL
135              
136             SV*
137             max(SV* self_sv, int16_t key, int16_t desired)
138             CODE:
139 3 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
140             int ok;
141 3           int16_t val = shm_i16_set_minmax(h, key, desired, 1, &ok);
142 3 50         if (!ok) croak("Data::HashMap::Shared::I16: max failed");
143 3           RETVAL = newSViv(val);
144             OUTPUT:
145             RETVAL
146              
147             SV*
148             min(SV* self_sv, int16_t key, int16_t desired)
149             CODE:
150 3 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
151             int ok;
152 3           int16_t val = shm_i16_set_minmax(h, key, desired, 0, &ok);
153 3 50         if (!ok) croak("Data::HashMap::Shared::I16: min failed");
154 3           RETVAL = newSViv(val);
155             OUTPUT:
156             RETVAL
157              
158             UV
159             size(SV* self_sv)
160             CODE:
161 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
162 1 50         RETVAL = (UV)shm_i16_size(h);
163             OUTPUT:
164             RETVAL
165              
166             UV
167             max_entries(SV* self_sv)
168             CODE:
169 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
170 0 0         RETVAL = (UV)shm_i16_max_entries(h);
171             OUTPUT:
172             RETVAL
173              
174             void
175             keys(SV* self_sv)
176             PPCODE:
177 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
178 1 50         uint32_t ns = h->shard_handles ? h->num_shards : 1;
179 2 100         for (uint32_t si = 0; si < ns; si++) {
180 1 50         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
181 1           ShmHeader *hdr = sh->hdr;
182 1           ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
183 1 50         uint32_t now = sh->expires_at ? shm_now() : 0;
184 1           RDLOCK_GUARD(sh);
185 1 50         EXTEND(SP, hdr->size);
186 17 100         for (uint32_t i = 0; i < hdr->table_cap; i++) {
187 16 100         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
    50          
    0          
    0          
188 5 50         mXPUSHi(nodes[i].key);
189             }
190             }
191              
192             void
193             values(SV* self_sv)
194             PPCODE:
195 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
196 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
197 0 0         for (uint32_t si = 0; si < ns; si++) {
198 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
199 0           ShmHeader *hdr = sh->hdr;
200 0           ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
201 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
202 0           RDLOCK_GUARD(sh);
203 0 0         EXTEND(SP, hdr->size);
204 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
205 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
    0          
    0          
    0          
206 0 0         mXPUSHi(nodes[i].value);
207             }
208             }
209              
210              
211             void
212             items(SV* self_sv)
213             PPCODE:
214 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
215 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
216 0 0         for (uint32_t si = 0; si < ns; si++) {
217 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
218 0           ShmHeader *hdr = sh->hdr;
219 0           ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
220 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
221 0           RDLOCK_GUARD(sh);
222 0 0         EXTEND(SP, hdr->size * 2);
223 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
224 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
    0          
    0          
    0          
225 0 0         mXPUSHi(nodes[i].key);
226 0 0         mXPUSHi(nodes[i].value);
227             }
228             }
229             }
230              
231              
232             void
233             each(SV* self_sv)
234             PPCODE:
235 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
236             int16_t out_key, out_value;
237 0 0         if (shm_i16_each(h, &out_key, &out_value)) {
238 0 0         EXTEND(SP, 2);
239 0 0         mXPUSHi(out_key);
240 0 0         mXPUSHi(out_value);
241 0           XSRETURN(2);
242             }
243 0           shm_i16_flush_deferred(h);
244 0           XSRETURN_EMPTY;
245              
246             void
247             iter_reset(SV* self_sv)
248             CODE:
249 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
250 0           shm_i16_iter_reset(h);
251 0           shm_i16_flush_deferred(h);
252              
253             void
254             clear(SV* self_sv)
255             CODE:
256 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
257 1           shm_i16_clear(h);
258              
259             SV*
260             to_hash(SV* self_sv)
261             CODE:
262 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
263 1           HV* hv = newHV();
264 1 50         uint32_t ns = h->shard_handles ? h->num_shards : 1;
265 2 100         for (uint32_t si = 0; si < ns; si++) {
266 1 50         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
267 1           ShmHeader *hdr = sh->hdr;
268 1           ShmNodeI16 *nodes = (ShmNodeI16 *)sh->nodes;
269 1 50         uint32_t now = sh->expires_at ? shm_now() : 0;
270 1           RDLOCK_GUARD(sh);
271 17 100         for (uint32_t i = 0; i < hdr->table_cap; i++) {
272 16 100         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
    50          
    0          
    0          
273 5           SV* val = newSViv(nodes[i].value);
274             char kbuf[24];
275 5           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)nodes[i].key);
276 5 50         if (!hv_store(hv, kbuf, klen, val, 0)) SvREFCNT_dec(val);
277             }
278             }
279             }
280              
281 1           RETVAL = newRV_noinc((SV*)hv);
282             OUTPUT:
283             RETVAL
284              
285             SV*
286             get_or_set(SV* self_sv, int16_t key, int16_t default_value)
287             CODE:
288 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
289             int16_t out;
290 2           int rc = shm_i16_get_or_set(h, key, default_value, &out);
291 2 50         if (!rc) XSRETURN_UNDEF;
292 2           RETVAL = newSViv(out);
293             OUTPUT:
294             RETVAL
295              
296             bool
297             put_ttl(SV* self_sv, int16_t key, int16_t value, UV ttl_sec)
298             CODE:
299 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
300 0 0         REQUIRE_TTL(h);
    0          
301 0 0         RETVAL = shm_i16_put_ttl(h, key, value, (uint32_t)ttl_sec);
302             OUTPUT:
303             RETVAL
304              
305             UV
306             max_size(SV* self_sv)
307             CODE:
308 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
309 0 0         RETVAL = (UV)shm_i16_max_size(h);
310             OUTPUT:
311             RETVAL
312              
313             UV
314             ttl(SV* self_sv)
315             CODE:
316 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
317 0 0         RETVAL = (UV)shm_i16_ttl(h);
318             OUTPUT:
319             RETVAL
320              
321             SV*
322             take(SV* self_sv, int16_t key)
323             CODE:
324 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
325             int16_t out_value;
326 0 0         if (!shm_i16_take(h, key, &out_value)) XSRETURN_UNDEF;
327 0           RETVAL = newSViv(out_value);
328             OUTPUT:
329             RETVAL
330              
331             void
332             pop(SV* self_sv)
333             PPCODE:
334 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
335             int16_t out_key;
336             int16_t out_val;
337 0 0         if (!shm_i16_pop(h, &out_key, &out_val)) XSRETURN_EMPTY;
338 0 0         EXTEND(SP, 2);
339 0           mPUSHi(out_key);
340 0           mPUSHi(out_val);
341              
342             void
343             shift(SV* self_sv)
344             PPCODE:
345 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
346             int16_t out_key;
347             int16_t out_val;
348 0 0         if (!shm_i16_shift(h, &out_key, &out_val)) XSRETURN_EMPTY;
349 0 0         EXTEND(SP, 2);
350 0           mPUSHi(out_key);
351 0           mPUSHi(out_val);
352              
353             void
354             drain(SV* self_sv, UV limit)
355             PPCODE:
356 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
357 0 0         if (limit == 0) XSRETURN_EMPTY;
358             shm_i16_drain_entry *entries;
359 0 0         Newxz(entries, limit, shm_i16_drain_entry);
360              
361 0           SAVEFREEPV(entries);
362 0           char *buf = NULL; uint32_t buf_cap = 0;
363 0           uint32_t n = shm_i16_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
364 0 0         if (buf) SAVEDESTRUCTOR_X(shm_free_cleanup, buf);
365              
366 0 0         EXTEND(SP, n * 2);
367 0 0         for (uint32_t i = 0; i < n; i++) {
368 0           mPUSHi(entries[i].key);
369 0           mPUSHi(entries[i].value);
370             }
371              
372              
373             UV
374             flush_expired(SV* self_sv)
375             CODE:
376 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
377 0 0         RETVAL = (UV)shm_i16_flush_expired(h);
378             OUTPUT:
379             RETVAL
380              
381             void
382             flush_expired_partial(SV* self_sv, UV limit)
383             PPCODE:
384 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
385 0           int done = 0;
386 0           uint32_t flushed = shm_i16_flush_expired_partial(h, (uint32_t)limit, &done);
387 0 0         EXTEND(SP, 2);
388 0           mPUSHu(flushed);
389 0           mPUSHi(done);
390              
391             UV
392             mmap_size(SV* self_sv)
393             CODE:
394 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
395 0           RETVAL = (UV)shm_i16_mmap_size(h);
396             OUTPUT:
397             RETVAL
398              
399             bool
400             touch(SV* self_sv, int16_t key)
401             CODE:
402 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
403 0 0         RETVAL = shm_i16_touch(h, key);
404             OUTPUT:
405             RETVAL
406              
407             bool
408             reserve(SV* self_sv, UV target)
409             CODE:
410 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
411 0 0         RETVAL = shm_i16_reserve(h, (uint32_t)target);
412             OUTPUT:
413             RETVAL
414              
415             UV
416             stat_evictions(SV* self_sv)
417             CODE:
418 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
419 0           RETVAL = (UV)shm_i16_stat_evictions(h);
420             OUTPUT:
421             RETVAL
422              
423             UV
424             stat_expired(SV* self_sv)
425             CODE:
426 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
427 0           RETVAL = (UV)shm_i16_stat_expired(h);
428             OUTPUT:
429             RETVAL
430              
431             UV
432             stat_recoveries(SV* self_sv)
433             CODE:
434 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
435 0 0         RETVAL = (UV)shm_i16_stat_recoveries(h);
436             OUTPUT:
437             RETVAL
438              
439             UV
440             arena_used(SV* self_sv)
441             CODE:
442 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
443 0           RETVAL = (UV)shm_i16_arena_used(h);
444             OUTPUT:
445             RETVAL
446              
447             UV
448             arena_cap(SV* self_sv)
449             CODE:
450 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
451 0           RETVAL = (UV)shm_i16_arena_cap(h);
452             OUTPUT:
453             RETVAL
454              
455             bool
456             add(SV* self_sv, int16_t key, int16_t value)
457             CODE:
458 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
459 2 100         RETVAL = shm_i16_add(h, key, value);
460             OUTPUT:
461             RETVAL
462              
463             bool
464             add_ttl(SV* self_sv, int16_t key, int16_t value, UV ttl_sec)
465             CODE:
466 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
467 2 50         REQUIRE_TTL(h);
    50          
468 2 100         RETVAL = shm_i16_add_ttl(h, key, value, (uint32_t)ttl_sec);
469             OUTPUT:
470             RETVAL
471              
472             bool
473             update(SV* self_sv, int16_t key, int16_t value)
474             CODE:
475 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
476 2 100         RETVAL = shm_i16_update(h, key, value);
477             OUTPUT:
478             RETVAL
479              
480             bool
481             update_ttl(SV* self_sv, int16_t key, int16_t value, UV ttl_sec)
482             CODE:
483 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
484 0 0         REQUIRE_TTL(h);
    0          
485 0 0         RETVAL = shm_i16_update_ttl(h, key, value, (uint32_t)ttl_sec);
486             OUTPUT:
487             RETVAL
488              
489             SV*
490             swap(SV* self_sv, int16_t key, int16_t value)
491             CODE:
492 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
493             int16_t out_value;
494 2           int rc = shm_i16_swap(h, key, value, &out_value);
495 2 100         if (rc != 1) XSRETURN_UNDEF;
496 1           RETVAL = newSViv(out_value);
497             OUTPUT:
498             RETVAL
499              
500             bool
501             cas(SV* self_sv, int16_t key, int16_t expected, int16_t desired)
502             CODE:
503 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
504 2 100         RETVAL = shm_i16_cas(h, key, expected, desired);
505             OUTPUT:
506             RETVAL
507              
508             SV*
509             cas_take(SV* self_sv, int16_t key, int16_t expected)
510             CODE:
511 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
512             int16_t out_value;
513 0 0         if (!shm_i16_cas_take(h, key, expected, &out_value)) XSRETURN_UNDEF;
514 0           RETVAL = newSViv(out_value);
515             OUTPUT:
516             RETVAL
517              
518             bool
519             persist(SV* self_sv, int16_t key)
520             CODE:
521 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
522 1 50         RETVAL = shm_i16_persist(h, key);
523             OUTPUT:
524             RETVAL
525              
526             bool
527             set_ttl(SV* self_sv, int16_t key, UV ttl_sec)
528             CODE:
529 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
530 1 50         RETVAL = shm_i16_set_ttl(h, key, (uint32_t)ttl_sec);
531             OUTPUT:
532             RETVAL
533              
534             void
535             get_multi(SV* self_sv, ...)
536             PPCODE:
537 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
538 0           int nkeys = items - 1;
539 0 0         if (nkeys == 0) XSRETURN_EMPTY;
540 0 0         EXTEND(SP, nkeys);
    0          
541 0 0         if (h->shard_handles) {
542 0 0         for (int i = 0; i < nkeys; i++) {
543 0           int16_t key = (int16_t)SvIV(ST(i + 1));
544             int16_t val;
545 0 0         if (shm_i16_get(h, key, &val))
546 0           mPUSHi(val);
547             else
548 0           PUSHs(&PL_sv_undef);
549             }
550             } else {
551 0           ShmHeader *hdr = h->hdr;
552 0           ShmNodeI16 *nodes = (ShmNodeI16 *)h->nodes;
553 0           uint8_t *states = h->states;
554 0 0         uint32_t now = h->expires_at ? shm_now() : 0;
555             /* Phase 1: compute hashes and prefetch first probe positions */
556 0           uint32_t *hashes = NULL;
557 0           Newx(hashes, nkeys, uint32_t);
558 0           SAVEFREEPV(hashes);
559 0           RDLOCK_GUARD(h);
560 0           uint32_t mask = hdr->table_cap - 1;
561 0 0         for (int i = 0; i < nkeys; i++) {
562 0           hashes[i] = shm_hash_int64((int64_t)(int16_t)SvIV(ST(i + 1)));
563 0           __builtin_prefetch(&states[hashes[i] & mask], 0, 0);
564 0           __builtin_prefetch(&nodes[hashes[i] & mask], 0, 0);
565             }
566             /* Phase 2: probe each key */
567 0 0         for (int i = 0; i < nkeys; i++) {
568 0           int16_t key = (int16_t)SvIV(ST(i + 1));
569 0           uint32_t hash = hashes[i];
570 0           uint32_t pos = hash & mask;
571 0           uint8_t tag = SHM_MAKE_TAG(hash);
572 0           int found = 0;
573 0           int16_t val = 0;
574 0 0         for (uint32_t j = 0; j <= mask; j++) {
575 0           uint32_t idx = (pos + j) & mask;
576 0           uint8_t st = states[idx];
577 0 0         if (st == SHM_EMPTY) break;
578 0 0         if (st != tag) continue;
579 0 0         if (nodes[idx].key == key) {
580 0 0         if (h->expires_at && h->expires_at[idx] && now >= h->expires_at[idx]) break;
    0          
    0          
581 0           val = nodes[idx].value;
582 0           found = 1;
583 0           break;
584             }
585             }
586 0 0         if (found) mPUSHi(val);
587 0           else PUSHs(&PL_sv_undef);
588             /* Prefetch next key's probe position */
589 0 0         if (i + 1 < nkeys) {
590 0           uint32_t npos = hashes[i + 1] & mask;
591 0           __builtin_prefetch(&states[npos], 0, 0);
592 0           __builtin_prefetch(&nodes[npos], 0, 0);
593             }
594             }
595             }
596              
597             void
598             get_with_ttl(SV* self_sv, int16_t key)
599             PPCODE:
600 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
601             int16_t out_value;
602             int64_t out_ttl;
603 0 0         if (!shm_i16_get_with_ttl(h, key, &out_value, &out_ttl)) XSRETURN_EMPTY;
604 0 0         EXTEND(SP, 2);
605 0           mPUSHi(out_value);
606 0 0         if (out_ttl < 0) PUSHs(&PL_sv_undef);
607 0           else mPUSHi(out_ttl);
608              
609             SV*
610             stats(SV* self_sv)
611             CODE:
612 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
613 0           HV *hv = newHV();
614 0           hv_store(hv, "size", 4, newSVuv(shm_i16_size(h)), 0);
615 0           hv_store(hv, "capacity", 8, newSVuv(shm_i16_capacity(h)), 0);
616 0           hv_store(hv, "max_entries", 11, newSVuv(shm_i16_max_entries(h)), 0);
617 0           hv_store(hv, "tombstones", 10, newSVuv(shm_i16_tombstones(h)), 0);
618 0           hv_store(hv, "mmap_size", 9, newSVuv(shm_i16_mmap_size(h)), 0);
619 0           hv_store(hv, "arena_used", 10, newSVuv(shm_i16_arena_used(h)), 0);
620 0           hv_store(hv, "arena_cap", 9, newSVuv(shm_i16_arena_cap(h)), 0);
621 0           hv_store(hv, "evictions", 9, newSVuv(shm_i16_stat_evictions(h)), 0);
622 0           hv_store(hv, "expired", 7, newSVuv(shm_i16_stat_expired(h)), 0);
623 0           hv_store(hv, "recoveries", 10, newSVuv(shm_i16_stat_recoveries(h)), 0);
624 0           hv_store(hv, "max_size", 8, newSVuv(shm_i16_max_size(h)), 0);
625 0           hv_store(hv, "ttl", 3, newSVuv(shm_i16_ttl(h)), 0);
626 0           RETVAL = newRV_noinc((SV*)hv);
627             OUTPUT:
628             RETVAL
629              
630             UV
631             set_multi(SV* self_sv, ...)
632             CODE:
633 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
634 0 0         if ((items - 1) % 2 != 0) croak("set_multi requires even number of arguments (key, value pairs)");
635 0           uint32_t count = 0;
636 0 0         if (h->shard_handles) {
637 0 0         for (int i = 1; i < items; i += 2)
638 0           count += shm_i16_put(h, (int16_t)SvIV(ST(i)), (int16_t)SvIV(ST(i + 1)));
639             } else {
640 0           WRSEQ_GUARD(h);
641 0 0         for (int i = 1; i < items; i += 2)
642 0           count += shm_i16_put_inner(h, (int16_t)SvIV(ST(i)), (int16_t)SvIV(ST(i + 1)), SHM_TTL_USE_DEFAULT);
643             }
644 0 0         RETVAL = count;
645             OUTPUT:
646             RETVAL
647              
648             UV
649             remove_multi(SV* self_sv, ...)
650             CODE:
651 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
652 0           uint32_t count = 0;
653 0 0         if (h->shard_handles) {
654 0 0         for (int i = 1; i < items; i++)
655 0           count += shm_i16_remove(h, (int16_t)SvIV(ST(i)));
656             } else {
657 0           WRSEQ_GUARD(h);
658 0 0         for (int i = 1; i < items; i++)
659 0           count += shm_i16_remove_inner(h, (int16_t)SvIV(ST(i)));
660 0 0         if (count) shm_i16_maybe_shrink(h);
661             }
662 0 0         RETVAL = count;
663             OUTPUT:
664             RETVAL
665              
666             SV*
667             path(SV* self_sv)
668             CODE:
669 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
670 0 0         RETVAL = h->path ? newSVpv(h->path, 0) : &PL_sv_undef;
671             OUTPUT:
672             RETVAL
673              
674             bool
675             unlink(SV* self_or_class, ...)
676             CODE:
677 0 0         if (SvROK(self_or_class) && SvOBJECT(SvRV(self_or_class))) {
    0          
678 0           ShmHandle* h = INT2PTR(ShmHandle*, SvIV(SvRV(self_or_class)));
679 0 0         if (!h) croak("Attempted to use a destroyed Data::HashMap::Shared::I16 object");
680 0           RETVAL = shm_unlink_sharded(h);
681             } else {
682 0 0         if (items < 2) croak("Usage: Data::HashMap::Shared::I16->unlink($path)");
683 0           RETVAL = shm_unlink_path(SvPV_nolen(ST(1)));
684             }
685             OUTPUT:
686             RETVAL
687              
688             SV*
689             ttl_remaining(SV* self_sv, int16_t key)
690             CODE:
691 4 50         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    50          
    50          
692 4           int64_t remaining = shm_i16_ttl_remaining(h, key);
693 4 50         if (remaining < 0) XSRETURN_UNDEF;
694 4           RETVAL = newSViv(remaining);
695             OUTPUT:
696             RETVAL
697              
698             UV
699             capacity(SV* self_sv)
700             CODE:
701 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
702 0 0         RETVAL = (UV)shm_i16_capacity(h);
703             OUTPUT:
704             RETVAL
705              
706             UV
707             tombstones(SV* self_sv)
708             CODE:
709 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
710 0 0         RETVAL = (UV)shm_i16_tombstones(h);
711             OUTPUT:
712             RETVAL
713              
714             SV*
715             cursor(SV* self_sv)
716             CODE:
717 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16", self_sv);
    0          
    0          
718 0           ShmCursor* c = shm_cursor_create(h);
719 0 0         if (!c) croak("Failed to allocate cursor");
720 0           RETVAL = sv_setref_pv(newSV(0), "Data::HashMap::Shared::I16::Cursor", (void*)c);
721             OUTPUT:
722             RETVAL
723              
724             MODULE = Data::HashMap::Shared PACKAGE = Data::HashMap::Shared::I16::Cursor
725             PROTOTYPES: DISABLE
726              
727             void
728             DESTROY(SV* self_sv)
729             CODE:
730 0 0         if (!SvROK(self_sv)) return;
731 0           ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
732 0 0         if (!c) return;
733 0           ShmHandle* h = c->current;
734 0           shm_cursor_destroy(c);
735 0 0         if (h) shm_i16_flush_deferred(h);
736 0           sv_setiv(SvRV(self_sv), 0);
737              
738             void
739             next(SV* self_sv)
740             PPCODE:
741 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I16::Cursor", self_sv);
    0          
    0          
742             int16_t out_key, out_value;
743 0 0         if (shm_i16_cursor_next(c, &out_key, &out_value)) {
744 0 0         EXTEND(SP, 2);
745 0 0         mXPUSHi(out_key);
746 0 0         mXPUSHi(out_value);
747 0           XSRETURN(2);
748             }
749 0           XSRETURN_EMPTY;
750              
751             void
752             reset(SV* self_sv)
753             CODE:
754 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I16::Cursor", self_sv);
    0          
    0          
755 0           shm_i16_cursor_reset(c);
756              
757             bool
758             seek(SV* self_sv, int16_t key)
759             CODE:
760 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I16::Cursor", self_sv);
    0          
    0          
761 0 0         RETVAL = shm_i16_cursor_seek(c, key);
762             OUTPUT:
763             RETVAL
764