File Coverage

xs/i32.xs
Criterion Covered Total %
statement 53 291 18.2
branch 66 570 11.5
condition n/a
subroutine n/a
pod n/a
total 119 861 13.8


line stmt bran cond sub pod time code
1             MODULE = Data::HashMap::Shared PACKAGE = Data::HashMap::Shared::I32
2             PROTOTYPES: DISABLE
3              
4             SV*
5             new(char* class, char* path, UV max_entries, UV lru_max = 0, UV ttl_default = 0, UV lru_skip = 0)
6             CODE:
7 4           char errbuf[SHM_ERR_BUFLEN]; ShmHandle* map = shm_i32_create(path, (uint32_t)max_entries, (uint32_t)lru_max, (uint32_t)ttl_default, (uint32_t)lru_skip, errbuf);
8 4 50         if (!map) croak("HashMap::Shared::I32: %s", errbuf[0] ? errbuf : "unknown error");
    0          
9 4           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
10             OUTPUT:
11             RETVAL
12              
13             SV*
14             new_sharded(char* class, char* path_prefix, UV num_shards, UV max_entries, UV lru_max = 0, UV ttl_default = 0, UV lru_skip = 0)
15             CODE:
16 0           char errbuf[SHM_ERR_BUFLEN]; ShmHandle* map = shm_i32_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);
17 0 0         if (!map) croak("HashMap::Shared::I32: %s", errbuf[0] ? errbuf : "unknown error");
    0          
18 0           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
19             OUTPUT:
20             RETVAL
21              
22             void
23             DESTROY(SV* self_sv)
24             CODE:
25 4 50         if (!SvROK(self_sv)) return;
26 4           ShmHandle* h = INT2PTR(ShmHandle*, SvIV(SvRV(self_sv)));
27 4 50         if (!h) return;
28 4           shm_close_map(h);
29 4           sv_setiv(SvRV(self_sv), 0);
30              
31             bool
32             put(SV* self_sv, int32_t key, int32_t value)
33             CODE:
34 1014 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
35 1014 50         RETVAL = shm_i32_put(h, key, value);
36             OUTPUT:
37             RETVAL
38              
39             UV
40             set_multi(SV* self_sv, ...)
41             CODE:
42 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
43 0 0         if ((items - 1) % 2 != 0) croak("set_multi requires even number of arguments (key, value pairs)");
44 0           uint32_t count = 0;
45 0 0         if (h->shard_handles) {
46 0 0         for (int i = 1; i < items; i += 2)
47 0           count += shm_i32_put(h, (int32_t)SvIV(ST(i)), (int32_t)SvIV(ST(i + 1)));
48             } else {
49 0           ShmHeader *hdr = h->hdr;
50 0           shm_rwlock_wrlock(hdr);
51 0           shm_seqlock_write_begin(&hdr->seq);
52 0 0         for (int i = 1; i < items; i += 2)
53 0           count += shm_i32_put_inner(h, (int32_t)SvIV(ST(i)), (int32_t)SvIV(ST(i + 1)), SHM_TTL_USE_DEFAULT);
54 0           shm_seqlock_write_end(&hdr->seq);
55 0           shm_rwlock_wrunlock(hdr);
56             }
57 0 0         RETVAL = count;
58             OUTPUT:
59             RETVAL
60              
61             void
62             get_multi(SV* self_sv, ...)
63             PPCODE:
64 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
65 0           int nkeys = items - 1;
66 0 0         if (nkeys == 0) XSRETURN_EMPTY;
67 0 0         EXTEND(SP, nkeys);
    0          
