File Coverage

xs/i16s.xs
Criterion Covered Total %
statement 59 314 18.7
branch 67 580 11.5
condition n/a
subroutine n/a
pod n/a
total 126 894 14.0


line stmt bran cond sub pod time code
1             MODULE = Data::HashMap::Shared PACKAGE = Data::HashMap::Shared::I16S
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 3           char errbuf[SHM_ERR_BUFLEN]; ShmHandle* map = shm_i16s_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::I16S: %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_i16s_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::I16S: %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 3 50         if (!SvROK(self_sv)) return;
26 3           ShmHandle* h = INT2PTR(ShmHandle*, SvIV(SvRV(self_sv)));
27 3 50         if (!h) return;
28 3           shm_close_map(h);
29 3           sv_setiv(SvRV(self_sv), 0);
30              
31             bool
32             put(SV* self_sv, int16_t key, SV* value)
33             CODE:
34 4 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
35 4 50         EXTRACT_STR_VAL(value);
36 4 50         RETVAL = shm_i16s_put(h, key, _vstr, (uint32_t)_vlen, _vutf8);
37             OUTPUT:
38             RETVAL
39              
40             UV
41             set_multi(SV* self_sv, ...)
42             CODE:
43 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", 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 _vl; const char *_vs = SvPV(ST(i+1), _vl);
49 0           bool _vu = SvUTF8(ST(i+1)) ? 1 : 0;
50 0           count += shm_i16s_put(h, (int16_t)SvIV(ST(i)), _vs, (uint32_t)_vl, _vu);
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 _vl; const char *_vs = SvPV(ST(i+1), _vl);
58 0           bool _vu = SvUTF8(ST(i+1)) ? 1 : 0;
59 0 0         if (_vl > SHM_MAX_STR_LEN) { shm_seqlock_write_end(&hdr->seq); shm_rwlock_wrunlock(hdr); croak("value too long"); }
60 0           count += shm_i16s_put_inner(h, (int16_t)SvIV(ST(i)), _vs, (uint32_t)_vl, _vu, 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::I16S", 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           int16_t key = (int16_t)SvIV(ST(i + 1));
79             const char *out_s; uint32_t out_l; bool out_u;
80 0 0         if (shm_i16s_get(h, key, &out_s, &out_l, &out_u)) {
81 0           SV *sv = newSVpvn(out_s, out_l);
82 0 0         if (out_u) SvUTF8_on(sv);
83 0           mPUSHs(sv);
84 0           } else PUSHs(&PL_sv_undef);
85             }
86             } else {
87 0           ShmHeader *hdr = h->hdr;
88 0           ShmNodeI16S *nodes = (ShmNodeI16S *)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             /* Phase 1: compute hashes and prefetch first probe positions */
93 0           uint32_t *hashes = NULL;
94 0           Newx(hashes, nkeys, uint32_t);
95 0           SAVEFREEPV(hashes);
96 0           RDLOCK_GUARD(hdr);
97 0           uint32_t mask = hdr->table_cap - 1;
98 0 0         for (int i = 0; i < nkeys; i++) {
99 0           hashes[i] = shm_hash_int64((int64_t)(int16_t)SvIV(ST(i + 1)));
100 0           __builtin_prefetch(&states[hashes[i] & mask], 0, 0);
101 0           __builtin_prefetch(&nodes[hashes[i] & mask], 0, 0);
102             }
103             /* Phase 2: probe each key */
104 0 0         for (int i = 0; i < nkeys; i++) {
105 0           int16_t key = (int16_t)SvIV(ST(i + 1));
106 0           uint32_t hash = hashes[i];
107 0           uint32_t pos = hash & mask;
108 0           uint8_t tag = SHM_MAKE_TAG(hash);
109 0           int found = 0;
110 0           uint32_t vidx = 0;
111 0 0         for (uint32_t j = 0; j <= mask; j++) {
112 0           uint32_t idx = (pos + j) & mask;
113 0           uint8_t st = states[idx];
114 0 0         if (st == SHM_EMPTY) break;
115 0 0         if (st != tag) continue;
116 0 0         if (nodes[idx].key == key) {
117 0 0         if (h->expires_at && h->expires_at[idx] && now >= h->expires_at[idx]) break;
    0          
    0          
118 0           vidx = idx; found = 1; break;
119             }
120             }
121 0 0         if (found) {
122             char _vib[SHM_INLINE_MAX]; uint32_t vl;
123 0           const char *vp = shm_str_ptr(nodes[vidx].val_off, nodes[vidx].val_len, arena, _vib, &vl);
124 0           SV *sv = newSVpvn(vp, vl);
125 0 0         if (SHM_UNPACK_UTF8(nodes[vidx].val_len)) SvUTF8_on(sv);
126 0           mPUSHs(sv);
127 0           } else PUSHs(&PL_sv_undef);
128             /* Prefetch next key's probe position */
129 0 0         if (i + 1 < nkeys) {
130 0           uint32_t npos = hashes[i + 1] & mask;
131 0           __builtin_prefetch(&states[npos], 0, 0);
132 0           __builtin_prefetch(&nodes[npos], 0, 0);
133             }
134             }
135             }
136              
137             SV*
138             stats(SV* self_sv)
139             CODE:
140 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
141 0           HV *hv = newHV();
142 0           hv_store(hv, "size", 4, newSVuv(shm_i16s_size(h)), 0);
143 0           hv_store(hv, "capacity", 8, newSVuv(shm_i16s_capacity(h)), 0);
144 0           hv_store(hv, "max_entries", 11, newSVuv(shm_i16s_max_entries(h)), 0);
145 0           hv_store(hv, "tombstones", 10, newSVuv(shm_i16s_tombstones(h)), 0);
146 0           hv_store(hv, "mmap_size", 9, newSVuv(shm_i16s_mmap_size(h)), 0);
147 0           hv_store(hv, "arena_used", 10, newSVuv(shm_i16s_arena_used(h)), 0);
148 0           hv_store(hv, "arena_cap", 9, newSVuv(shm_i16s_arena_cap(h)), 0);
149 0           hv_store(hv, "evictions", 9, newSVuv(shm_i16s_stat_evictions(h)), 0);
150 0           hv_store(hv, "expired", 7, newSVuv(shm_i16s_stat_expired(h)), 0);
151 0           hv_store(hv, "recoveries", 10, newSVuv(shm_i16s_stat_recoveries(h)), 0);
152 0           hv_store(hv, "max_size", 8, newSVuv(shm_i16s_max_size(h)), 0);
153 0           hv_store(hv, "ttl", 3, newSVuv(shm_i16s_ttl(h)), 0);
154 0           RETVAL = newRV_noinc((SV*)hv);
155             OUTPUT:
156             RETVAL
157              
158             bool
159             persist(SV* self_sv, int16_t key)
160             CODE:
161 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
162 0 0         RETVAL = shm_i16s_persist(h, key);
163             OUTPUT:
164             RETVAL
165              
166             bool
167             set_ttl(SV* self_sv, int16_t key, UV ttl_sec)
168             CODE:
169 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
170 0 0         RETVAL = shm_i16s_set_ttl(h, key, (uint32_t)ttl_sec);
171             OUTPUT:
172             RETVAL
173              
174             bool
175             put_ttl(SV* self_sv, int16_t key, SV* value, UV ttl_sec)
176             CODE:
177 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
178 0 0         EXTRACT_STR_VAL(value);
179 0 0         REQUIRE_TTL(h);
    0          
