File Coverage

xs/si32.xs
Criterion Covered Total %
statement 81 338 23.9
branch 91 654 13.9
condition n/a
subroutine n/a
pod n/a
total 172 992 17.3


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