68 0 0         if (h->shard_handles) {
69 0 0         for (int i = 0; i < nkeys; i++) {
70 0           int32_t key = (int32_t)SvIV(ST(i + 1));
71             int32_t val;
72 0 0         if (shm_i32_get(h, key, &val))
73 0           mPUSHi(val);
74             else
75 0           PUSHs(&PL_sv_undef);
76             }
77             } else {
78 0           ShmHeader *hdr = h->hdr;
79 0           ShmNodeI32 *nodes = (ShmNodeI32 *)h->nodes;
80 0           uint8_t *states = h->states;
81 0 0         uint32_t now = h->expires_at ? shm_now() : 0;
82             /* Phase 1: compute hashes and prefetch first probe positions */
83 0           uint32_t *hashes = NULL;
84 0           Newx(hashes, nkeys, uint32_t);
85 0           SAVEFREEPV(hashes);
86 0           RDLOCK_GUARD(hdr);
87 0           uint32_t mask = hdr->table_cap - 1;
88 0 0         for (int i = 0; i < nkeys; i++) {
89 0           hashes[i] = shm_hash_int64((int64_t)(int32_t)SvIV(ST(i + 1)));
90 0           __builtin_prefetch(&states[hashes[i] & mask], 0, 0);
91 0           __builtin_prefetch(&nodes[hashes[i] & mask], 0, 0);
92             }
93             /* Phase 2: probe each key */
94 0 0         for (int i = 0; i < nkeys; i++) {
95 0           int32_t key = (int32_t)SvIV(ST(i + 1));
96 0           uint32_t hash = hashes[i];
97 0           uint32_t pos = hash & mask;
98 0           uint8_t tag = SHM_MAKE_TAG(hash);
99 0           int found = 0;
100 0           int32_t val = 0;
101 0 0         for (uint32_t j = 0; j <= mask; j++) {
102 0           uint32_t idx = (pos + j) & mask;
103 0           uint8_t st = states[idx];
104 0 0         if (st == SHM_EMPTY) break;
105 0 0         if (st != tag) continue;
106 0 0         if (nodes[idx].key == key) {
107 0 0         if (h->expires_at && h->expires_at[idx] && now >= h->expires_at[idx]) break;
    0          
    0          
108 0           val = nodes[idx].value;
109 0           found = 1;
110 0           break;
111             }
112             }
113 0 0         if (found) mPUSHi(val);
114 0           else PUSHs(&PL_sv_undef);
115             /* Prefetch next key's probe position */
116 0 0         if (i + 1 < nkeys) {
117 0           uint32_t npos = hashes[i + 1] & mask;
118 0           __builtin_prefetch(&states[npos], 0, 0);
119 0           __builtin_prefetch(&nodes[npos], 0, 0);
120             }
121             }
122             }
123              
124             SV*
125             stats(SV* self_sv)
126             CODE:
127 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
128 0           HV *hv = newHV();
129 0           hv_store(hv, "size", 4, newSVuv(shm_i32_size(h)), 0);
130 0           hv_store(hv, "capacity", 8, newSVuv(shm_i32_capacity(h)), 0);
131 0           hv_store(hv, "max_entries", 11, newSVuv(shm_i32_max_entries(h)), 0);
132 0           hv_store(hv, "tombstones", 10, newSVuv(shm_i32_tombstones(h)), 0);
133 0           hv_store(hv, "mmap_size", 9, newSVuv(shm_i32_mmap_size(h)), 0);
134 0           hv_store(hv, "arena_used", 10, newSVuv(shm_i32_arena_used(h)), 0);
135 0           hv_store(hv, "arena_cap", 9, newSVuv(shm_i32_arena_cap(h)), 0);
136 0           hv_store(hv, "evictions", 9, newSVuv(shm_i32_stat_evictions(h)), 0);
137 0           hv_store(hv, "expired", 7, newSVuv(shm_i32_stat_expired(h)), 0);
138 0           hv_store(hv, "recoveries", 10, newSVuv(shm_i32_stat_recoveries(h)), 0);
139 0           hv_store(hv, "max_size", 8, newSVuv(shm_i32_max_size(h)), 0);
140 0           hv_store(hv, "ttl", 3, newSVuv(shm_i32_ttl(h)), 0);
141 0           RETVAL = newRV_noinc((SV*)hv);
142             OUTPUT:
143             RETVAL
144              
145             bool
146             cas(SV* self_sv, int32_t key, int32_t expected, int32_t desired)
147             CODE:
148 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
149 1 50         RETVAL = shm_i32_cas(h, key, expected, desired);
150             OUTPUT:
151             RETVAL
152              
153             bool
154             persist(SV* self_sv, int32_t key)
155             CODE:
156 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
157 0 0         RETVAL = shm_i32_persist(h, key);
158             OUTPUT:
159             RETVAL
160              
161             bool
162             set_ttl(SV* self_sv, int32_t key, UV ttl_sec)
163             CODE:
164 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
165 0 0         RETVAL = shm_i32_set_ttl(h, key, (uint32_t)ttl_sec);
166             OUTPUT:
167             RETVAL
168              
169             SV*
170             get(SV* self_sv, int32_t key)
171             CODE:
172 7 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
173             int32_t value;
174 7 50         if (!shm_i32_get(h, key, &value)) XSRETURN_UNDEF;
175 7           RETVAL = newSViv(value);
176             OUTPUT:
177             RETVAL
178              
179             bool
180             remove(SV* self_sv, int32_t key)
181             CODE:
182 500 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
183 500 50         RETVAL = shm_i32_remove(h, key);
184             OUTPUT:
185             RETVAL
186              
187             bool
188             exists(SV* self_sv, int32_t key)
189             CODE:
190 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
191 0 0         RETVAL = shm_i32_exists(h, key);
192             OUTPUT:
193             RETVAL
194              
195             SV*
196             incr(SV* self_sv, int32_t key)
197             CODE:
198 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
199             int ok;
200 1           int32_t val = shm_i32_incr_by(h, key, 1, &ok);
201 1 50         if (!ok) croak("HashMap::Shared::I32: increment failed");
202 1           RETVAL = newSViv(val);
203             OUTPUT:
204             RETVAL
205              
206             SV*
207             decr(SV* self_sv, int32_t key)
208             CODE:
209 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
210             int ok;
211 0           int32_t val = shm_i32_incr_by(h, key, -1, &ok);
212 0 0         if (!ok) croak("HashMap::Shared::I32: decrement failed");
213 0           RETVAL = newSViv(val);
214             OUTPUT:
215             RETVAL
216              
217             SV*
218             incr_by(SV* self_sv, int32_t key, int32_t delta)
219             CODE:
220 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
221             int ok;
222 1           int32_t val = shm_i32_incr_by(h, key, delta, &ok);
223 1 50         if (!ok) croak("HashMap::Shared::I32: incr_by failed");
224 1           RETVAL = newSViv(val);
225             OUTPUT:
226             RETVAL
227              
228             UV
229             size(SV* self_sv)
230             CODE:
231 2 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
232 2 50         RETVAL = (UV)shm_i32_size(h);
233             OUTPUT:
234             RETVAL
235              
236             UV
237             max_entries(SV* self_sv)
238             CODE:
239 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
240 0 0         RETVAL = (UV)shm_i32_max_entries(h);
241             OUTPUT:
242             RETVAL
243              
244             void
245             keys(SV* self_sv)
246             PPCODE:
247 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
248 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
249 0 0         for (uint32_t si = 0; si < ns; si++) {
250 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
251 0           ShmHeader *hdr = sh->hdr;
252 0           ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
253 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
254 0           RDLOCK_GUARD(hdr);
255 0 0         EXTEND(SP, hdr->size);
256 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
257 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
    0          
    0          
    0          
258 0 0         mXPUSHi(nodes[i].key);
259             }
260             }
261              
262             void
263             values(SV* self_sv)
264             PPCODE:
265 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
266 1 50         uint32_t ns = h->shard_handles ? h->num_shards : 1;
267 2 100         for (uint32_t si = 0; si < ns; si++) {
268 1 50         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
269 1           ShmHeader *hdr = sh->hdr;
270 1           ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
271 1 50         uint32_t now = sh->expires_at ? shm_now() : 0;
272 1           RDLOCK_GUARD(hdr);
273 1 50         EXTEND(SP, hdr->size);
274 17 100         for (uint32_t i = 0; i < hdr->table_cap; i++) {
275 16 100         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
    50          
    0          
    0          
276 10 50         mXPUSHi(nodes[i].value);
277             }
278             }
279              
280             void
281             items(SV* self_sv)
282             PPCODE:
283 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
284 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
285 0 0         for (uint32_t si = 0; si < ns; si++) {
286 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
287 0           ShmHeader *hdr = sh->hdr;
288 0           ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
289 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
290 0           RDLOCK_GUARD(hdr);
291 0 0         EXTEND(SP, hdr->size * 2);
292 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
293 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
    0          
    0          
    0          
294 0 0         mXPUSHi(nodes[i].key);
295 0 0         mXPUSHi(nodes[i].value);
296             }
297             }
298             }
299            
300              
301             void
302             each(SV* self_sv)
303             PPCODE:
304 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
305             int32_t out_key, out_value;
306 0 0         if (shm_i32_each(h, &out_key, &out_value)) {
307 0 0         EXTEND(SP, 2);
308 0 0         mXPUSHi(out_key);
309 0 0         mXPUSHi(out_value);
310 0           XSRETURN(2);
311             }
312 0           shm_i32_flush_deferred(h);
313 0           XSRETURN_EMPTY;
314              
315             void
316             iter_reset(SV* self_sv)
317             CODE:
318 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
319 0           shm_i32_iter_reset(h);
320 0           shm_i32_flush_deferred(h);
321              
322             void
323             clear(SV* self_sv)
324             CODE:
325 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
326 1           shm_i32_clear(h);
327              
328             SV*
329             to_hash(SV* self_sv)
330             CODE:
331 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
332 0           HV* hv = newHV();
333 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
334 0 0         for (uint32_t si = 0; si < ns; si++) {
335 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
336 0           ShmHeader *hdr = sh->hdr;
337 0           ShmNodeI32 *nodes = (ShmNodeI32 *)sh->nodes;
338 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
339 0           RDLOCK_GUARD(hdr);
340 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
341 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
    0          
    0          
    0          
342 0           SV* val = newSViv(nodes[i].value);
343             char kbuf[24];
344 0           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)nodes[i].key);
345 0 0         if (!hv_store(hv, kbuf, klen, val, 0)) SvREFCNT_dec(val);
346             }
347             }
348             }
349            
350 0           RETVAL = newRV_noinc((SV*)hv);
351             OUTPUT:
352             RETVAL
353              
354             SV*
355             get_or_set(SV* self_sv, int32_t key, int32_t default_value)
356             CODE:
357 2 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
358             int32_t out;
359 2           int rc = shm_i32_get_or_set(h, key, default_value, &out);
360 2 50         if (!rc) XSRETURN_UNDEF;
361 2           RETVAL = newSViv(out);
362             OUTPUT:
363             RETVAL
364              
365             bool
366             put_ttl(SV* self_sv, int32_t key, int32_t value, UV ttl_sec)
367             CODE:
368 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
369 0 0         REQUIRE_TTL(h);
    0          