180 0 0         RETVAL = shm_i16s_put_ttl(h, key, _vstr, (uint32_t)_vlen, _vutf8, (uint32_t)ttl_sec);
181             OUTPUT:
182             RETVAL
183              
184             UV
185             max_size(SV* self_sv)
186             CODE:
187 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
188 0 0         RETVAL = (UV)shm_i16s_max_size(h);
189             OUTPUT:
190             RETVAL
191              
192             UV
193             ttl(SV* self_sv)
194             CODE:
195 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
196 0 0         RETVAL = (UV)shm_i16s_ttl(h);
197             OUTPUT:
198             RETVAL
199              
200             SV*
201             get(SV* self_sv, int16_t key)
202             CODE:
203 5 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
204             const char* val; uint32_t val_len; bool val_utf8;
205 5 100         if (!shm_i16s_get(h, key, &val, &val_len, &val_utf8)) XSRETURN_UNDEF;
206 4           RETVAL = newSVpvn(val, val_len);
207 4 100         if (val_utf8) SvUTF8_on(RETVAL);
208             OUTPUT:
209             RETVAL
210              
211             bool
212             remove(SV* self_sv, int16_t key)
213             CODE:
214 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
215 1 50         RETVAL = shm_i16s_remove(h, key);
216             OUTPUT:
217             RETVAL
218              
219             bool
220             exists(SV* self_sv, int16_t key)
221             CODE:
222 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
223 1 50         RETVAL = shm_i16s_exists(h, key);
224             OUTPUT:
225             RETVAL
226              
227             UV
228             size(SV* self_sv)
229             CODE:
230 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
231 1 50         RETVAL = (UV)shm_i16s_size(h);
232             OUTPUT:
233             RETVAL
234              
235             UV
236             max_entries(SV* self_sv)
237             CODE:
238 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
239 0 0         RETVAL = (UV)shm_i16s_max_entries(h);
240             OUTPUT:
241             RETVAL
242              
243             void
244             keys(SV* self_sv)
245             PPCODE:
246 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
247 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
248 0 0         for (uint32_t si = 0; si < ns; si++) {
249 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
250 0           ShmHeader *hdr = sh->hdr;
251 0           ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
252 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
253 0           RDLOCK_GUARD(hdr);
254 0 0         EXTEND(SP, hdr->size);
255 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
256 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now))
    0          
    0          
    0          
