File Coverage

xs/i32.xs
Criterion Covered Total %
statement 64 328 19.5
branch 83 672 12.3
condition n/a
subroutine n/a
pod n/a
total 147 1000 14.7


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