370 0 0         RETVAL = shm_i32_put_ttl(h, key, value, (uint32_t)ttl_sec);
371             OUTPUT:
372             RETVAL
373              
374             UV
375             max_size(SV* self_sv)
376             CODE:
377 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
378 0 0         RETVAL = (UV)shm_i32_max_size(h);
379             OUTPUT:
380             RETVAL
381              
382             UV
383             ttl(SV* self_sv)
384             CODE:
385 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
386 0 0         RETVAL = (UV)shm_i32_ttl(h);
387             OUTPUT:
388             RETVAL
389              
390             SV*
391             take(SV* self_sv, int32_t key)
392             CODE:
393 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
394             int32_t out_value;
395 0 0         if (!shm_i32_take(h, key, &out_value)) XSRETURN_UNDEF;
396 0           RETVAL = newSViv(out_value);
397             OUTPUT:
398             RETVAL
399              
400             void
401             pop(SV* self_sv)
402             PPCODE:
403 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
404             int32_t out_key;
405             int32_t out_val;
406 0 0         if (!shm_i32_pop(h, &out_key, &out_val)) XSRETURN_EMPTY;
407 0 0         EXTEND(SP, 2);
408 0           mPUSHi(out_key);
409 0           mPUSHi(out_val);
410              
411             void
412             shift(SV* self_sv)
413             PPCODE:
414 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
415             int32_t out_key;
416             int32_t out_val;
417 0 0         if (!shm_i32_shift(h, &out_key, &out_val)) XSRETURN_EMPTY;
418 0 0         EXTEND(SP, 2);
419 0           mPUSHi(out_key);
420 0           mPUSHi(out_val);
421              
422             void
423             drain(SV* self_sv, UV limit)
424             PPCODE:
425 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
426 0 0         if (limit == 0) XSRETURN_EMPTY;
427 0           shm_i32_drain_entry *entries = (shm_i32_drain_entry *)calloc(limit, sizeof(shm_i32_drain_entry));
428 0 0         if (!entries) croak("drain: out of memory");
429 0           SAVEFREEPV(entries);
430 0           char *buf = NULL; uint32_t buf_cap = 0;
431 0           uint32_t n = shm_i32_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
432 0 0         if (buf) SAVEFREEPV(buf);
433 0 0         EXTEND(SP, n * 2);
434 0 0         for (uint32_t i = 0; i < n; i++) {
435 0           mPUSHi(entries[i].key);
436 0           mPUSHi(entries[i].value);
437             }
438            
439              
440             UV
441             flush_expired(SV* self_sv)
442             CODE:
443 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
444 0 0         RETVAL = (UV)shm_i32_flush_expired(h);
445             OUTPUT:
446             RETVAL
447              
448             void
449             flush_expired_partial(SV* self_sv, UV limit)
450             PPCODE:
451 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
452 0           int done = 0;
453 0           uint32_t flushed = shm_i32_flush_expired_partial(h, (uint32_t)limit, &done);
454 0 0         EXTEND(SP, 2);
455 0           mPUSHu(flushed);
456 0           mPUSHi(done);
457              
458             UV
459             mmap_size(SV* self_sv)
460             CODE:
461 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
462 0           RETVAL = (UV)shm_i32_mmap_size(h);
463             OUTPUT:
464             RETVAL
465              
466             bool
467             touch(SV* self_sv, int32_t key)
468             CODE:
469 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
470 0 0         RETVAL = shm_i32_touch(h, key);
471             OUTPUT:
472             RETVAL
473              
474             bool
475             reserve(SV* self_sv, UV target)
476             CODE:
477 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
478 0 0         RETVAL = shm_i32_reserve(h, (uint32_t)target);
479             OUTPUT:
480             RETVAL
481              
482             UV
483             stat_evictions(SV* self_sv)
484             CODE:
485 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
486 0           RETVAL = (UV)shm_i32_stat_evictions(h);
487             OUTPUT:
488             RETVAL
489              
490             UV
491             stat_expired(SV* self_sv)
492             CODE:
493 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
494 0           RETVAL = (UV)shm_i32_stat_expired(h);
495             OUTPUT:
496             RETVAL
497              
498             UV
499             stat_recoveries(SV* self_sv)
500             CODE:
501 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
502 0 0         RETVAL = (UV)shm_i32_stat_recoveries(h);
503             OUTPUT:
504             RETVAL
505              
506             UV
507             arena_used(SV* self_sv)
508             CODE:
509 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
510 0           RETVAL = (UV)shm_i32_arena_used(h);
511             OUTPUT:
512             RETVAL
513              
514             UV
515             arena_cap(SV* self_sv)
516             CODE:
517 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
518 0           RETVAL = (UV)shm_i32_arena_cap(h);
519             OUTPUT:
520             RETVAL
521              
522             bool
523             add(SV* self_sv, int32_t key, int32_t value)
524             CODE:
525 2 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
526 2 100         RETVAL = shm_i32_add(h, key, value);
527             OUTPUT:
528             RETVAL
529              
530             bool
531             update(SV* self_sv, int32_t key, int32_t value)
532             CODE:
533 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
534 1 50         RETVAL = shm_i32_update(h, key, value);
535             OUTPUT:
536             RETVAL
537              
538             SV*
539             swap(SV* self_sv, int32_t key, int32_t value)
540             CODE:
541 1 50         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    50          
    50          