257 0 0         mXPUSHi(nodes[i].key);
258             }
259             }
260              
261             void
262             values(SV* self_sv)
263             PPCODE:
264 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
265 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
266 0 0         for (uint32_t si = 0; si < ns; si++) {
267 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
268 0           ShmHeader *hdr = sh->hdr;
269 0           ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
270 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
271 0           RDLOCK_GUARD(hdr);
272 0 0         EXTEND(SP, hdr->size);
273 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
274 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
    0          
    0          
    0          
275             char _ib[SHM_INLINE_MAX]; uint32_t vlen;
276 0           const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
277 0           SV* sv = newSVpvn(vp, vlen);
278 0 0         if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
279 0 0         mXPUSHs(sv);
280             }
281             }
282             }
283              
284             void
285             items(SV* self_sv)
286             PPCODE:
287 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
288 0 0         uint32_t ns = h->shard_handles ? h->num_shards : 1;
289 0 0         for (uint32_t si = 0; si < ns; si++) {
290 0 0         ShmHandle *sh = h->shard_handles ? h->shard_handles[si] : h;
291 0           ShmHeader *hdr = sh->hdr;
292 0           ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
293 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
294 0           RDLOCK_GUARD(hdr);
295 0 0         EXTEND(SP, hdr->size * 2);
296 0 0         for (uint32_t i = 0; i < hdr->table_cap; i++) {
297 0 0         if (SHM_IS_LIVE(sh->states[i]) && !SHM_IS_EXPIRED(sh, i, now)) {
    0          
    0          
    0          
298 0 0         mXPUSHi(nodes[i].key);
299             char _ib[SHM_INLINE_MAX]; uint32_t vlen;
300 0           const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
301 0           SV* sv = newSVpvn(vp, vlen);
302 0 0         if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(sv);
303 0 0         mXPUSHs(sv);
304             }
305             }
306             }
307            
308              
309             void
310             each(SV* self_sv)
311             PPCODE:
312 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
313             int16_t out_key;
314             const char *out_val; uint32_t out_vlen; bool out_vutf8;
315 0 0         if (shm_i16s_each(h, &out_key, &out_val, &out_vlen, &out_vutf8)) {
316 0 0         EXTEND(SP, 2);
317 0 0         mXPUSHi(out_key);
318 0           SV* sv = newSVpvn(out_val, out_vlen);
319 0 0         if (out_vutf8) SvUTF8_on(sv);
320 0 0         mXPUSHs(sv);
321 0           XSRETURN(2);
322             }
323 0           shm_i16s_flush_deferred(h);
324 0           XSRETURN_EMPTY;
325              
326             void
327             iter_reset(SV* self_sv)
328             CODE:
329 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
330 0           shm_i16s_iter_reset(h);
331 0           shm_i16s_flush_deferred(h);
332              
333             void
334             clear(SV* self_sv)
335             CODE:
336 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
337 0           shm_i16s_clear(h);
338              
339             SV*
340             to_hash(SV* self_sv)
341             CODE:
342 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
343 0           HV* hv = newHV();
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           ShmNodeI16S *nodes = (ShmNodeI16S *)sh->nodes;
349 0 0         uint32_t now = sh->expires_at ? shm_now() : 0;
350 0           RDLOCK_GUARD(hdr);
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             char _ib[SHM_INLINE_MAX]; uint32_t vlen;
354 0           const char *vp = shm_str_ptr(nodes[i].val_off, nodes[i].val_len, sh->arena, _ib, &vlen);
355 0           SV* val = newSVpvn(vp, vlen);
356 0 0         if (SHM_UNPACK_UTF8(nodes[i].val_len)) SvUTF8_on(val);
357             char kbuf[24];
358 0           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)nodes[i].key);
359 0 0         if (!hv_store(hv, kbuf, klen, val, 0)) SvREFCNT_dec(val);
360             }
361             }
362             }
363            
364 0           RETVAL = newRV_noinc((SV*)hv);
365             OUTPUT:
366             RETVAL
367              
368             SV*
369             get_or_set(SV* self_sv, int16_t key, SV* default_sv)
370             CODE:
371 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
372             const char *out_str; uint32_t out_len; bool out_utf8;
373 2 50         EXTRACT_STR_VAL(default_sv);
374 2           int rc = shm_i16s_get_or_set(h, key, _vstr, (uint32_t)_vlen, _vutf8, &out_str, &out_len, &out_utf8);
375 2 50         if (!rc) XSRETURN_UNDEF;
376 2           RETVAL = newSVpvn(out_str, out_len);
377 2 50         if (out_utf8) SvUTF8_on(RETVAL);
378             OUTPUT:
379             RETVAL
380              
381             SV*
382             ttl_remaining(SV* self_sv, int16_t key)
383             CODE:
384 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
385 0           int64_t remaining = shm_i16s_ttl_remaining(h, key);
386 0 0         if (remaining < 0) XSRETURN_UNDEF;
387 0           RETVAL = newSViv(remaining);
388             OUTPUT:
389             RETVAL
390              
391             UV
392             capacity(SV* self_sv)
393             CODE:
394 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
395 0 0         RETVAL = (UV)shm_i16s_capacity(h);
396             OUTPUT:
397             RETVAL
398              
399             UV
400             tombstones(SV* self_sv)
401             CODE:
402 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
403 0 0         RETVAL = (UV)shm_i16s_tombstones(h);
404             OUTPUT:
405             RETVAL
406              
407             SV*
408             cursor(SV* self_sv)
409             CODE:
410 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
411 1           ShmCursor* c = shm_cursor_create(h);
412 1 50         if (!c) croak("Failed to allocate cursor");
413 1           RETVAL = sv_setref_pv(newSV(0), "Data::HashMap::Shared::I16S::Cursor", (void*)c);
414             OUTPUT:
415             RETVAL
416              
417             SV*
418             take(SV* self_sv, int16_t key)
419             CODE:
420 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
421             const char *out_str; uint32_t out_len; bool out_utf8;
422 0 0         if (!shm_i16s_take(h, key, &out_str, &out_len, &out_utf8)) XSRETURN_UNDEF;
423 0           RETVAL = newSVpvn(out_str, out_len);
424 0 0         if (out_utf8) SvUTF8_on(RETVAL);
425             OUTPUT:
426             RETVAL
427              
428             void
429             pop(SV* self_sv)
430             PPCODE:
431 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
432             int16_t out_key;
433             const char *out_val; uint32_t out_vlen; bool out_vutf8;
434 0 0         if (!shm_i16s_pop(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
435 0 0         EXTEND(SP, 2);
436 0           mPUSHi(out_key);
437 0           SV *vsv = newSVpvn(out_val, out_vlen);
438 0 0         if (out_vutf8) SvUTF8_on(vsv);
439 0           mPUSHs(vsv);
440              
441             void
442             shift(SV* self_sv)
443             PPCODE:
444 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
445             int16_t out_key;
446             const char *out_val; uint32_t out_vlen; bool out_vutf8;
447 0 0         if (!shm_i16s_shift(h, &out_key, &out_val, &out_vlen, &out_vutf8)) XSRETURN_EMPTY;
448 0 0         EXTEND(SP, 2);
449 0           mPUSHi(out_key);
450 0           SV *vsv = newSVpvn(out_val, out_vlen);
451 0 0         if (out_vutf8) SvUTF8_on(vsv);
452 0           mPUSHs(vsv);
453              
454             void
455             drain(SV* self_sv, UV limit)
456             PPCODE:
457 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
458 0 0         if (limit == 0) XSRETURN_EMPTY;
459             shm_i16s_drain_entry *entries;
460 0 0         Newxz(entries, limit, shm_i16s_drain_entry);
461            
462 0           SAVEFREEPV(entries);
463 0           char *buf = NULL; uint32_t buf_cap = 0;
464 0           uint32_t n = shm_i16s_drain(h, (uint32_t)limit, entries, &buf, &buf_cap);
465            
466 0 0         EXTEND(SP, n * 2);
467 0 0         for (uint32_t i = 0; i < n; i++) {
468 0           mPUSHi(entries[i].key);
469 0           SV *vsv = newSVpvn(buf + entries[i].val_off, entries[i].val_len);
470 0 0         if (entries[i].val_utf8) SvUTF8_on(vsv);
471 0           mPUSHs(vsv);
472             }
473 0 0         if (buf) free(buf);
474            
475              
476             UV
477             flush_expired(SV* self_sv)
478             CODE:
479 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
480 0 0         RETVAL = (UV)shm_i16s_flush_expired(h);
481             OUTPUT:
482             RETVAL
483              
484             void
485             flush_expired_partial(SV* self_sv, UV limit)
486             PPCODE:
487 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
488 0           int done = 0;
489 0           uint32_t flushed = shm_i16s_flush_expired_partial(h, (uint32_t)limit, &done);
490 0 0         EXTEND(SP, 2);
491 0           mPUSHu(flushed);
492 0           mPUSHi(done);
493              
494             UV
495             mmap_size(SV* self_sv)
496             CODE:
497 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
498 0           RETVAL = (UV)shm_i16s_mmap_size(h);
499             OUTPUT:
500             RETVAL
501              
502             bool
503             touch(SV* self_sv, int16_t key)
504             CODE:
505 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
506 0 0         RETVAL = shm_i16s_touch(h, key);
507             OUTPUT:
508             RETVAL
509              
510             bool
511             reserve(SV* self_sv, UV target)
512             CODE:
513 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
514 0 0         RETVAL = shm_i16s_reserve(h, (uint32_t)target);
515             OUTPUT:
516             RETVAL
517              
518             UV
519             stat_evictions(SV* self_sv)
520             CODE:
521 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
522 0           RETVAL = (UV)shm_i16s_stat_evictions(h);
523             OUTPUT:
524             RETVAL
525              
526             UV
527             stat_expired(SV* self_sv)
528             CODE:
529 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
530 0           RETVAL = (UV)shm_i16s_stat_expired(h);
531             OUTPUT:
532             RETVAL
533              
534             UV
535             stat_recoveries(SV* self_sv)
536             CODE:
537 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
538 0 0         RETVAL = (UV)shm_i16s_stat_recoveries(h);
539             OUTPUT:
540             RETVAL
541              
542             UV
543             arena_used(SV* self_sv)
544             CODE:
545 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
546 0           RETVAL = (UV)shm_i16s_arena_used(h);
547             OUTPUT:
548             RETVAL
549              
550             UV
551             arena_cap(SV* self_sv)
552             CODE:
553 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
554 0           RETVAL = (UV)shm_i16s_arena_cap(h);
555             OUTPUT:
556             RETVAL
557              
558             bool
559             add(SV* self_sv, int16_t key, SV* val_sv)
560             CODE:
561 2 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
562 2 50         EXTRACT_STR_VAL(val_sv);
563 2 100         RETVAL = shm_i16s_add(h, key, _vstr, (uint32_t)_vlen, _vutf8);
564             OUTPUT:
565             RETVAL
566              
567             bool
568             update(SV* self_sv, int16_t key, SV* val_sv)
569             CODE:
570 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
571 1 50         EXTRACT_STR_VAL(val_sv);
572 1 50         RETVAL = shm_i16s_update(h, key, _vstr, (uint32_t)_vlen, _vutf8);
573             OUTPUT:
574             RETVAL
575              
576             SV*
577             swap(SV* self_sv, int16_t key, SV* val_sv)
578             CODE:
579 1 50         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    50          
    50          
580 1 50         EXTRACT_STR_VAL(val_sv);
581             const char *out_s; uint32_t out_l; bool out_u;
582 1           int rc = shm_i16s_swap(h, key, _vstr, (uint32_t)_vlen, _vutf8, &out_s, &out_l, &out_u);
583 1 50         if (rc != 1) XSRETURN_UNDEF;
584 1           RETVAL = newSVpvn(out_s, out_l);
585 1 50         if (out_u) SvUTF8_on(RETVAL);
586             OUTPUT:
587             RETVAL
588              
589             SV*
590             path(SV* self_sv)
591             CODE:
592 0 0         EXTRACT_MAP("Data::HashMap::Shared::I16S", self_sv);
    0          
    0          
593 0           RETVAL = newSVpv(h->path, 0);
594             OUTPUT:
595             RETVAL
596              
597             bool
598             unlink(SV* self_or_class, ...)
599             CODE:
600             const char *p;
601 0 0         if (SvROK(self_or_class) && SvOBJECT(SvRV(self_or_class))) {
    0          
602 0           ShmHandle* h = INT2PTR(ShmHandle*, SvIV(SvRV(self_or_class)));
603 0 0         if (!h) croak("Attempted to use a destroyed Data::HashMap::Shared::I16S object");
604 0           p = h->path;
605             } else {
606 0 0         if (items < 2) croak("Usage: Data::HashMap::Shared::I16S->unlink($path)");
607 0           p = SvPV_nolen(ST(1));
608             }
609 0 0         RETVAL = (SvROK(self_or_class) && SvOBJECT(SvRV(self_or_class))) ?
    0          
610 0 0         shm_unlink_sharded(INT2PTR(ShmHandle*, SvIV(SvRV(self_or_class)))) :
611 0           shm_unlink_path(p);
612             OUTPUT:
613             RETVAL
614              
615             MODULE = Data::HashMap::Shared PACKAGE = Data::HashMap::Shared::I16S::Cursor
616             PROTOTYPES: DISABLE
617              
618             void
619             DESTROY(SV* self_sv)
620             CODE:
621 1 50         if (!SvROK(self_sv)) return;
622 1           ShmCursor* c = INT2PTR(ShmCursor*, SvIV(SvRV(self_sv)));
623 1 50         if (!c) return;
624 1           ShmHandle* h = c->current;
625 1           shm_cursor_destroy(c);
626 1 50         if (h) shm_i16s_flush_deferred(h);
627 1           sv_setiv(SvRV(self_sv), 0);
628              
629             void
630             next(SV* self_sv)
631             PPCODE:
632 3 50         EXTRACT_CURSOR("Data::HashMap::Shared::I16S::Cursor", self_sv);
    50          
    50          
633             int16_t out_key;
634             const char *out_val; uint32_t out_vlen; bool out_vutf8;
635 3 100         if (shm_i16s_cursor_next(c, &out_key, &out_val, &out_vlen, &out_vutf8)) {
636 2 50         EXTEND(SP, 2);
637 2 50         mXPUSHi(out_key);
638 2           SV* sv = newSVpvn(out_val, out_vlen);
639 2 100         if (out_vutf8) SvUTF8_on(sv);
640 2 50         mXPUSHs(sv);
641 2           XSRETURN(2);
642             }
643 1           XSRETURN_EMPTY;
644              
645             void
646             reset(SV* self_sv)
647             CODE:
648 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I16S::Cursor", self_sv);
    0          
    0          
649 0           shm_i16s_cursor_reset(c);
650              
651             bool
652             seek(SV* self_sv, int16_t key)
653             CODE:
654 0 0         EXTRACT_CURSOR("Data::HashMap::Shared::I16S::Cursor", self_sv);
    0          
    0          
655 0 0         RETVAL = shm_i16s_cursor_seek(c, key);
656             OUTPUT:
657             RETVAL
658