File Coverage

xs/si16.xs
Criterion Covered Total %
statement 61 327 18.6
branch 74 624 11.8
condition n/a
subroutine n/a
pod n/a
total 135 951 14.2


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