542             int32_t out_value;
543 1           int rc = shm_i32_swap(h, key, value, &out_value);
544 1 50         if (rc != 1) XSRETURN_UNDEF;
545 1           RETVAL = newSViv(out_value);
546             OUTPUT:
547             RETVAL
548              
549             SV*
550             path(SV* self_sv)
551             CODE:
552 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
553 0           RETVAL = newSVpv(h->path, 0);
554             OUTPUT:
555             RETVAL
556              
557             bool
558             unlink(SV* self_or_class, ...)
559             CODE:
560             const char *p;
561 0 0         if (SvROK(self_or_class) && SvOBJECT(SvRV(self_or_class))) {
    0          
562 0           ShmHandle* h = INT2PTR(ShmHandle*, SvIV(SvRV(self_or_class)));
563 0 0         if (!h) croak("Attempted to use a destroyed Data::HashMap::Shared::I32 object");
564 0           p = h->path;
565             } else {
566 0 0         if (items < 2) croak("Usage: Data::HashMap::Shared::I32->unlink($path)");
567 0           p = SvPV_nolen(ST(1));
568             }
569 0 0         RETVAL = (SvROK(self_or_class) && SvOBJECT(SvRV(self_or_class))) ?
    0          
570 0 0         shm_unlink_sharded(INT2PTR(ShmHandle*, SvIV(SvRV(self_or_class)))) :
571 0           shm_unlink_path(p);
572             OUTPUT:
573             RETVAL
574              
575             SV*
576             ttl_remaining(SV* self_sv, int32_t key)
577             CODE:
578 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
579 0           int64_t remaining = shm_i32_ttl_remaining(h, key);
580 0 0         if (remaining < 0) XSRETURN_UNDEF;
581 0           RETVAL = newSViv(remaining);
582             OUTPUT:
583             RETVAL
584              
585             UV
586             capacity(SV* self_sv)
587             CODE:
588 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
589 0 0         RETVAL = (UV)shm_i32_capacity(h);
590             OUTPUT:
591             RETVAL
592              
593             UV
594             tombstones(SV* self_sv)
595             CODE:
596 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
597 0 0         RETVAL = (UV)shm_i32_tombstones(h);
598             OUTPUT:
599             RETVAL
600              
601             SV*
602             cursor(SV* self_sv)
603             CODE:
604 0 0         EXTRACT_MAP("Data::HashMap::Shared::I32", self_sv);
    0          
    0          
605 0           ShmCursor* c = shm_cursor_create(h);
606 0 0         if (!c) croak("Failed to allocate cursor");
607 0           RETVAL = sv_setref_pv(newSV(0), "Data::HashMap::Shared::I32::Cursor", (void*)c);
608             OUTPUT:
609             RETVAL
610              
611             MODULE = Data::HashMap::Shared PACKAGE = Data::HashMap::Shared::I32::Cursor
612             PROTOTYPES: DISABLE
613              
614             void
615             DESTROY(SV* self_sv)
616             CODE:
617 0 0         if (!SvROK(self_sv)) return;
618 0           ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
619 0 0         if (!c) return;
620 0           ShmHandle* h = c->current;
621 0           shm_cursor_destroy(c);
622 0 0         if (h) shm_i32_flush_deferred(h);
623 0           sv_setiv(SvRV(self_sv), 0);
624              
625             void
626             next(SV* self_sv)
627             PPCODE:
628 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I32::Cursor", self_sv);
    0          
    0          
629             int32_t out_key; int32_t out_value;
630 0 0         if (shm_i32_cursor_next(c, &out_key, &out_value)) {
631 0 0         EXTEND(SP, 2);
632 0 0         mXPUSHi(out_key);
633 0 0         mXPUSHi(out_value);
634 0           XSRETURN(2);
635             }
636 0           XSRETURN_EMPTY;
637              
638             void
639             reset(SV* self_sv)
640             CODE:
641 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I32::Cursor", self_sv);
    0          
    0          
642 0           shm_i32_cursor_reset(c);
643              
644             bool
645             seek(SV* self_sv, int32_t key)
646             CODE:
647 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I32::Cursor", self_sv);
    0          
    0          
648 0 0         RETVAL = shm_i32_cursor_seek(c, key);
649             OUTPUT:
650             RETVAL
651