File Coverage

HashMap.xs
Criterion Covered Total %
statement 1421 1612 88.1
branch 1562 3386 46.1
condition n/a
subroutine n/a
pod n/a
total 2983 4998 59.6


line stmt bran cond sub pod time code
1             #define PERL_NO_GET_CONTEXT
2             #include "EXTERN.h"
3             #include "perl.h"
4             #include "XSUB.h"
5              
6             #include "ppport.h"
7              
8             #include "hashmap_i16.h"
9             #include "hashmap_i16s.h"
10             #include "hashmap_si16.h"
11             #include "hashmap_i32.h"
12             #include "hashmap_ii.h"
13             #include "hashmap_is.h"
14             #include "hashmap_si.h"
15             #include "hashmap_ss.h"
16             #include "hashmap_i32s.h"
17             #include "hashmap_si32.h"
18             #include "hashmap_i32a.h"
19             #include "hashmap_i16a.h"
20             #include "hashmap_ia.h"
21             #include "hashmap_sa.h"
22              
23             #include "XSParseKeyword.h"
24              
25             /* ---- Helper macros ---- */
26              
27             #define EXTRACT_MAP(type, classname, sv) \
28             if (!sv_isobject(sv) || !sv_derived_from(sv, classname)) \
29             croak("Expected a %s object", classname); \
30             type* self = INT2PTR(type*, SvIV(SvRV(sv))); \
31             if (!self) croak("Attempted to use a destroyed %s object", classname)
32              
33             #define HM_MAX_STR_LEN 0x7FFFFFFFU
34              
35             /* SV* value free callback for IA/SA variants */
36 97           static void hm_sv_free(void* sv) {
37             dTHX;
38 97           SvREFCNT_dec((SV*)sv);
39 97           }
40              
41             #define EXTRACT_STR_KEY(sv) \
42             STRLEN _klen; \
43             const char* _kstr = SvPV(sv, _klen); \
44             if (_klen > HM_MAX_STR_LEN) croak("key too long (max 2GB)"); \
45             bool _kutf8 = SvUTF8(sv) ? true : false; \
46             uint32_t _khash = hm_hash_string(_kstr, (uint32_t)_klen); \
47             (void)_kutf8
48              
49             #define EXTRACT_STR_VAL(sv) \
50             STRLEN _vlen; \
51             const char* _vstr = SvPV(sv, _vlen); \
52             if (_vlen > HM_MAX_STR_LEN) croak("value too long (max 2GB)"); \
53             bool _vutf8 = SvUTF8(sv) ? true : false
54              
55             /* ---- Extract optional (max_size, default_ttl) from new() args ---- */
56              
57             #define EXTRACT_NEW_ARGS(max_size_var, ttl_var) \
58             size_t max_size_var = 0; \
59             uint32_t ttl_var = 0; \
60             if (items > 1) max_size_var = (size_t)SvUV(ST(1)); \
61             if (items > 2) ttl_var = (uint32_t)SvUV(ST(2))
62              
63             /* ---- Generic keyword build functions ---- */
64              
65 135           static int build_kw_1arg(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata) {
66             (void)nargs;
67 135           const char *func = (const char *)hookdata;
68 135           OP *map_op = args[0]->op;
69 135           OP *cvref = newCVREF(0, newGVOP(OP_GV, 0, gv_fetchpv(func, GV_ADD, SVt_PVCV)));
70 135           OP *arglist = op_append_elem(OP_LIST, map_op, cvref);
71 135           *out = op_convert_list(OP_ENTERSUB, OPf_STACKED, arglist);
72 135           return KEYWORD_PLUGIN_EXPR;
73             }
74              
75 400           static int build_kw_2arg(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata) {
76             (void)nargs;
77 400           const char *func = (const char *)hookdata;
78 400           OP *map_op = args[0]->op;
79 400           OP *key_op = args[1]->op;
80 400           OP *cvref = newCVREF(0, newGVOP(OP_GV, 0, gv_fetchpv(func, GV_ADD, SVt_PVCV)));
81 400           OP *arglist = op_append_elem(OP_LIST, map_op, key_op);
82 400           arglist = op_append_elem(OP_LIST, arglist, cvref);
83 400           *out = op_convert_list(OP_ENTERSUB, OPf_STACKED, arglist);
84 400           return KEYWORD_PLUGIN_EXPR;
85             }
86              
87 438           static int build_kw_3arg(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata) {
88             (void)nargs;
89 438           const char *func = (const char *)hookdata;
90 438           OP *map_op = args[0]->op;
91 438           OP *key_op = args[1]->op;
92 438           OP *val_op = args[2]->op;
93 438           OP *cvref = newCVREF(0, newGVOP(OP_GV, 0, gv_fetchpv(func, GV_ADD, SVt_PVCV)));
94 438           OP *arglist = op_append_elem(OP_LIST, map_op, key_op);
95 438           arglist = op_append_elem(OP_LIST, arglist, val_op);
96 438           arglist = op_append_elem(OP_LIST, arglist, cvref);
97 438           *out = op_convert_list(OP_ENTERSUB, OPf_STACKED, arglist);
98 438           return KEYWORD_PLUGIN_EXPR;
99             }
100              
101              
102 12           static int build_kw_4arg(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata) {
103             (void)nargs;
104 12           const char *func = (const char *)hookdata;
105 12           OP *map_op = args[0]->op;
106 12           OP *key_op = args[1]->op;
107 12           OP *val_op = args[2]->op;
108 12           OP *ttl_op = args[3]->op;
109 12           OP *cvref = newCVREF(0, newGVOP(OP_GV, 0, gv_fetchpv(func, GV_ADD, SVt_PVCV)));
110 12           OP *arglist = op_append_elem(OP_LIST, map_op, key_op);
111 12           arglist = op_append_elem(OP_LIST, arglist, val_op);
112 12           arglist = op_append_elem(OP_LIST, arglist, ttl_op);
113 12           arglist = op_append_elem(OP_LIST, arglist, cvref);
114 12           *out = op_convert_list(OP_ENTERSUB, OPf_STACKED, arglist);
115 12           return KEYWORD_PLUGIN_EXPR;
116             }
117              
118             /* list-returning variant for keys/values/items */
119 96           static int build_kw_1arg_list(pTHX_ OP **out, XSParseKeywordPiece *args[], size_t nargs, void *hookdata) {
120             (void)nargs;
121 96           const char *func = (const char *)hookdata;
122 96           OP *map_op = args[0]->op;
123 96           OP *cvref = newCVREF(0, newGVOP(OP_GV, 0, gv_fetchpv(func, GV_ADD, SVt_PVCV)));
124 96           OP *arglist = op_append_elem(OP_LIST, map_op, cvref);
125 96           *out = op_convert_list(OP_ENTERSUB, OPf_STACKED | OPf_WANT_LIST, arglist);
126 96           return KEYWORD_PLUGIN_EXPR;
127             }
128              
129             /* ---- Keyword pieces ---- */
130              
131             static const struct XSParseKeywordPieceType pieces_1expr[] = {
132             XPK_TERMEXPR, {0}
133             };
134              
135             static const struct XSParseKeywordPieceType pieces_2expr[] = {
136             XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, {0}
137             };
138              
139             static const struct XSParseKeywordPieceType pieces_3expr[] = {
140             XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, {0}
141             };
142             static const struct XSParseKeywordPieceType pieces_4expr[] = {
143             XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, {0}
144             };
145              
146              
147             /* ---- Keyword hook definitions ----
148             *
149             * Macro to define a keyword hook struct.
150             * variant = i16, i16a, i16s, i32, i32a, i32s, ia, ii, is, sa, si16, si32, si, ss
151             * kw = keyword name (e.g., put, get)
152             * nargs = 1, 2, or 3
153             * builder = build function (build_kw_1arg, build_kw_2arg, etc.)
154             */
155             #define DEFINE_KW_HOOK(variant, PKG, kw, nargs, builder) \
156             static const struct XSParseKeywordHooks hooks_hm_##variant##_##kw = { \
157             .flags = XPK_FLAG_EXPR, \
158             .permit_hintkey = "Data::HashMap::" PKG "/hm_" #variant "_" #kw, \
159             .pieces = pieces_##nargs##expr, \
160             .build = builder, \
161             };
162              
163             /* I16 keywords */
164             DEFINE_KW_HOOK(i16, "I16", put, 3, build_kw_3arg)
165             DEFINE_KW_HOOK(i16, "I16", get, 2, build_kw_2arg)
166             DEFINE_KW_HOOK(i16, "I16", remove, 2, build_kw_2arg)
167             DEFINE_KW_HOOK(i16, "I16", exists, 2, build_kw_2arg)
168             DEFINE_KW_HOOK(i16, "I16", incr, 2, build_kw_2arg)
169             DEFINE_KW_HOOK(i16, "I16", decr, 2, build_kw_2arg)
170             DEFINE_KW_HOOK(i16, "I16", incr_by, 3, build_kw_3arg)
171             DEFINE_KW_HOOK(i16, "I16", size, 1, build_kw_1arg)
172             DEFINE_KW_HOOK(i16, "I16", keys, 1, build_kw_1arg_list)
173             DEFINE_KW_HOOK(i16, "I16", values, 1, build_kw_1arg_list)
174             DEFINE_KW_HOOK(i16, "I16", items, 1, build_kw_1arg_list)
175             DEFINE_KW_HOOK(i16, "I16", max_size, 1, build_kw_1arg)
176             DEFINE_KW_HOOK(i16, "I16", ttl, 1, build_kw_1arg)
177             DEFINE_KW_HOOK(i16, "I16", each, 1, build_kw_1arg_list)
178             DEFINE_KW_HOOK(i16, "I16", iter_reset, 1, build_kw_1arg)
179             DEFINE_KW_HOOK(i16, "I16", clear, 1, build_kw_1arg)
180             DEFINE_KW_HOOK(i16, "I16", to_hash, 1, build_kw_1arg)
181             DEFINE_KW_HOOK(i16, "I16", put_ttl, 4, build_kw_4arg)
182             DEFINE_KW_HOOK(i16, "I16", get_or_set, 3, build_kw_3arg)
183              
184             /* I16S keywords (int16 -> string) */
185             DEFINE_KW_HOOK(i16s, "I16S", put, 3, build_kw_3arg)
186             DEFINE_KW_HOOK(i16s, "I16S", get, 2, build_kw_2arg)
187             DEFINE_KW_HOOK(i16s, "I16S", remove, 2, build_kw_2arg)
188             DEFINE_KW_HOOK(i16s, "I16S", exists, 2, build_kw_2arg)
189             DEFINE_KW_HOOK(i16s, "I16S", size, 1, build_kw_1arg)
190             DEFINE_KW_HOOK(i16s, "I16S", keys, 1, build_kw_1arg_list)
191             DEFINE_KW_HOOK(i16s, "I16S", values, 1, build_kw_1arg_list)
192             DEFINE_KW_HOOK(i16s, "I16S", items, 1, build_kw_1arg_list)
193             DEFINE_KW_HOOK(i16s, "I16S", max_size, 1, build_kw_1arg)
194             DEFINE_KW_HOOK(i16s, "I16S", ttl, 1, build_kw_1arg)
195             DEFINE_KW_HOOK(i16s, "I16S", each, 1, build_kw_1arg_list)
196             DEFINE_KW_HOOK(i16s, "I16S", iter_reset, 1, build_kw_1arg)
197             DEFINE_KW_HOOK(i16s, "I16S", clear, 1, build_kw_1arg)
198             DEFINE_KW_HOOK(i16s, "I16S", to_hash, 1, build_kw_1arg)
199             DEFINE_KW_HOOK(i16s, "I16S", put_ttl, 4, build_kw_4arg)
200             DEFINE_KW_HOOK(i16s, "I16S", get_or_set, 3, build_kw_3arg)
201              
202             /* SI16 keywords (string -> int16) */
203             DEFINE_KW_HOOK(si16, "SI16", put, 3, build_kw_3arg)
204             DEFINE_KW_HOOK(si16, "SI16", get, 2, build_kw_2arg)
205             DEFINE_KW_HOOK(si16, "SI16", remove, 2, build_kw_2arg)
206             DEFINE_KW_HOOK(si16, "SI16", exists, 2, build_kw_2arg)
207             DEFINE_KW_HOOK(si16, "SI16", incr, 2, build_kw_2arg)
208             DEFINE_KW_HOOK(si16, "SI16", decr, 2, build_kw_2arg)
209             DEFINE_KW_HOOK(si16, "SI16", incr_by, 3, build_kw_3arg)
210             DEFINE_KW_HOOK(si16, "SI16", size, 1, build_kw_1arg)
211             DEFINE_KW_HOOK(si16, "SI16", keys, 1, build_kw_1arg_list)
212             DEFINE_KW_HOOK(si16, "SI16", values, 1, build_kw_1arg_list)
213             DEFINE_KW_HOOK(si16, "SI16", items, 1, build_kw_1arg_list)
214             DEFINE_KW_HOOK(si16, "SI16", max_size, 1, build_kw_1arg)
215             DEFINE_KW_HOOK(si16, "SI16", ttl, 1, build_kw_1arg)
216             DEFINE_KW_HOOK(si16, "SI16", each, 1, build_kw_1arg_list)
217             DEFINE_KW_HOOK(si16, "SI16", iter_reset, 1, build_kw_1arg)
218             DEFINE_KW_HOOK(si16, "SI16", clear, 1, build_kw_1arg)
219             DEFINE_KW_HOOK(si16, "SI16", to_hash, 1, build_kw_1arg)
220             DEFINE_KW_HOOK(si16, "SI16", put_ttl, 4, build_kw_4arg)
221             DEFINE_KW_HOOK(si16, "SI16", get_or_set, 3, build_kw_3arg)
222              
223             /* I32 keywords */
224             DEFINE_KW_HOOK(i32, "I32", put, 3, build_kw_3arg)
225             DEFINE_KW_HOOK(i32, "I32", get, 2, build_kw_2arg)
226             DEFINE_KW_HOOK(i32, "I32", remove, 2, build_kw_2arg)
227             DEFINE_KW_HOOK(i32, "I32", exists, 2, build_kw_2arg)
228             DEFINE_KW_HOOK(i32, "I32", incr, 2, build_kw_2arg)
229             DEFINE_KW_HOOK(i32, "I32", decr, 2, build_kw_2arg)
230             DEFINE_KW_HOOK(i32, "I32", incr_by, 3, build_kw_3arg)
231             DEFINE_KW_HOOK(i32, "I32", size, 1, build_kw_1arg)
232             DEFINE_KW_HOOK(i32, "I32", keys, 1, build_kw_1arg_list)
233             DEFINE_KW_HOOK(i32, "I32", values, 1, build_kw_1arg_list)
234             DEFINE_KW_HOOK(i32, "I32", items, 1, build_kw_1arg_list)
235             DEFINE_KW_HOOK(i32, "I32", max_size, 1, build_kw_1arg)
236             DEFINE_KW_HOOK(i32, "I32", ttl, 1, build_kw_1arg)
237             DEFINE_KW_HOOK(i32, "I32", each, 1, build_kw_1arg_list)
238             DEFINE_KW_HOOK(i32, "I32", iter_reset, 1, build_kw_1arg)
239             DEFINE_KW_HOOK(i32, "I32", clear, 1, build_kw_1arg)
240             DEFINE_KW_HOOK(i32, "I32", to_hash, 1, build_kw_1arg)
241             DEFINE_KW_HOOK(i32, "I32", put_ttl, 4, build_kw_4arg)
242             DEFINE_KW_HOOK(i32, "I32", get_or_set, 3, build_kw_3arg)
243              
244             /* II keywords */
245             DEFINE_KW_HOOK(ii, "II", put, 3, build_kw_3arg)
246             DEFINE_KW_HOOK(ii, "II", get, 2, build_kw_2arg)
247             DEFINE_KW_HOOK(ii, "II", remove, 2, build_kw_2arg)
248             DEFINE_KW_HOOK(ii, "II", exists, 2, build_kw_2arg)
249             DEFINE_KW_HOOK(ii, "II", incr, 2, build_kw_2arg)
250             DEFINE_KW_HOOK(ii, "II", decr, 2, build_kw_2arg)
251             DEFINE_KW_HOOK(ii, "II", incr_by, 3, build_kw_3arg)
252             DEFINE_KW_HOOK(ii, "II", size, 1, build_kw_1arg)
253             DEFINE_KW_HOOK(ii, "II", keys, 1, build_kw_1arg_list)
254             DEFINE_KW_HOOK(ii, "II", values, 1, build_kw_1arg_list)
255             DEFINE_KW_HOOK(ii, "II", items, 1, build_kw_1arg_list)
256             DEFINE_KW_HOOK(ii, "II", max_size, 1, build_kw_1arg)
257             DEFINE_KW_HOOK(ii, "II", ttl, 1, build_kw_1arg)
258             DEFINE_KW_HOOK(ii, "II", each, 1, build_kw_1arg_list)
259             DEFINE_KW_HOOK(ii, "II", iter_reset, 1, build_kw_1arg)
260             DEFINE_KW_HOOK(ii, "II", clear, 1, build_kw_1arg)
261             DEFINE_KW_HOOK(ii, "II", to_hash, 1, build_kw_1arg)
262             DEFINE_KW_HOOK(ii, "II", put_ttl, 4, build_kw_4arg)
263             DEFINE_KW_HOOK(ii, "II", get_or_set, 3, build_kw_3arg)
264              
265             /* IS keywords */
266             DEFINE_KW_HOOK(is, "IS", put, 3, build_kw_3arg)
267             DEFINE_KW_HOOK(is, "IS", get, 2, build_kw_2arg)
268             DEFINE_KW_HOOK(is, "IS", remove, 2, build_kw_2arg)
269             DEFINE_KW_HOOK(is, "IS", exists, 2, build_kw_2arg)
270             DEFINE_KW_HOOK(is, "IS", size, 1, build_kw_1arg)
271             DEFINE_KW_HOOK(is, "IS", keys, 1, build_kw_1arg_list)
272             DEFINE_KW_HOOK(is, "IS", values, 1, build_kw_1arg_list)
273             DEFINE_KW_HOOK(is, "IS", items, 1, build_kw_1arg_list)
274             DEFINE_KW_HOOK(is, "IS", max_size, 1, build_kw_1arg)
275             DEFINE_KW_HOOK(is, "IS", ttl, 1, build_kw_1arg)
276             DEFINE_KW_HOOK(is, "IS", each, 1, build_kw_1arg_list)
277             DEFINE_KW_HOOK(is, "IS", iter_reset, 1, build_kw_1arg)
278             DEFINE_KW_HOOK(is, "IS", clear, 1, build_kw_1arg)
279             DEFINE_KW_HOOK(is, "IS", to_hash, 1, build_kw_1arg)
280             DEFINE_KW_HOOK(is, "IS", put_ttl, 4, build_kw_4arg)
281             DEFINE_KW_HOOK(is, "IS", get_or_set, 3, build_kw_3arg)
282              
283             /* SI keywords */
284             DEFINE_KW_HOOK(si, "SI", put, 3, build_kw_3arg)
285             DEFINE_KW_HOOK(si, "SI", get, 2, build_kw_2arg)
286             DEFINE_KW_HOOK(si, "SI", remove, 2, build_kw_2arg)
287             DEFINE_KW_HOOK(si, "SI", exists, 2, build_kw_2arg)
288             DEFINE_KW_HOOK(si, "SI", incr, 2, build_kw_2arg)
289             DEFINE_KW_HOOK(si, "SI", decr, 2, build_kw_2arg)
290             DEFINE_KW_HOOK(si, "SI", incr_by, 3, build_kw_3arg)
291             DEFINE_KW_HOOK(si, "SI", size, 1, build_kw_1arg)
292             DEFINE_KW_HOOK(si, "SI", keys, 1, build_kw_1arg_list)
293             DEFINE_KW_HOOK(si, "SI", values, 1, build_kw_1arg_list)
294             DEFINE_KW_HOOK(si, "SI", items, 1, build_kw_1arg_list)
295             DEFINE_KW_HOOK(si, "SI", max_size, 1, build_kw_1arg)
296             DEFINE_KW_HOOK(si, "SI", ttl, 1, build_kw_1arg)
297             DEFINE_KW_HOOK(si, "SI", each, 1, build_kw_1arg_list)
298             DEFINE_KW_HOOK(si, "SI", iter_reset, 1, build_kw_1arg)
299             DEFINE_KW_HOOK(si, "SI", clear, 1, build_kw_1arg)
300             DEFINE_KW_HOOK(si, "SI", to_hash, 1, build_kw_1arg)
301             DEFINE_KW_HOOK(si, "SI", put_ttl, 4, build_kw_4arg)
302             DEFINE_KW_HOOK(si, "SI", get_or_set, 3, build_kw_3arg)
303              
304             /* SS keywords */
305             DEFINE_KW_HOOK(ss, "SS", put, 3, build_kw_3arg)
306             DEFINE_KW_HOOK(ss, "SS", get, 2, build_kw_2arg)
307             DEFINE_KW_HOOK(ss, "SS", remove, 2, build_kw_2arg)
308             DEFINE_KW_HOOK(ss, "SS", exists, 2, build_kw_2arg)
309             DEFINE_KW_HOOK(ss, "SS", size, 1, build_kw_1arg)
310             DEFINE_KW_HOOK(ss, "SS", keys, 1, build_kw_1arg_list)
311             DEFINE_KW_HOOK(ss, "SS", values, 1, build_kw_1arg_list)
312             DEFINE_KW_HOOK(ss, "SS", items, 1, build_kw_1arg_list)
313             DEFINE_KW_HOOK(ss, "SS", max_size, 1, build_kw_1arg)
314             DEFINE_KW_HOOK(ss, "SS", ttl, 1, build_kw_1arg)
315             DEFINE_KW_HOOK(ss, "SS", each, 1, build_kw_1arg_list)
316             DEFINE_KW_HOOK(ss, "SS", iter_reset, 1, build_kw_1arg)
317             DEFINE_KW_HOOK(ss, "SS", clear, 1, build_kw_1arg)
318             DEFINE_KW_HOOK(ss, "SS", to_hash, 1, build_kw_1arg)
319             DEFINE_KW_HOOK(ss, "SS", put_ttl, 4, build_kw_4arg)
320             DEFINE_KW_HOOK(ss, "SS", get_or_set, 3, build_kw_3arg)
321              
322             /* I32S keywords (int32 -> string) */
323             DEFINE_KW_HOOK(i32s, "I32S", put, 3, build_kw_3arg)
324             DEFINE_KW_HOOK(i32s, "I32S", get, 2, build_kw_2arg)
325             DEFINE_KW_HOOK(i32s, "I32S", remove, 2, build_kw_2arg)
326             DEFINE_KW_HOOK(i32s, "I32S", exists, 2, build_kw_2arg)
327             DEFINE_KW_HOOK(i32s, "I32S", size, 1, build_kw_1arg)
328             DEFINE_KW_HOOK(i32s, "I32S", keys, 1, build_kw_1arg_list)
329             DEFINE_KW_HOOK(i32s, "I32S", values, 1, build_kw_1arg_list)
330             DEFINE_KW_HOOK(i32s, "I32S", items, 1, build_kw_1arg_list)
331             DEFINE_KW_HOOK(i32s, "I32S", max_size, 1, build_kw_1arg)
332             DEFINE_KW_HOOK(i32s, "I32S", ttl, 1, build_kw_1arg)
333             DEFINE_KW_HOOK(i32s, "I32S", each, 1, build_kw_1arg_list)
334             DEFINE_KW_HOOK(i32s, "I32S", iter_reset, 1, build_kw_1arg)
335             DEFINE_KW_HOOK(i32s, "I32S", clear, 1, build_kw_1arg)
336             DEFINE_KW_HOOK(i32s, "I32S", to_hash, 1, build_kw_1arg)
337             DEFINE_KW_HOOK(i32s, "I32S", put_ttl, 4, build_kw_4arg)
338             DEFINE_KW_HOOK(i32s, "I32S", get_or_set, 3, build_kw_3arg)
339              
340             /* SI32 keywords (string -> int32) */
341             DEFINE_KW_HOOK(si32, "SI32", put, 3, build_kw_3arg)
342             DEFINE_KW_HOOK(si32, "SI32", get, 2, build_kw_2arg)
343             DEFINE_KW_HOOK(si32, "SI32", remove, 2, build_kw_2arg)
344             DEFINE_KW_HOOK(si32, "SI32", exists, 2, build_kw_2arg)
345             DEFINE_KW_HOOK(si32, "SI32", incr, 2, build_kw_2arg)
346             DEFINE_KW_HOOK(si32, "SI32", decr, 2, build_kw_2arg)
347             DEFINE_KW_HOOK(si32, "SI32", incr_by, 3, build_kw_3arg)
348             DEFINE_KW_HOOK(si32, "SI32", size, 1, build_kw_1arg)
349             DEFINE_KW_HOOK(si32, "SI32", keys, 1, build_kw_1arg_list)
350             DEFINE_KW_HOOK(si32, "SI32", values, 1, build_kw_1arg_list)
351             DEFINE_KW_HOOK(si32, "SI32", items, 1, build_kw_1arg_list)
352             DEFINE_KW_HOOK(si32, "SI32", max_size, 1, build_kw_1arg)
353             DEFINE_KW_HOOK(si32, "SI32", ttl, 1, build_kw_1arg)
354             DEFINE_KW_HOOK(si32, "SI32", each, 1, build_kw_1arg_list)
355             DEFINE_KW_HOOK(si32, "SI32", iter_reset, 1, build_kw_1arg)
356             DEFINE_KW_HOOK(si32, "SI32", clear, 1, build_kw_1arg)
357             DEFINE_KW_HOOK(si32, "SI32", to_hash, 1, build_kw_1arg)
358             DEFINE_KW_HOOK(si32, "SI32", put_ttl, 4, build_kw_4arg)
359             DEFINE_KW_HOOK(si32, "SI32", get_or_set, 3, build_kw_3arg)
360              
361             /* I32A keywords (int32 -> SV*) */
362             DEFINE_KW_HOOK(i32a, "I32A", put, 3, build_kw_3arg)
363             DEFINE_KW_HOOK(i32a, "I32A", get, 2, build_kw_2arg)
364             DEFINE_KW_HOOK(i32a, "I32A", remove, 2, build_kw_2arg)
365             DEFINE_KW_HOOK(i32a, "I32A", exists, 2, build_kw_2arg)
366             DEFINE_KW_HOOK(i32a, "I32A", size, 1, build_kw_1arg)
367             DEFINE_KW_HOOK(i32a, "I32A", keys, 1, build_kw_1arg_list)
368             DEFINE_KW_HOOK(i32a, "I32A", values, 1, build_kw_1arg_list)
369             DEFINE_KW_HOOK(i32a, "I32A", items, 1, build_kw_1arg_list)
370             DEFINE_KW_HOOK(i32a, "I32A", max_size, 1, build_kw_1arg)
371             DEFINE_KW_HOOK(i32a, "I32A", ttl, 1, build_kw_1arg)
372             DEFINE_KW_HOOK(i32a, "I32A", each, 1, build_kw_1arg_list)
373             DEFINE_KW_HOOK(i32a, "I32A", iter_reset, 1, build_kw_1arg)
374             DEFINE_KW_HOOK(i32a, "I32A", clear, 1, build_kw_1arg)
375             DEFINE_KW_HOOK(i32a, "I32A", to_hash, 1, build_kw_1arg)
376             DEFINE_KW_HOOK(i32a, "I32A", put_ttl, 4, build_kw_4arg)
377             DEFINE_KW_HOOK(i32a, "I32A", get_or_set, 3, build_kw_3arg)
378              
379             /* I16A keywords (int16 -> SV*) */
380             DEFINE_KW_HOOK(i16a, "I16A", put, 3, build_kw_3arg)
381             DEFINE_KW_HOOK(i16a, "I16A", get, 2, build_kw_2arg)
382             DEFINE_KW_HOOK(i16a, "I16A", remove, 2, build_kw_2arg)
383             DEFINE_KW_HOOK(i16a, "I16A", exists, 2, build_kw_2arg)
384             DEFINE_KW_HOOK(i16a, "I16A", size, 1, build_kw_1arg)
385             DEFINE_KW_HOOK(i16a, "I16A", keys, 1, build_kw_1arg_list)
386             DEFINE_KW_HOOK(i16a, "I16A", values, 1, build_kw_1arg_list)
387             DEFINE_KW_HOOK(i16a, "I16A", items, 1, build_kw_1arg_list)
388             DEFINE_KW_HOOK(i16a, "I16A", max_size, 1, build_kw_1arg)
389             DEFINE_KW_HOOK(i16a, "I16A", ttl, 1, build_kw_1arg)
390             DEFINE_KW_HOOK(i16a, "I16A", each, 1, build_kw_1arg_list)
391             DEFINE_KW_HOOK(i16a, "I16A", iter_reset, 1, build_kw_1arg)
392             DEFINE_KW_HOOK(i16a, "I16A", clear, 1, build_kw_1arg)
393             DEFINE_KW_HOOK(i16a, "I16A", to_hash, 1, build_kw_1arg)
394             DEFINE_KW_HOOK(i16a, "I16A", put_ttl, 4, build_kw_4arg)
395             DEFINE_KW_HOOK(i16a, "I16A", get_or_set, 3, build_kw_3arg)
396              
397             /* IA keywords (int64 -> SV*) */
398             DEFINE_KW_HOOK(ia, "IA", put, 3, build_kw_3arg)
399             DEFINE_KW_HOOK(ia, "IA", get, 2, build_kw_2arg)
400             DEFINE_KW_HOOK(ia, "IA", remove, 2, build_kw_2arg)
401             DEFINE_KW_HOOK(ia, "IA", exists, 2, build_kw_2arg)
402             DEFINE_KW_HOOK(ia, "IA", size, 1, build_kw_1arg)
403             DEFINE_KW_HOOK(ia, "IA", keys, 1, build_kw_1arg_list)
404             DEFINE_KW_HOOK(ia, "IA", values, 1, build_kw_1arg_list)
405             DEFINE_KW_HOOK(ia, "IA", items, 1, build_kw_1arg_list)
406             DEFINE_KW_HOOK(ia, "IA", max_size, 1, build_kw_1arg)
407             DEFINE_KW_HOOK(ia, "IA", ttl, 1, build_kw_1arg)
408             DEFINE_KW_HOOK(ia, "IA", each, 1, build_kw_1arg_list)
409             DEFINE_KW_HOOK(ia, "IA", iter_reset, 1, build_kw_1arg)
410             DEFINE_KW_HOOK(ia, "IA", clear, 1, build_kw_1arg)
411             DEFINE_KW_HOOK(ia, "IA", to_hash, 1, build_kw_1arg)
412             DEFINE_KW_HOOK(ia, "IA", put_ttl, 4, build_kw_4arg)
413             DEFINE_KW_HOOK(ia, "IA", get_or_set, 3, build_kw_3arg)
414              
415             /* SA keywords (string -> SV*) */
416             DEFINE_KW_HOOK(sa, "SA", put, 3, build_kw_3arg)
417             DEFINE_KW_HOOK(sa, "SA", get, 2, build_kw_2arg)
418             DEFINE_KW_HOOK(sa, "SA", remove, 2, build_kw_2arg)
419             DEFINE_KW_HOOK(sa, "SA", exists, 2, build_kw_2arg)
420             DEFINE_KW_HOOK(sa, "SA", size, 1, build_kw_1arg)
421             DEFINE_KW_HOOK(sa, "SA", keys, 1, build_kw_1arg_list)
422             DEFINE_KW_HOOK(sa, "SA", values, 1, build_kw_1arg_list)
423             DEFINE_KW_HOOK(sa, "SA", items, 1, build_kw_1arg_list)
424             DEFINE_KW_HOOK(sa, "SA", max_size, 1, build_kw_1arg)
425             DEFINE_KW_HOOK(sa, "SA", ttl, 1, build_kw_1arg)
426             DEFINE_KW_HOOK(sa, "SA", each, 1, build_kw_1arg_list)
427             DEFINE_KW_HOOK(sa, "SA", iter_reset, 1, build_kw_1arg)
428             DEFINE_KW_HOOK(sa, "SA", clear, 1, build_kw_1arg)
429             DEFINE_KW_HOOK(sa, "SA", to_hash, 1, build_kw_1arg)
430             DEFINE_KW_HOOK(sa, "SA", put_ttl, 4, build_kw_4arg)
431             DEFINE_KW_HOOK(sa, "SA", get_or_set, 3, build_kw_3arg)
432              
433             /* ---- Macro to register a keyword ---- */
434             #define REGISTER_KW(variant, kw, func_name) \
435             register_xs_parse_keyword("hm_" #variant "_" #kw, \
436             &hooks_hm_##variant##_##kw, (void*)func_name)
437              
438             /* ---- Live node checks ---- */
439             #define I16_NODE_LIVE(n) ((n).key != INT16_MIN && (n).key != (INT16_MIN + 1))
440             #define I16S_NODE_LIVE(n) I16_NODE_LIVE(n) /* I16S keys are int16_t */
441             #define I32_NODE_LIVE(n) ((n).key != INT32_MIN && (n).key != (INT32_MIN + 1))
442             #define I32S_NODE_LIVE(n) I32_NODE_LIVE(n) /* I32S keys are int32_t */
443             #define II_NODE_LIVE(n) ((n).key != INT64_MIN && (n).key != (INT64_MIN + 1))
444             #define IS_NODE_LIVE(n) II_NODE_LIVE(n) /* IS keys are int64_t */
445             #define STR_NODE_LIVE(n) ((n).key != NULL && (n).key != &hm_str_tombstone_marker)
446             #define SI16_NODE_LIVE(n) STR_NODE_LIVE(n)
447             #define SI32_NODE_LIVE(n) STR_NODE_LIVE(n)
448             #define SI_NODE_LIVE(n) STR_NODE_LIVE(n)
449             #define SS_NODE_LIVE(n) STR_NODE_LIVE(n)
450             #define I32A_NODE_LIVE(n) I32_NODE_LIVE(n) /* I32A keys are int32_t */
451             #define I16A_NODE_LIVE(n) I16_NODE_LIVE(n) /* I16A keys are int16_t */
452             #define IA_NODE_LIVE(n) II_NODE_LIVE(n) /* IA keys are int64_t */
453             #define SA_NODE_LIVE(n) STR_NODE_LIVE(n)
454              
455             /* ---- TTL-aware iteration helper ---- */
456             #define HM_TTL_SKIP_EXPIRED(self, i, now) \
457             (self->expires_at && self->expires_at[i] && (now) >= self->expires_at[i])
458              
459              
460             MODULE = Data::HashMap PACKAGE = Data::HashMap::I32
461             PROTOTYPES: DISABLE
462              
463             BOOT:
464 20           boot_xs_parse_keyword(0.40);
465 20           REGISTER_KW(i16, put, "Data::HashMap::I16::put");
466 20           REGISTER_KW(i16, get, "Data::HashMap::I16::get");
467 20           REGISTER_KW(i16, remove, "Data::HashMap::I16::remove");
468 20           REGISTER_KW(i16, exists, "Data::HashMap::I16::exists");
469 20           REGISTER_KW(i16, incr, "Data::HashMap::I16::incr");
470 20           REGISTER_KW(i16, decr, "Data::HashMap::I16::decr");
471 20           REGISTER_KW(i16, incr_by, "Data::HashMap::I16::incr_by");
472 20           REGISTER_KW(i16, size, "Data::HashMap::I16::size");
473 20           REGISTER_KW(i16, keys, "Data::HashMap::I16::keys");
474 20           REGISTER_KW(i16, values, "Data::HashMap::I16::values");
475 20           REGISTER_KW(i16, items, "Data::HashMap::I16::items");
476 20           REGISTER_KW(i16, max_size, "Data::HashMap::I16::max_size");
477 20           REGISTER_KW(i16, ttl, "Data::HashMap::I16::ttl");
478 20           REGISTER_KW(i16, each, "Data::HashMap::I16::each");
479 20           REGISTER_KW(i16, iter_reset, "Data::HashMap::I16::iter_reset");
480 20           REGISTER_KW(i16, clear, "Data::HashMap::I16::clear");
481 20           REGISTER_KW(i16, to_hash, "Data::HashMap::I16::to_hash");
482 20           REGISTER_KW(i16, put_ttl, "Data::HashMap::I16::put_ttl");
483 20           REGISTER_KW(i16, get_or_set, "Data::HashMap::I16::get_or_set");
484 20           REGISTER_KW(i16s, put, "Data::HashMap::I16S::put");
485 20           REGISTER_KW(i16s, get, "Data::HashMap::I16S::get");
486 20           REGISTER_KW(i16s, remove, "Data::HashMap::I16S::remove");
487 20           REGISTER_KW(i16s, exists, "Data::HashMap::I16S::exists");
488 20           REGISTER_KW(i16s, size, "Data::HashMap::I16S::size");
489 20           REGISTER_KW(i16s, keys, "Data::HashMap::I16S::keys");
490 20           REGISTER_KW(i16s, values, "Data::HashMap::I16S::values");
491 20           REGISTER_KW(i16s, items, "Data::HashMap::I16S::items");
492 20           REGISTER_KW(i16s, max_size, "Data::HashMap::I16S::max_size");
493 20           REGISTER_KW(i16s, ttl, "Data::HashMap::I16S::ttl");
494 20           REGISTER_KW(i16s, each, "Data::HashMap::I16S::each");
495 20           REGISTER_KW(i16s, iter_reset, "Data::HashMap::I16S::iter_reset");
496 20           REGISTER_KW(i16s, clear, "Data::HashMap::I16S::clear");
497 20           REGISTER_KW(i16s, to_hash, "Data::HashMap::I16S::to_hash");
498 20           REGISTER_KW(i16s, put_ttl, "Data::HashMap::I16S::put_ttl");
499 20           REGISTER_KW(i16s, get_or_set, "Data::HashMap::I16S::get_or_set");
500 20           REGISTER_KW(si16, put, "Data::HashMap::SI16::put");
501 20           REGISTER_KW(si16, get, "Data::HashMap::SI16::get");
502 20           REGISTER_KW(si16, remove, "Data::HashMap::SI16::remove");
503 20           REGISTER_KW(si16, exists, "Data::HashMap::SI16::exists");
504 20           REGISTER_KW(si16, incr, "Data::HashMap::SI16::incr");
505 20           REGISTER_KW(si16, decr, "Data::HashMap::SI16::decr");
506 20           REGISTER_KW(si16, incr_by, "Data::HashMap::SI16::incr_by");
507 20           REGISTER_KW(si16, size, "Data::HashMap::SI16::size");
508 20           REGISTER_KW(si16, keys, "Data::HashMap::SI16::keys");
509 20           REGISTER_KW(si16, values, "Data::HashMap::SI16::values");
510 20           REGISTER_KW(si16, items, "Data::HashMap::SI16::items");
511 20           REGISTER_KW(si16, max_size, "Data::HashMap::SI16::max_size");
512 20           REGISTER_KW(si16, ttl, "Data::HashMap::SI16::ttl");
513 20           REGISTER_KW(si16, each, "Data::HashMap::SI16::each");
514 20           REGISTER_KW(si16, iter_reset, "Data::HashMap::SI16::iter_reset");
515 20           REGISTER_KW(si16, clear, "Data::HashMap::SI16::clear");
516 20           REGISTER_KW(si16, to_hash, "Data::HashMap::SI16::to_hash");
517 20           REGISTER_KW(si16, put_ttl, "Data::HashMap::SI16::put_ttl");
518 20           REGISTER_KW(si16, get_or_set, "Data::HashMap::SI16::get_or_set");
519 20           REGISTER_KW(i32, put, "Data::HashMap::I32::put");
520 20           REGISTER_KW(i32, get, "Data::HashMap::I32::get");
521 20           REGISTER_KW(i32, remove, "Data::HashMap::I32::remove");
522 20           REGISTER_KW(i32, exists, "Data::HashMap::I32::exists");
523 20           REGISTER_KW(i32, incr, "Data::HashMap::I32::incr");
524 20           REGISTER_KW(i32, decr, "Data::HashMap::I32::decr");
525 20           REGISTER_KW(i32, incr_by, "Data::HashMap::I32::incr_by");
526 20           REGISTER_KW(i32, size, "Data::HashMap::I32::size");
527 20           REGISTER_KW(i32, keys, "Data::HashMap::I32::keys");
528 20           REGISTER_KW(i32, values, "Data::HashMap::I32::values");
529 20           REGISTER_KW(i32, items, "Data::HashMap::I32::items");
530 20           REGISTER_KW(i32, max_size, "Data::HashMap::I32::max_size");
531 20           REGISTER_KW(i32, ttl, "Data::HashMap::I32::ttl");
532 20           REGISTER_KW(i32, each, "Data::HashMap::I32::each");
533 20           REGISTER_KW(i32, iter_reset, "Data::HashMap::I32::iter_reset");
534 20           REGISTER_KW(i32, clear, "Data::HashMap::I32::clear");
535 20           REGISTER_KW(i32, to_hash, "Data::HashMap::I32::to_hash");
536 20           REGISTER_KW(i32, put_ttl, "Data::HashMap::I32::put_ttl");
537 20           REGISTER_KW(i32, get_or_set, "Data::HashMap::I32::get_or_set");
538 20           REGISTER_KW(ii, put, "Data::HashMap::II::put");
539 20           REGISTER_KW(ii, get, "Data::HashMap::II::get");
540 20           REGISTER_KW(ii, remove, "Data::HashMap::II::remove");
541 20           REGISTER_KW(ii, exists, "Data::HashMap::II::exists");
542 20           REGISTER_KW(ii, incr, "Data::HashMap::II::incr");
543 20           REGISTER_KW(ii, decr, "Data::HashMap::II::decr");
544 20           REGISTER_KW(ii, incr_by, "Data::HashMap::II::incr_by");
545 20           REGISTER_KW(ii, size, "Data::HashMap::II::size");
546 20           REGISTER_KW(ii, keys, "Data::HashMap::II::keys");
547 20           REGISTER_KW(ii, values, "Data::HashMap::II::values");
548 20           REGISTER_KW(ii, items, "Data::HashMap::II::items");
549 20           REGISTER_KW(ii, max_size, "Data::HashMap::II::max_size");
550 20           REGISTER_KW(ii, ttl, "Data::HashMap::II::ttl");
551 20           REGISTER_KW(ii, each, "Data::HashMap::II::each");
552 20           REGISTER_KW(ii, iter_reset, "Data::HashMap::II::iter_reset");
553 20           REGISTER_KW(ii, clear, "Data::HashMap::II::clear");
554 20           REGISTER_KW(ii, to_hash, "Data::HashMap::II::to_hash");
555 20           REGISTER_KW(ii, put_ttl, "Data::HashMap::II::put_ttl");
556 20           REGISTER_KW(ii, get_or_set, "Data::HashMap::II::get_or_set");
557 20           REGISTER_KW(is, put, "Data::HashMap::IS::put");
558 20           REGISTER_KW(is, get, "Data::HashMap::IS::get");
559 20           REGISTER_KW(is, remove, "Data::HashMap::IS::remove");
560 20           REGISTER_KW(is, exists, "Data::HashMap::IS::exists");
561 20           REGISTER_KW(is, size, "Data::HashMap::IS::size");
562 20           REGISTER_KW(is, keys, "Data::HashMap::IS::keys");
563 20           REGISTER_KW(is, values, "Data::HashMap::IS::values");
564 20           REGISTER_KW(is, items, "Data::HashMap::IS::items");
565 20           REGISTER_KW(is, max_size, "Data::HashMap::IS::max_size");
566 20           REGISTER_KW(is, ttl, "Data::HashMap::IS::ttl");
567 20           REGISTER_KW(is, each, "Data::HashMap::IS::each");
568 20           REGISTER_KW(is, iter_reset, "Data::HashMap::IS::iter_reset");
569 20           REGISTER_KW(is, clear, "Data::HashMap::IS::clear");
570 20           REGISTER_KW(is, to_hash, "Data::HashMap::IS::to_hash");
571 20           REGISTER_KW(is, put_ttl, "Data::HashMap::IS::put_ttl");
572 20           REGISTER_KW(is, get_or_set, "Data::HashMap::IS::get_or_set");
573 20           REGISTER_KW(si, put, "Data::HashMap::SI::put");
574 20           REGISTER_KW(si, get, "Data::HashMap::SI::get");
575 20           REGISTER_KW(si, remove, "Data::HashMap::SI::remove");
576 20           REGISTER_KW(si, exists, "Data::HashMap::SI::exists");
577 20           REGISTER_KW(si, incr, "Data::HashMap::SI::incr");
578 20           REGISTER_KW(si, decr, "Data::HashMap::SI::decr");
579 20           REGISTER_KW(si, incr_by, "Data::HashMap::SI::incr_by");
580 20           REGISTER_KW(si, size, "Data::HashMap::SI::size");
581 20           REGISTER_KW(si, keys, "Data::HashMap::SI::keys");
582 20           REGISTER_KW(si, values, "Data::HashMap::SI::values");
583 20           REGISTER_KW(si, items, "Data::HashMap::SI::items");
584 20           REGISTER_KW(si, max_size, "Data::HashMap::SI::max_size");
585 20           REGISTER_KW(si, ttl, "Data::HashMap::SI::ttl");
586 20           REGISTER_KW(si, each, "Data::HashMap::SI::each");
587 20           REGISTER_KW(si, iter_reset, "Data::HashMap::SI::iter_reset");
588 20           REGISTER_KW(si, clear, "Data::HashMap::SI::clear");
589 20           REGISTER_KW(si, to_hash, "Data::HashMap::SI::to_hash");
590 20           REGISTER_KW(si, put_ttl, "Data::HashMap::SI::put_ttl");
591 20           REGISTER_KW(si, get_or_set, "Data::HashMap::SI::get_or_set");
592 20           REGISTER_KW(ss, put, "Data::HashMap::SS::put");
593 20           REGISTER_KW(ss, get, "Data::HashMap::SS::get");
594 20           REGISTER_KW(ss, remove, "Data::HashMap::SS::remove");
595 20           REGISTER_KW(ss, exists, "Data::HashMap::SS::exists");
596 20           REGISTER_KW(ss, size, "Data::HashMap::SS::size");
597 20           REGISTER_KW(ss, keys, "Data::HashMap::SS::keys");
598 20           REGISTER_KW(ss, values, "Data::HashMap::SS::values");
599 20           REGISTER_KW(ss, items, "Data::HashMap::SS::items");
600 20           REGISTER_KW(ss, max_size, "Data::HashMap::SS::max_size");
601 20           REGISTER_KW(ss, ttl, "Data::HashMap::SS::ttl");
602 20           REGISTER_KW(ss, each, "Data::HashMap::SS::each");
603 20           REGISTER_KW(ss, iter_reset, "Data::HashMap::SS::iter_reset");
604 20           REGISTER_KW(ss, clear, "Data::HashMap::SS::clear");
605 20           REGISTER_KW(ss, to_hash, "Data::HashMap::SS::to_hash");
606 20           REGISTER_KW(ss, put_ttl, "Data::HashMap::SS::put_ttl");
607 20           REGISTER_KW(ss, get_or_set, "Data::HashMap::SS::get_or_set");
608 20           REGISTER_KW(i32s, put, "Data::HashMap::I32S::put");
609 20           REGISTER_KW(i32s, get, "Data::HashMap::I32S::get");
610 20           REGISTER_KW(i32s, remove, "Data::HashMap::I32S::remove");
611 20           REGISTER_KW(i32s, exists, "Data::HashMap::I32S::exists");
612 20           REGISTER_KW(i32s, size, "Data::HashMap::I32S::size");
613 20           REGISTER_KW(i32s, keys, "Data::HashMap::I32S::keys");
614 20           REGISTER_KW(i32s, values, "Data::HashMap::I32S::values");
615 20           REGISTER_KW(i32s, items, "Data::HashMap::I32S::items");
616 20           REGISTER_KW(i32s, max_size, "Data::HashMap::I32S::max_size");
617 20           REGISTER_KW(i32s, ttl, "Data::HashMap::I32S::ttl");
618 20           REGISTER_KW(i32s, each, "Data::HashMap::I32S::each");
619 20           REGISTER_KW(i32s, iter_reset, "Data::HashMap::I32S::iter_reset");
620 20           REGISTER_KW(i32s, clear, "Data::HashMap::I32S::clear");
621 20           REGISTER_KW(i32s, to_hash, "Data::HashMap::I32S::to_hash");
622 20           REGISTER_KW(i32s, put_ttl, "Data::HashMap::I32S::put_ttl");
623 20           REGISTER_KW(i32s, get_or_set, "Data::HashMap::I32S::get_or_set");
624 20           REGISTER_KW(si32, put, "Data::HashMap::SI32::put");
625 20           REGISTER_KW(si32, get, "Data::HashMap::SI32::get");
626 20           REGISTER_KW(si32, remove, "Data::HashMap::SI32::remove");
627 20           REGISTER_KW(si32, exists, "Data::HashMap::SI32::exists");
628 20           REGISTER_KW(si32, incr, "Data::HashMap::SI32::incr");
629 20           REGISTER_KW(si32, decr, "Data::HashMap::SI32::decr");
630 20           REGISTER_KW(si32, incr_by, "Data::HashMap::SI32::incr_by");
631 20           REGISTER_KW(si32, size, "Data::HashMap::SI32::size");
632 20           REGISTER_KW(si32, keys, "Data::HashMap::SI32::keys");
633 20           REGISTER_KW(si32, values, "Data::HashMap::SI32::values");
634 20           REGISTER_KW(si32, items, "Data::HashMap::SI32::items");
635 20           REGISTER_KW(si32, max_size, "Data::HashMap::SI32::max_size");
636 20           REGISTER_KW(si32, ttl, "Data::HashMap::SI32::ttl");
637 20           REGISTER_KW(si32, each, "Data::HashMap::SI32::each");
638 20           REGISTER_KW(si32, iter_reset, "Data::HashMap::SI32::iter_reset");
639 20           REGISTER_KW(si32, clear, "Data::HashMap::SI32::clear");
640 20           REGISTER_KW(si32, to_hash, "Data::HashMap::SI32::to_hash");
641 20           REGISTER_KW(si32, put_ttl, "Data::HashMap::SI32::put_ttl");
642 20           REGISTER_KW(si32, get_or_set, "Data::HashMap::SI32::get_or_set");
643 20           REGISTER_KW(i32a, put, "Data::HashMap::I32A::put");
644 20           REGISTER_KW(i32a, get, "Data::HashMap::I32A::get");
645 20           REGISTER_KW(i32a, remove, "Data::HashMap::I32A::remove");
646 20           REGISTER_KW(i32a, exists, "Data::HashMap::I32A::exists");
647 20           REGISTER_KW(i32a, size, "Data::HashMap::I32A::size");
648 20           REGISTER_KW(i32a, keys, "Data::HashMap::I32A::keys");
649 20           REGISTER_KW(i32a, values, "Data::HashMap::I32A::values");
650 20           REGISTER_KW(i32a, items, "Data::HashMap::I32A::items");
651 20           REGISTER_KW(i32a, max_size, "Data::HashMap::I32A::max_size");
652 20           REGISTER_KW(i32a, ttl, "Data::HashMap::I32A::ttl");
653 20           REGISTER_KW(i32a, each, "Data::HashMap::I32A::each");
654 20           REGISTER_KW(i32a, iter_reset, "Data::HashMap::I32A::iter_reset");
655 20           REGISTER_KW(i32a, clear, "Data::HashMap::I32A::clear");
656 20           REGISTER_KW(i32a, to_hash, "Data::HashMap::I32A::to_hash");
657 20           REGISTER_KW(i32a, put_ttl, "Data::HashMap::I32A::put_ttl");
658 20           REGISTER_KW(i32a, get_or_set, "Data::HashMap::I32A::get_or_set");
659 20           REGISTER_KW(i16a, put, "Data::HashMap::I16A::put");
660 20           REGISTER_KW(i16a, get, "Data::HashMap::I16A::get");
661 20           REGISTER_KW(i16a, remove, "Data::HashMap::I16A::remove");
662 20           REGISTER_KW(i16a, exists, "Data::HashMap::I16A::exists");
663 20           REGISTER_KW(i16a, size, "Data::HashMap::I16A::size");
664 20           REGISTER_KW(i16a, keys, "Data::HashMap::I16A::keys");
665 20           REGISTER_KW(i16a, values, "Data::HashMap::I16A::values");
666 20           REGISTER_KW(i16a, items, "Data::HashMap::I16A::items");
667 20           REGISTER_KW(i16a, max_size, "Data::HashMap::I16A::max_size");
668 20           REGISTER_KW(i16a, ttl, "Data::HashMap::I16A::ttl");
669 20           REGISTER_KW(i16a, each, "Data::HashMap::I16A::each");
670 20           REGISTER_KW(i16a, iter_reset, "Data::HashMap::I16A::iter_reset");
671 20           REGISTER_KW(i16a, clear, "Data::HashMap::I16A::clear");
672 20           REGISTER_KW(i16a, to_hash, "Data::HashMap::I16A::to_hash");
673 20           REGISTER_KW(i16a, put_ttl, "Data::HashMap::I16A::put_ttl");
674 20           REGISTER_KW(i16a, get_or_set, "Data::HashMap::I16A::get_or_set");
675 20           REGISTER_KW(ia, put, "Data::HashMap::IA::put");
676 20           REGISTER_KW(ia, get, "Data::HashMap::IA::get");
677 20           REGISTER_KW(ia, remove, "Data::HashMap::IA::remove");
678 20           REGISTER_KW(ia, exists, "Data::HashMap::IA::exists");
679 20           REGISTER_KW(ia, size, "Data::HashMap::IA::size");
680 20           REGISTER_KW(ia, keys, "Data::HashMap::IA::keys");
681 20           REGISTER_KW(ia, values, "Data::HashMap::IA::values");
682 20           REGISTER_KW(ia, items, "Data::HashMap::IA::items");
683 20           REGISTER_KW(ia, max_size, "Data::HashMap::IA::max_size");
684 20           REGISTER_KW(ia, ttl, "Data::HashMap::IA::ttl");
685 20           REGISTER_KW(ia, each, "Data::HashMap::IA::each");
686 20           REGISTER_KW(ia, iter_reset, "Data::HashMap::IA::iter_reset");
687 20           REGISTER_KW(ia, clear, "Data::HashMap::IA::clear");
688 20           REGISTER_KW(ia, to_hash, "Data::HashMap::IA::to_hash");
689 20           REGISTER_KW(ia, put_ttl, "Data::HashMap::IA::put_ttl");
690 20           REGISTER_KW(ia, get_or_set, "Data::HashMap::IA::get_or_set");
691 20           REGISTER_KW(sa, put, "Data::HashMap::SA::put");
692 20           REGISTER_KW(sa, get, "Data::HashMap::SA::get");
693 20           REGISTER_KW(sa, remove, "Data::HashMap::SA::remove");
694 20           REGISTER_KW(sa, exists, "Data::HashMap::SA::exists");
695 20           REGISTER_KW(sa, size, "Data::HashMap::SA::size");
696 20           REGISTER_KW(sa, keys, "Data::HashMap::SA::keys");
697 20           REGISTER_KW(sa, values, "Data::HashMap::SA::values");
698 20           REGISTER_KW(sa, items, "Data::HashMap::SA::items");
699 20           REGISTER_KW(sa, max_size, "Data::HashMap::SA::max_size");
700 20           REGISTER_KW(sa, ttl, "Data::HashMap::SA::ttl");
701 20           REGISTER_KW(sa, each, "Data::HashMap::SA::each");
702 20           REGISTER_KW(sa, iter_reset, "Data::HashMap::SA::iter_reset");
703 20           REGISTER_KW(sa, clear, "Data::HashMap::SA::clear");
704 20           REGISTER_KW(sa, to_hash, "Data::HashMap::SA::to_hash");
705 20           REGISTER_KW(sa, put_ttl, "Data::HashMap::SA::put_ttl");
706 20           REGISTER_KW(sa, get_or_set, "Data::HashMap::SA::get_or_set");
707              
708             SV*
709             new(char* class, ...)
710             CODE:
711 17 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    50          
712 17           HashMapI32* map = hashmap_i32_create(_max_size, _ttl);
713 17 50         if (!map) croak("Failed to create HashMap::I32");
714 17           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
715             OUTPUT:
716             RETVAL
717              
718             void
719             DESTROY(SV* self_sv)
720             CODE:
721 17 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
722 17           hashmap_i32_destroy(self);
723 17           sv_setiv(SvRV(self_sv), 0);
724              
725             bool
726             put(SV* self_sv, int32_t key, int32_t value)
727             CODE:
728 150023 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
729 150023           RETVAL = hashmap_i32_put(self, key, value, 0);
730             OUTPUT:
731             RETVAL
732              
733             SV*
734             get(SV* self_sv, int32_t key)
735             CODE:
736 50009 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
737             int32_t value;
738 50009 100         if (!hashmap_i32_get(self, key, &value)) XSRETURN_UNDEF;
739 50004           RETVAL = newSViv(value);
740             OUTPUT:
741             RETVAL
742              
743             bool
744             remove(SV* self_sv, int32_t key)
745             CODE:
746 150004 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
747 150004           RETVAL = hashmap_i32_remove(self, key);
748             OUTPUT:
749             RETVAL
750              
751             bool
752             exists(SV* self_sv, int32_t key)
753             CODE:
754 3 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
755 3           RETVAL = hashmap_i32_exists(self, key);
756             OUTPUT:
757             RETVAL
758              
759             SV*
760             incr(SV* self_sv, int32_t key)
761             CODE:
762 7 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
763             int32_t val;
764 7 100         if (!hashmap_i32_increment(self, key, &val))
765 2           croak("HashMap::I32: increment failed");
766 5           RETVAL = newSViv(val);
767             OUTPUT:
768             RETVAL
769              
770             SV*
771             decr(SV* self_sv, int32_t key)
772             CODE:
773 5 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
774             int32_t val;
775 5 100         if (!hashmap_i32_decrement(self, key, &val))
776 2           croak("HashMap::I32: decrement failed");
777 3           RETVAL = newSViv(val);
778             OUTPUT:
779             RETVAL
780              
781             SV*
782             incr_by(SV* self_sv, int32_t key, int32_t delta)
783             CODE:
784 7 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
785             int32_t val;
786 7 100         if (!hashmap_i32_increment_by(self, key, delta, &val))
787 2           croak("HashMap::I32: incr_by failed");
788 5           RETVAL = newSViv(val);
789             OUTPUT:
790             RETVAL
791              
792             size_t
793             size(SV* self_sv)
794             CODE:
795 6 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
796 6 50         RETVAL = self->size;
797             OUTPUT:
798             RETVAL
799              
800             size_t
801             max_size(SV* self_sv)
802             CODE:
803 0 0         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    0          
    0          
804 0 0         RETVAL = self->max_size;
805             OUTPUT:
806             RETVAL
807              
808             UV
809             ttl(SV* self_sv)
810             CODE:
811 0 0         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    0          
    0          
812 0 0         RETVAL = (UV)self->default_ttl;
813             OUTPUT:
814             RETVAL
815              
816             void
817             keys(SV* self_sv)
818             PPCODE:
819 2 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
820 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
821 2 50         EXTEND(SP, self->size);
822             size_t i;
823 34 100         for (i = 0; i < self->capacity; i++) {
824 32 100         if (I32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
825 2 50         mXPUSHi(self->nodes[i].key);
826             }
827              
828             void
829             values(SV* self_sv)
830             PPCODE:
831 1 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
832 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
833 1 50         EXTEND(SP, self->size);
834             size_t i;
835 17 100         for (i = 0; i < self->capacity; i++) {
836 16 100         if (I32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
837 2 50         mXPUSHi(self->nodes[i].value);
838             }
839              
840             void
841             items(SV* self_sv)
842             PPCODE:
843 1 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
844 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
845 1 50         EXTEND(SP, self->size * 2);
846             size_t i;
847 17 100         for (i = 0; i < self->capacity; i++) {
848 16 100         if (I32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
849 2 50         mXPUSHi(self->nodes[i].key);
850 2 50         mXPUSHi(self->nodes[i].value);
851             }
852             }
853              
854             void
855             each(SV* self_sv)
856             PPCODE:
857 14 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
858 14 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
859 76 100         while (self->iter_pos < self->capacity) {
860 72           size_t i = self->iter_pos++;
861 72 100         if (I32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
862 10 50         EXTEND(SP, 2);
863 10 50         mXPUSHi(self->nodes[i].key);
864 10 50         mXPUSHi(self->nodes[i].value);
865 10           XSRETURN(2);
866             }
867             }
868 4           self->iter_pos = 0;
869 4           XSRETURN_EMPTY;
870              
871             void
872             iter_reset(SV* self_sv)
873             CODE:
874 1 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
875 1           self->iter_pos = 0;
876              
877             void
878             clear(SV* self_sv)
879             CODE:
880 1 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
881 1           hashmap_i32_clear(self);
882              
883             SV*
884             to_hash(SV* self_sv)
885             CODE:
886 1 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
887 1           HV* hv = newHV();
888 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
889             size_t i;
890 17 100         for (i = 0; i < self->capacity; i++) {
891 16 100         if (I32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
892 1           SV* val = newSViv(self->nodes[i].value);
893             char kbuf[24];
894 1           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
895 1           (void)hv_store(hv, kbuf, klen, val, 0);
896             }
897             }
898 1           RETVAL = newRV_noinc((SV*)hv);
899             OUTPUT:
900             RETVAL
901              
902             bool
903             put_ttl(SV* self_sv, int32_t key, int32_t value, UV ttl)
904             CODE:
905 1 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
906 1           RETVAL = hashmap_i32_put(self, key, value, (uint32_t)ttl);
907             OUTPUT:
908             RETVAL
909              
910             SV*
911             get_or_set(SV* self_sv, int32_t key, int32_t default_value)
912             CODE:
913 3 50         EXTRACT_MAP(HashMapI32, "Data::HashMap::I32", self_sv);
    50          
    50          
914             int32_t value;
915 3 100         if (hashmap_i32_get(self, key, &value)) {
916 1           RETVAL = newSViv(value);
917             } else {
918 2 100         if (!hashmap_i32_put(self, key, default_value, 0))
919 1           XSRETURN_UNDEF;
920 1           RETVAL = newSViv(default_value);
921             }
922             OUTPUT:
923             RETVAL
924              
925              
926              
927             MODULE = Data::HashMap PACKAGE = Data::HashMap::II
928             PROTOTYPES: DISABLE
929              
930             SV*
931             new(char* class, ...)
932             CODE:
933 61 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
934 61           HashMapII* map = hashmap_ii_create(_max_size, _ttl);
935 61 50         if (!map) croak("Failed to create HashMap::II");
936 61           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
937             OUTPUT:
938             RETVAL
939              
940             void
941             DESTROY(SV* self_sv)
942             CODE:
943 61 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
944 61           hashmap_ii_destroy(self);
945 61           sv_setiv(SvRV(self_sv), 0);
946              
947             bool
948             put(SV* self_sv, int64_t key, int64_t value)
949             CODE:
950 382726 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
951 382726           RETVAL = hashmap_ii_put(self, key, value, 0);
952             OUTPUT:
953             RETVAL
954              
955             SV*
956             get(SV* self_sv, int64_t key)
957             CODE:
958 100153 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
959             int64_t value;
960 100153 100         if (!hashmap_ii_get(self, key, &value)) XSRETURN_UNDEF;
961 100134           RETVAL = newSViv(value);
962             OUTPUT:
963             RETVAL
964              
965             bool
966             remove(SV* self_sv, int64_t key)
967             CODE:
968 280020 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
969 280020           RETVAL = hashmap_ii_remove(self, key);
970             OUTPUT:
971             RETVAL
972              
973             bool
974             exists(SV* self_sv, int64_t key)
975             CODE:
976 10 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
977 10           RETVAL = hashmap_ii_exists(self, key);
978             OUTPUT:
979             RETVAL
980              
981             SV*
982             incr(SV* self_sv, int64_t key)
983             CODE:
984 15011 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
985             int64_t val;
986 15011 100         if (!hashmap_ii_increment(self, key, &val))
987 2           croak("HashMap::II: increment failed");
988 15009           RETVAL = newSViv(val);
989             OUTPUT:
990             RETVAL
991              
992             SV*
993             decr(SV* self_sv, int64_t key)
994             CODE:
995 5006 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
996             int64_t val;
997 5006 100         if (!hashmap_ii_decrement(self, key, &val))
998 2           croak("HashMap::II: decrement failed");
999 5004           RETVAL = newSViv(val);
1000             OUTPUT:
1001             RETVAL
1002              
1003             SV*
1004             incr_by(SV* self_sv, int64_t key, int64_t delta)
1005             CODE:
1006 8 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1007             int64_t val;
1008 8 100         if (!hashmap_ii_increment_by(self, key, delta, &val))
1009 2           croak("HashMap::II: incr_by failed");
1010 6           RETVAL = newSViv(val);
1011             OUTPUT:
1012             RETVAL
1013              
1014             size_t
1015             size(SV* self_sv)
1016             CODE:
1017 31 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1018 31 50         RETVAL = self->size;
1019             OUTPUT:
1020             RETVAL
1021              
1022             size_t
1023             max_size(SV* self_sv)
1024             CODE:
1025 4 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1026 4 50         RETVAL = self->max_size;
1027             OUTPUT:
1028             RETVAL
1029              
1030             UV
1031             ttl(SV* self_sv)
1032             CODE:
1033 5 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1034 5 50         RETVAL = (UV)self->default_ttl;
1035             OUTPUT:
1036             RETVAL
1037              
1038             void
1039             keys(SV* self_sv)
1040             PPCODE:
1041 6 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1042 6 100         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1043 6 50         EXTEND(SP, self->size);
1044             size_t i;
1045 118 100         for (i = 0; i < self->capacity; i++) {
1046 112 100         if (II_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    100          
    100          
    50          
    100          
1047 23 50         mXPUSHi(self->nodes[i].key);
1048             }
1049              
1050             void
1051             values(SV* self_sv)
1052             PPCODE:
1053 3 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1054 3 100         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1055 3 50         EXTEND(SP, self->size);
1056             size_t i;
1057 51 100         for (i = 0; i < self->capacity; i++) {
1058 48 100         if (II_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    100          
    50          
    50          
1059 5 50         mXPUSHi(self->nodes[i].value);
1060             }
1061              
1062             void
1063             items(SV* self_sv)
1064             PPCODE:
1065 3 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1066 3 100         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1067 3 50         EXTEND(SP, self->size * 2);
1068             size_t i;
1069 51 100         for (i = 0; i < self->capacity; i++) {
1070 48 100         if (II_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    100          
    50          
    50          
1071 5 50         mXPUSHi(self->nodes[i].key);
1072 5 50         mXPUSHi(self->nodes[i].value);
1073             }
1074             }
1075              
1076             void
1077             each(SV* self_sv)
1078             PPCODE:
1079 24 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1080 24 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1081 114 100         while (self->iter_pos < self->capacity) {
1082 109           size_t i = self->iter_pos++;
1083 109 100         if (II_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    50          
    0          
    0          
1084 19 50         EXTEND(SP, 2);
1085 19 50         mXPUSHi(self->nodes[i].key);
1086 19 50         mXPUSHi(self->nodes[i].value);
1087 19           XSRETURN(2);
1088             }
1089             }
1090 5           self->iter_pos = 0;
1091 5           XSRETURN_EMPTY;
1092              
1093             void
1094             iter_reset(SV* self_sv)
1095             CODE:
1096 1 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1097 1           self->iter_pos = 0;
1098              
1099             void
1100             clear(SV* self_sv)
1101             CODE:
1102 4 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1103 4           hashmap_ii_clear(self);
1104              
1105             SV*
1106             to_hash(SV* self_sv)
1107             CODE:
1108 4 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1109 4           HV* hv = newHV();
1110 4 100         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1111             size_t i;
1112 68 100         for (i = 0; i < self->capacity; i++) {
1113 64 100         if (II_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    100          
    100          
    50          
1114 3           SV* val = newSViv(self->nodes[i].value);
1115             char kbuf[24];
1116 3           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
1117 3           (void)hv_store(hv, kbuf, klen, val, 0);
1118             }
1119             }
1120 4           RETVAL = newRV_noinc((SV*)hv);
1121             OUTPUT:
1122             RETVAL
1123              
1124             bool
1125             put_ttl(SV* self_sv, int64_t key, int64_t value, UV ttl)
1126             CODE:
1127 8 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1128 8           RETVAL = hashmap_ii_put(self, key, value, (uint32_t)ttl);
1129             OUTPUT:
1130             RETVAL
1131              
1132             SV*
1133             get_or_set(SV* self_sv, int64_t key, int64_t default_value)
1134             CODE:
1135 9 50         EXTRACT_MAP(HashMapII, "Data::HashMap::II", self_sv);
    50          
    50          
1136             int64_t value;
1137 9 100         if (hashmap_ii_get(self, key, &value)) {
1138 2           RETVAL = newSViv(value);
1139             } else {
1140 7 50         if (!hashmap_ii_put(self, key, default_value, 0))
1141 0           XSRETURN_UNDEF;
1142 7           RETVAL = newSViv(default_value);
1143             }
1144             OUTPUT:
1145             RETVAL
1146              
1147              
1148              
1149             MODULE = Data::HashMap PACKAGE = Data::HashMap::IS
1150             PROTOTYPES: DISABLE
1151              
1152             SV*
1153             new(char* class, ...)
1154             CODE:
1155 9 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    50          
1156 9           HashMapIS* map = hashmap_is_create(_max_size, _ttl);
1157 9 50         if (!map) croak("Failed to create HashMap::IS");
1158 9           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
1159             OUTPUT:
1160             RETVAL
1161              
1162             void
1163             DESTROY(SV* self_sv)
1164             CODE:
1165 9 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1166 9           hashmap_is_destroy(self);
1167 9           sv_setiv(SvRV(self_sv), 0);
1168              
1169             bool
1170             put(SV* self_sv, int64_t key, SV* value)
1171             CODE:
1172 80015 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1173 80015 50         EXTRACT_STR_VAL(value);
1174 80015           RETVAL = hashmap_is_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, 0);
1175             OUTPUT:
1176             RETVAL
1177              
1178             SV*
1179             get(SV* self_sv, int64_t key)
1180             CODE:
1181 50009 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1182             const char* val;
1183             uint32_t val_len;
1184             bool val_utf8;
1185 50009 100         if (!hashmap_is_get(self, key, &val, &val_len, &val_utf8))
1186 3           XSRETURN_UNDEF;
1187 50006           RETVAL = newSVpvn(val, val_len);
1188 50006 100         if (val_utf8) SvUTF8_on(RETVAL);
1189             OUTPUT:
1190             RETVAL
1191              
1192             bool
1193             remove(SV* self_sv, int64_t key)
1194             CODE:
1195 80004 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1196 80004           RETVAL = hashmap_is_remove(self, key);
1197             OUTPUT:
1198             RETVAL
1199              
1200             bool
1201             exists(SV* self_sv, int64_t key)
1202             CODE:
1203 3 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1204 3           RETVAL = hashmap_is_exists(self, key);
1205             OUTPUT:
1206             RETVAL
1207              
1208             size_t
1209             size(SV* self_sv)
1210             CODE:
1211 5 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1212 5 50         RETVAL = self->size;
1213             OUTPUT:
1214             RETVAL
1215              
1216             size_t
1217             max_size(SV* self_sv)
1218             CODE:
1219 0 0         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    0          
    0          
1220 0 0         RETVAL = self->max_size;
1221             OUTPUT:
1222             RETVAL
1223              
1224             UV
1225             ttl(SV* self_sv)
1226             CODE:
1227 0 0         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    0          
    0          
1228 0 0         RETVAL = (UV)self->default_ttl;
1229             OUTPUT:
1230             RETVAL
1231              
1232             void
1233             keys(SV* self_sv)
1234             PPCODE:
1235 2 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1236 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1237 2 50         EXTEND(SP, self->size);
1238             size_t i;
1239 34 100         for (i = 0; i < self->capacity; i++) {
1240 32 100         if (IS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
1241 2 50         mXPUSHi(self->nodes[i].key);
1242             }
1243              
1244             void
1245             values(SV* self_sv)
1246             PPCODE:
1247 1 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1248 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1249 1 50         EXTEND(SP, self->size);
1250             size_t i;
1251 17 100         for (i = 0; i < self->capacity; i++) {
1252 16 100         if (IS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1253 2 50         if (self->nodes[i].value) {
1254 2           SV* sv = newSVpvn(self->nodes[i].value,
1255             HM_UNPACK_LEN(self->nodes[i].val_len));
1256 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
1257 2 50         mXPUSHs(sv);
1258             } else {
1259 0 0         XPUSHs(&PL_sv_undef);
1260             }
1261             }
1262             }
1263              
1264             void
1265             items(SV* self_sv)
1266             PPCODE:
1267 1 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1268 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1269 1 50         EXTEND(SP, self->size * 2);
1270             size_t i;
1271 17 100         for (i = 0; i < self->capacity; i++) {
1272 16 100         if (IS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1273 2 50         mXPUSHi(self->nodes[i].key);
1274 2 50         if (self->nodes[i].value) {
1275 2           SV* sv = newSVpvn(self->nodes[i].value,
1276             HM_UNPACK_LEN(self->nodes[i].val_len));
1277 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
1278 2 50         mXPUSHs(sv);
1279             } else {
1280 0 0         XPUSHs(&PL_sv_undef);
1281             }
1282             }
1283             }
1284              
1285             void
1286             each(SV* self_sv)
1287             PPCODE:
1288 3 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1289 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1290 17 100         while (self->iter_pos < self->capacity) {
1291 16           size_t i = self->iter_pos++;
1292 16 100         if (IS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1293 2 50         EXTEND(SP, 2);
1294 2 50         mXPUSHi(self->nodes[i].key);
1295 2 50         if (self->nodes[i].value) {
1296 2           SV* vsv = newSVpvn(self->nodes[i].value,
1297             HM_UNPACK_LEN(self->nodes[i].val_len));
1298 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(vsv);
1299 2 50         mXPUSHs(vsv);
1300             } else {
1301 0 0         XPUSHs(&PL_sv_undef);
1302             }
1303 2           XSRETURN(2);
1304             }
1305             }
1306 1           self->iter_pos = 0;
1307 1           XSRETURN_EMPTY;
1308              
1309             void
1310             iter_reset(SV* self_sv)
1311             CODE:
1312 0 0         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    0          
    0          
1313 0           self->iter_pos = 0;
1314              
1315             void
1316             clear(SV* self_sv)
1317             CODE:
1318 0 0         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    0          
    0          
1319 0           hashmap_is_clear(self);
1320              
1321             SV*
1322             to_hash(SV* self_sv)
1323             CODE:
1324 1 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1325 1           HV* hv = newHV();
1326 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1327             size_t i;
1328 17 100         for (i = 0; i < self->capacity; i++) {
1329 16 100         if (IS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1330 1           uint32_t vlen = HM_UNPACK_LEN(self->nodes[i].val_len);
1331 1           bool vutf8 = HM_UNPACK_UTF8(self->nodes[i].val_len);
1332 2           SV* val = self->nodes[i].value
1333 1           ? newSVpvn(self->nodes[i].value, vlen)
1334 1 50         : newSV(0);
1335 1 50         if (self->nodes[i].value && vutf8) SvUTF8_on(val);
    50          
1336             char kbuf[24];
1337 1           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
1338 1           (void)hv_store(hv, kbuf, klen, val, 0);
1339             }
1340             }
1341 1           RETVAL = newRV_noinc((SV*)hv);
1342             OUTPUT:
1343             RETVAL
1344              
1345             bool
1346             put_ttl(SV* self_sv, int64_t key, SV* value, UV ttl)
1347             CODE:
1348 0 0         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    0          
    0          
1349 0 0         EXTRACT_STR_VAL(value);
1350 0           RETVAL = hashmap_is_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, (uint32_t)ttl);
1351             OUTPUT:
1352             RETVAL
1353              
1354             SV*
1355             get_or_set(SV* self_sv, int64_t key, SV* default_sv)
1356             CODE:
1357 2 50         EXTRACT_MAP(HashMapIS, "Data::HashMap::IS", self_sv);
    50          
    50          
1358             const char* val; uint32_t val_len; bool val_utf8;
1359 2 100         if (hashmap_is_get(self, key, &val, &val_len, &val_utf8)) {
1360 1           RETVAL = newSVpvn(val, val_len);
1361 1 50         if (val_utf8) SvUTF8_on(RETVAL);
1362             } else {
1363 1 50         EXTRACT_STR_VAL(default_sv);
1364 1 50         if (!hashmap_is_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, 0))
1365 0           XSRETURN_UNDEF;
1366 1           RETVAL = SvREFCNT_inc(default_sv);
1367             }
1368             OUTPUT:
1369             RETVAL
1370              
1371              
1372              
1373             MODULE = Data::HashMap PACKAGE = Data::HashMap::SI
1374             PROTOTYPES: DISABLE
1375              
1376             SV*
1377             new(char* class, ...)
1378             CODE:
1379 18 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
1380 18           HashMapSI* map = hashmap_si_create(_max_size, _ttl);
1381 18 50         if (!map) croak("Failed to create HashMap::SI");
1382 18           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
1383             OUTPUT:
1384             RETVAL
1385              
1386             void
1387             DESTROY(SV* self_sv)
1388             CODE:
1389 18 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1390 18           hashmap_si_destroy(self);
1391 18           sv_setiv(SvRV(self_sv), 0);
1392              
1393             bool
1394             put(SV* self_sv, SV* key_sv, int64_t value)
1395             CODE:
1396 80022 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1397 80022 50         EXTRACT_STR_KEY(key_sv);
1398 80022           RETVAL = hashmap_si_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, value, 0);
1399             OUTPUT:
1400             RETVAL
1401              
1402             SV*
1403             get(SV* self_sv, SV* key_sv)
1404             CODE:
1405 50012 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1406 50012 50         EXTRACT_STR_KEY(key_sv);
1407             int64_t value;
1408 50012 100         if (!hashmap_si_get(self, _kstr, (uint32_t)_klen, _khash, &value))
1409 3           XSRETURN_UNDEF;
1410 50009           RETVAL = newSViv(value);
1411             OUTPUT:
1412             RETVAL
1413              
1414             bool
1415             remove(SV* self_sv, SV* key_sv)
1416             CODE:
1417 80004 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1418 80004 50         EXTRACT_STR_KEY(key_sv);
1419 80004           RETVAL = hashmap_si_remove(self, _kstr, (uint32_t)_klen, _khash);
1420             OUTPUT:
1421             RETVAL
1422              
1423             bool
1424             exists(SV* self_sv, SV* key_sv)
1425             CODE:
1426 2 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1427 2 50         EXTRACT_STR_KEY(key_sv);
1428 2           RETVAL = hashmap_si_exists(self, _kstr, (uint32_t)_klen, _khash);
1429             OUTPUT:
1430             RETVAL
1431              
1432             SV*
1433             incr(SV* self_sv, SV* key_sv)
1434             CODE:
1435 15013 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1436 15013 50         EXTRACT_STR_KEY(key_sv);
1437             int64_t val;
1438 15013 100         if (!hashmap_si_increment(self, _kstr, (uint32_t)_klen, _khash, _kutf8, &val))
1439 1           croak("HashMap::SI: increment failed");
1440 15012           RETVAL = newSViv(val);
1441             OUTPUT:
1442             RETVAL
1443              
1444             SV*
1445             decr(SV* self_sv, SV* key_sv)
1446             CODE:
1447 5004 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1448 5004 50         EXTRACT_STR_KEY(key_sv);
1449             int64_t val;
1450 5004 100         if (!hashmap_si_decrement(self, _kstr, (uint32_t)_klen, _khash, _kutf8, &val))
1451 1           croak("HashMap::SI: decrement failed");
1452 5003           RETVAL = newSViv(val);
1453             OUTPUT:
1454             RETVAL
1455              
1456             SV*
1457             incr_by(SV* self_sv, SV* key_sv, int64_t delta)
1458             CODE:
1459 6 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1460 6 50         EXTRACT_STR_KEY(key_sv);
1461             int64_t val;
1462 6 100         if (!hashmap_si_increment_by(self, _kstr, (uint32_t)_klen, _khash, _kutf8, delta, &val))
1463 2           croak("HashMap::SI: incr_by failed");
1464 4           RETVAL = newSViv(val);
1465             OUTPUT:
1466             RETVAL
1467              
1468             size_t
1469             size(SV* self_sv)
1470             CODE:
1471 4 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1472 4 50         RETVAL = self->size;
1473             OUTPUT:
1474             RETVAL
1475              
1476             size_t
1477             max_size(SV* self_sv)
1478             CODE:
1479 0 0         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    0          
    0          
1480 0 0         RETVAL = self->max_size;
1481             OUTPUT:
1482             RETVAL
1483              
1484             UV
1485             ttl(SV* self_sv)
1486             CODE:
1487 0 0         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    0          
    0          
1488 0 0         RETVAL = (UV)self->default_ttl;
1489             OUTPUT:
1490             RETVAL
1491              
1492             void
1493             keys(SV* self_sv)
1494             PPCODE:
1495 3 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1496 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1497 3 50         EXTEND(SP, self->size);
1498             size_t i;
1499 51 100         for (i = 0; i < self->capacity; i++) {
1500 48 100         if (SI_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    50          
    0          
    0          
1501 7           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1502 7           SV* sv = newSVpvn(self->nodes[i].key, klen);
1503 7 100         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
1504 7 50         mXPUSHs(sv);
1505             }
1506             }
1507              
1508             void
1509             values(SV* self_sv)
1510             PPCODE:
1511 1 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1512 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1513 1 50         EXTEND(SP, self->size);
1514             size_t i;
1515 17 100         for (i = 0; i < self->capacity; i++) {
1516 16 100         if (SI_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
1517 2 50         mXPUSHi(self->nodes[i].value);
1518             }
1519              
1520             void
1521             items(SV* self_sv)
1522             PPCODE:
1523 2 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1524 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1525 2 50         EXTEND(SP, self->size * 2);
1526             size_t i;
1527 34 100         for (i = 0; i < self->capacity; i++) {
1528 32 100         if (SI_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    50          
    0          
    0          
1529 7           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1530 7           SV* sv = newSVpvn(self->nodes[i].key, klen);
1531 7 100         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
1532 7 50         mXPUSHs(sv);
1533 7 50         mXPUSHi(self->nodes[i].value);
1534             }
1535             }
1536              
1537             void
1538             each(SV* self_sv)
1539             PPCODE:
1540 3 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1541 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1542 17 100         while (self->iter_pos < self->capacity) {
1543 16           size_t i = self->iter_pos++;
1544 16 100         if (SI_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1545 2 50         EXTEND(SP, 2);
1546             {
1547 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1548 2           SV* ksv = newSVpvn(self->nodes[i].key, klen);
1549 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(ksv);
1550 2 50         mXPUSHs(ksv);
1551             }
1552 2 50         mXPUSHi(self->nodes[i].value);
1553 2           XSRETURN(2);
1554             }
1555             }
1556 1           self->iter_pos = 0;
1557 1           XSRETURN_EMPTY;
1558              
1559             void
1560             iter_reset(SV* self_sv)
1561             CODE:
1562 0 0         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    0          
    0          
1563 0           self->iter_pos = 0;
1564              
1565             void
1566             clear(SV* self_sv)
1567             CODE:
1568 0 0         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    0          
    0          
1569 0           hashmap_si_clear(self);
1570              
1571             SV*
1572             to_hash(SV* self_sv)
1573             CODE:
1574 1 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1575 1           HV* hv = newHV();
1576 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1577             size_t i;
1578 17 100         for (i = 0; i < self->capacity; i++) {
1579 16 100         if (SI_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1580 1           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1581 1           bool kutf8 = HM_UNPACK_UTF8(self->nodes[i].key_len);
1582 1           SV* val = newSViv(self->nodes[i].value);
1583 1 50         (void)hv_store(hv, self->nodes[i].key, kutf8 ? -(I32)klen : (I32)klen, val, 0);
1584             }
1585             }
1586 1           RETVAL = newRV_noinc((SV*)hv);
1587             OUTPUT:
1588             RETVAL
1589              
1590             bool
1591             put_ttl(SV* self_sv, SV* key_sv, int64_t value, UV ttl)
1592             CODE:
1593 0 0         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    0          
    0          
1594 0 0         EXTRACT_STR_KEY(key_sv);
1595 0           RETVAL = hashmap_si_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, value, (uint32_t)ttl);
1596             OUTPUT:
1597             RETVAL
1598              
1599             SV*
1600             get_or_set(SV* self_sv, SV* key_sv, int64_t default_value)
1601             CODE:
1602 2 50         EXTRACT_MAP(HashMapSI, "Data::HashMap::SI", self_sv);
    50          
    50          
1603 2 50         EXTRACT_STR_KEY(key_sv);
1604             int64_t value;
1605 2 100         if (hashmap_si_get(self, _kstr, (uint32_t)_klen, _khash, &value)) {
1606 1           RETVAL = newSViv(value);
1607             } else {
1608 1 50         if (!hashmap_si_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, default_value, 0))
1609 0           XSRETURN_UNDEF;
1610 1           RETVAL = newSViv(default_value);
1611             }
1612             OUTPUT:
1613             RETVAL
1614              
1615              
1616              
1617             MODULE = Data::HashMap PACKAGE = Data::HashMap::SS
1618             PROTOTYPES: DISABLE
1619              
1620             SV*
1621             new(char* class, ...)
1622             CODE:
1623 16 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
1624 16           HashMapSS* map = hashmap_ss_create(_max_size, _ttl);
1625 16 50         if (!map) croak("Failed to create HashMap::SS");
1626 16           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
1627             OUTPUT:
1628             RETVAL
1629              
1630             void
1631             DESTROY(SV* self_sv)
1632             CODE:
1633 16 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1634 16           hashmap_ss_destroy(self);
1635 16           sv_setiv(SvRV(self_sv), 0);
1636              
1637             bool
1638             put(SV* self_sv, SV* key_sv, SV* value)
1639             CODE:
1640 80024 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1641 80024 50         EXTRACT_STR_KEY(key_sv);
1642 80024 50         EXTRACT_STR_VAL(value);
1643 80024           RETVAL = hashmap_ss_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8,
1644             _vstr, (uint32_t)_vlen, _vutf8, 0);
1645             OUTPUT:
1646             RETVAL
1647              
1648             SV*
1649             get(SV* self_sv, SV* key_sv)
1650             CODE:
1651 50016 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1652 50016 50         EXTRACT_STR_KEY(key_sv);
1653             const char* val;
1654             uint32_t val_len;
1655             bool val_utf8;
1656 50016 100         if (!hashmap_ss_get(self, _kstr, (uint32_t)_klen, _khash, &val, &val_len, &val_utf8))
1657 5           XSRETURN_UNDEF;
1658 50011           RETVAL = newSVpvn(val, val_len);
1659 50011 100         if (val_utf8) SvUTF8_on(RETVAL);
1660             OUTPUT:
1661             RETVAL
1662              
1663             bool
1664             remove(SV* self_sv, SV* key_sv)
1665             CODE:
1666 80003 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1667 80003 50         EXTRACT_STR_KEY(key_sv);
1668 80003           RETVAL = hashmap_ss_remove(self, _kstr, (uint32_t)_klen, _khash);
1669             OUTPUT:
1670             RETVAL
1671              
1672             bool
1673             exists(SV* self_sv, SV* key_sv)
1674             CODE:
1675 2 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1676 2 50         EXTRACT_STR_KEY(key_sv);
1677 2           RETVAL = hashmap_ss_exists(self, _kstr, (uint32_t)_klen, _khash);
1678             OUTPUT:
1679             RETVAL
1680              
1681             size_t
1682             size(SV* self_sv)
1683             CODE:
1684 7 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1685 7 50         RETVAL = self->size;
1686             OUTPUT:
1687             RETVAL
1688              
1689             size_t
1690             max_size(SV* self_sv)
1691             CODE:
1692 0 0         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    0          
    0          
1693 0 0         RETVAL = self->max_size;
1694             OUTPUT:
1695             RETVAL
1696              
1697             UV
1698             ttl(SV* self_sv)
1699             CODE:
1700 0 0         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    0          
    0          
1701 0 0         RETVAL = (UV)self->default_ttl;
1702             OUTPUT:
1703             RETVAL
1704              
1705             void
1706             keys(SV* self_sv)
1707             PPCODE:
1708 3 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1709 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1710 3 50         EXTEND(SP, self->size);
1711             size_t i;
1712 51 100         for (i = 0; i < self->capacity; i++) {
1713 48 100         if (SS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    50          
    0          
    0          
1714 6           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1715 6           SV* sv = newSVpvn(self->nodes[i].key, klen);
1716 6 100         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
1717 6 50         mXPUSHs(sv);
1718             }
1719             }
1720              
1721             void
1722             values(SV* self_sv)
1723             PPCODE:
1724 1 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1725 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1726 1 50         EXTEND(SP, self->size);
1727             size_t i;
1728 17 100         for (i = 0; i < self->capacity; i++) {
1729 16 100         if (SS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1730 2 50         if (self->nodes[i].value) {
1731 2           SV* sv = newSVpvn(self->nodes[i].value,
1732             HM_UNPACK_LEN(self->nodes[i].val_len));
1733 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
1734 2 50         mXPUSHs(sv);
1735             } else {
1736 0 0         XPUSHs(&PL_sv_undef);
1737             }
1738             }
1739             }
1740              
1741             void
1742             items(SV* self_sv)
1743             PPCODE:
1744 1 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1745 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1746 1 50         EXTEND(SP, self->size * 2);
1747             size_t i;
1748 17 100         for (i = 0; i < self->capacity; i++) {
1749 16 100         if (SS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1750 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1751 2           SV* sv = newSVpvn(self->nodes[i].key, klen);
1752 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
1753 2 50         mXPUSHs(sv);
1754 2 50         if (self->nodes[i].value) {
1755 2           SV* vsv = newSVpvn(self->nodes[i].value,
1756             HM_UNPACK_LEN(self->nodes[i].val_len));
1757 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(vsv);
1758 2 50         mXPUSHs(vsv);
1759             } else {
1760 0 0         XPUSHs(&PL_sv_undef);
1761             }
1762             }
1763             }
1764              
1765             void
1766             each(SV* self_sv)
1767             PPCODE:
1768 4 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1769 4 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1770 27 100         while (self->iter_pos < self->capacity) {
1771 26           size_t i = self->iter_pos++;
1772 26 100         if (SS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1773 3 50         EXTEND(SP, 2);
1774             {
1775 3           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1776 3           SV* ksv = newSVpvn(self->nodes[i].key, klen);
1777 3 100         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(ksv);
1778 3 50         mXPUSHs(ksv);
1779             }
1780 3 50         if (self->nodes[i].value) {
1781 3           SV* vsv = newSVpvn(self->nodes[i].value,
1782             HM_UNPACK_LEN(self->nodes[i].val_len));
1783 3 100         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(vsv);
1784 3 50         mXPUSHs(vsv);
1785             } else {
1786 0 0         XPUSHs(&PL_sv_undef);
1787             }
1788 3           XSRETURN(2);
1789             }
1790             }
1791 1           self->iter_pos = 0;
1792 1           XSRETURN_EMPTY;
1793              
1794             void
1795             iter_reset(SV* self_sv)
1796             CODE:
1797 0 0         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    0          
    0          
1798 0           self->iter_pos = 0;
1799              
1800             void
1801             clear(SV* self_sv)
1802             CODE:
1803 1 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1804 1           hashmap_ss_clear(self);
1805              
1806             SV*
1807             to_hash(SV* self_sv)
1808             CODE:
1809 2 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1810 2           HV* hv = newHV();
1811 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1812             size_t i;
1813 34 100         for (i = 0; i < self->capacity; i++) {
1814 32 100         if (SS_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1815 3           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
1816 3           bool kutf8 = HM_UNPACK_UTF8(self->nodes[i].key_len);
1817 3           uint32_t vlen = HM_UNPACK_LEN(self->nodes[i].val_len);
1818 3           bool vutf8 = HM_UNPACK_UTF8(self->nodes[i].val_len);
1819 6           SV* val = self->nodes[i].value
1820 3           ? newSVpvn(self->nodes[i].value, vlen)
1821 3 50         : newSV(0);
1822 3 50         if (self->nodes[i].value && vutf8) SvUTF8_on(val);
    100          
1823 3 100         (void)hv_store(hv, self->nodes[i].key, kutf8 ? -(I32)klen : (I32)klen, val, 0);
1824             }
1825             }
1826 2           RETVAL = newRV_noinc((SV*)hv);
1827             OUTPUT:
1828             RETVAL
1829              
1830             bool
1831             put_ttl(SV* self_sv, SV* key_sv, SV* value, UV ttl)
1832             CODE:
1833 2 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1834 2 50         EXTRACT_STR_KEY(key_sv);
1835 2 50         EXTRACT_STR_VAL(value);
1836 2           RETVAL = hashmap_ss_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8,
1837             _vstr, (uint32_t)_vlen, _vutf8, (uint32_t)ttl);
1838             OUTPUT:
1839             RETVAL
1840              
1841             SV*
1842             get_or_set(SV* self_sv, SV* key_sv, SV* default_sv)
1843             CODE:
1844 2 50         EXTRACT_MAP(HashMapSS, "Data::HashMap::SS", self_sv);
    50          
    50          
1845 2 50         EXTRACT_STR_KEY(key_sv);
1846             const char* val; uint32_t val_len; bool val_utf8;
1847 2 100         if (hashmap_ss_get(self, _kstr, (uint32_t)_klen, _khash, &val, &val_len, &val_utf8)) {
1848 1           RETVAL = newSVpvn(val, val_len);
1849 1 50         if (val_utf8) SvUTF8_on(RETVAL);
1850             } else {
1851 1 50         EXTRACT_STR_VAL(default_sv);
1852 1 50         if (!hashmap_ss_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8,
1853             _vstr, (uint32_t)_vlen, _vutf8, 0))
1854 0           XSRETURN_UNDEF;
1855 1           RETVAL = SvREFCNT_inc(default_sv);
1856             }
1857             OUTPUT:
1858             RETVAL
1859              
1860              
1861              
1862             MODULE = Data::HashMap PACKAGE = Data::HashMap::I32S
1863             PROTOTYPES: DISABLE
1864              
1865             SV*
1866             new(char* class, ...)
1867             CODE:
1868 8 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    50          
1869 8           HashMapI32S* map = hashmap_i32s_create(_max_size, _ttl);
1870 8 50         if (!map) croak("Failed to create HashMap::I32S");
1871 8           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
1872             OUTPUT:
1873             RETVAL
1874              
1875             void
1876             DESTROY(SV* self_sv)
1877             CODE:
1878 8 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1879 8           hashmap_i32s_destroy(self);
1880 8           sv_setiv(SvRV(self_sv), 0);
1881              
1882             bool
1883             put(SV* self_sv, int32_t key, SV* value)
1884             CODE:
1885 80015 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1886 80015 50         EXTRACT_STR_VAL(value);
1887 80015           RETVAL = hashmap_i32s_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, 0);
1888             OUTPUT:
1889             RETVAL
1890              
1891             SV*
1892             get(SV* self_sv, int32_t key)
1893             CODE:
1894 50008 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1895             const char* val;
1896             uint32_t val_len;
1897             bool val_utf8;
1898 50008 100         if (!hashmap_i32s_get(self, key, &val, &val_len, &val_utf8))
1899 3           XSRETURN_UNDEF;
1900 50005           RETVAL = newSVpvn(val, val_len);
1901 50005 100         if (val_utf8) SvUTF8_on(RETVAL);
1902             OUTPUT:
1903             RETVAL
1904              
1905             bool
1906             remove(SV* self_sv, int32_t key)
1907             CODE:
1908 80004 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1909 80004           RETVAL = hashmap_i32s_remove(self, key);
1910             OUTPUT:
1911             RETVAL
1912              
1913             bool
1914             exists(SV* self_sv, int32_t key)
1915             CODE:
1916 3 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1917 3           RETVAL = hashmap_i32s_exists(self, key);
1918             OUTPUT:
1919             RETVAL
1920              
1921             size_t
1922             size(SV* self_sv)
1923             CODE:
1924 6 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1925 6 50         RETVAL = self->size;
1926             OUTPUT:
1927             RETVAL
1928              
1929             size_t
1930             max_size(SV* self_sv)
1931             CODE:
1932 0 0         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    0          
    0          
1933 0 0         RETVAL = self->max_size;
1934             OUTPUT:
1935             RETVAL
1936              
1937             UV
1938             ttl(SV* self_sv)
1939             CODE:
1940 0 0         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    0          
    0          
1941 0 0         RETVAL = (UV)self->default_ttl;
1942             OUTPUT:
1943             RETVAL
1944              
1945             void
1946             keys(SV* self_sv)
1947             PPCODE:
1948 2 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1949 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1950 2 50         EXTEND(SP, self->size);
1951             size_t i;
1952 34 100         for (i = 0; i < self->capacity; i++) {
1953 32 100         if (I32S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
1954 2 50         mXPUSHi(self->nodes[i].key);
1955             }
1956              
1957             void
1958             values(SV* self_sv)
1959             PPCODE:
1960 1 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1961 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1962 1 50         EXTEND(SP, self->size);
1963             size_t i;
1964 17 100         for (i = 0; i < self->capacity; i++) {
1965 16 100         if (I32S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1966 2 50         if (self->nodes[i].value) {
1967 2           SV* sv = newSVpvn(self->nodes[i].value,
1968             HM_UNPACK_LEN(self->nodes[i].val_len));
1969 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
1970 2 50         mXPUSHs(sv);
1971             } else {
1972 0 0         XPUSHs(&PL_sv_undef);
1973             }
1974             }
1975             }
1976              
1977             void
1978             items(SV* self_sv)
1979             PPCODE:
1980 1 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
1981 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
1982 1 50         EXTEND(SP, self->size * 2);
1983             size_t i;
1984 17 100         for (i = 0; i < self->capacity; i++) {
1985 16 100         if (I32S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
1986 2 50         mXPUSHi(self->nodes[i].key);
1987 2 50         if (self->nodes[i].value) {
1988 2           SV* sv = newSVpvn(self->nodes[i].value,
1989             HM_UNPACK_LEN(self->nodes[i].val_len));
1990 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
1991 2 50         mXPUSHs(sv);
1992             } else {
1993 0 0         XPUSHs(&PL_sv_undef);
1994             }
1995             }
1996             }
1997              
1998             void
1999             each(SV* self_sv)
2000             PPCODE:
2001 3 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
2002 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2003 17 100         while (self->iter_pos < self->capacity) {
2004 16           size_t i = self->iter_pos++;
2005 16 100         if (I32S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2006 2 50         EXTEND(SP, 2);
2007 2 50         mXPUSHi(self->nodes[i].key);
2008 2 50         if (self->nodes[i].value) {
2009 2           SV* vsv = newSVpvn(self->nodes[i].value,
2010             HM_UNPACK_LEN(self->nodes[i].val_len));
2011 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(vsv);
2012 2 50         mXPUSHs(vsv);
2013             } else {
2014 0 0         XPUSHs(&PL_sv_undef);
2015             }
2016 2           XSRETURN(2);
2017             }
2018             }
2019 1           self->iter_pos = 0;
2020 1           XSRETURN_EMPTY;
2021              
2022             void
2023             iter_reset(SV* self_sv)
2024             CODE:
2025 0 0         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    0          
    0          
2026 0           self->iter_pos = 0;
2027              
2028             void
2029             clear(SV* self_sv)
2030             CODE:
2031 1 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
2032 1           hashmap_i32s_clear(self);
2033              
2034             SV*
2035             to_hash(SV* self_sv)
2036             CODE:
2037 1 50         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    50          
    50          
2038 1           HV* hv = newHV();
2039 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2040             size_t i;
2041 17 100         for (i = 0; i < self->capacity; i++) {
2042 16 100         if (I32S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2043 1           uint32_t vlen = HM_UNPACK_LEN(self->nodes[i].val_len);
2044 1           bool vutf8 = HM_UNPACK_UTF8(self->nodes[i].val_len);
2045 2           SV* val = self->nodes[i].value
2046 1           ? newSVpvn(self->nodes[i].value, vlen)
2047 1 50         : newSV(0);
2048 1 50         if (self->nodes[i].value && vutf8) SvUTF8_on(val);
    50          
2049             char kbuf[24];
2050 1           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
2051 1           (void)hv_store(hv, kbuf, klen, val, 0);
2052             }
2053             }
2054 1           RETVAL = newRV_noinc((SV*)hv);
2055             OUTPUT:
2056             RETVAL
2057              
2058             bool
2059             put_ttl(SV* self_sv, int32_t key, SV* value, UV ttl)
2060             CODE:
2061 0 0         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    0          
    0          
2062 0 0         EXTRACT_STR_VAL(value);
2063 0           RETVAL = hashmap_i32s_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, (uint32_t)ttl);
2064             OUTPUT:
2065             RETVAL
2066              
2067             SV*
2068             get_or_set(SV* self_sv, int32_t key, SV* default_sv)
2069             CODE:
2070 0 0         EXTRACT_MAP(HashMapI32S, "Data::HashMap::I32S", self_sv);
    0          
    0          
2071             const char* val; uint32_t val_len; bool val_utf8;
2072 0 0         if (hashmap_i32s_get(self, key, &val, &val_len, &val_utf8)) {
2073 0           RETVAL = newSVpvn(val, val_len);
2074 0 0         if (val_utf8) SvUTF8_on(RETVAL);
2075             } else {
2076 0 0         EXTRACT_STR_VAL(default_sv);
2077 0 0         if (!hashmap_i32s_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, 0))
2078 0           XSRETURN_UNDEF;
2079 0           RETVAL = SvREFCNT_inc(default_sv);
2080             }
2081             OUTPUT:
2082             RETVAL
2083              
2084              
2085              
2086             MODULE = Data::HashMap PACKAGE = Data::HashMap::SI32
2087             PROTOTYPES: DISABLE
2088              
2089             SV*
2090             new(char* class, ...)
2091             CODE:
2092 12 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    50          
2093 12           HashMapSI32* map = hashmap_si32_create(_max_size, _ttl);
2094 12 50         if (!map) croak("Failed to create HashMap::SI32");
2095 12           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
2096             OUTPUT:
2097             RETVAL
2098              
2099             void
2100             DESTROY(SV* self_sv)
2101             CODE:
2102 12 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2103 12           hashmap_si32_destroy(self);
2104 12           sv_setiv(SvRV(self_sv), 0);
2105              
2106             bool
2107             put(SV* self_sv, SV* key_sv, int32_t value)
2108             CODE:
2109 80019 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2110 80019 50         EXTRACT_STR_KEY(key_sv);
2111 80019           RETVAL = hashmap_si32_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, value, 0);
2112             OUTPUT:
2113             RETVAL
2114              
2115             SV*
2116             get(SV* self_sv, SV* key_sv)
2117             CODE:
2118 50008 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2119 50008 50         EXTRACT_STR_KEY(key_sv);
2120             int32_t value;
2121 50008 100         if (!hashmap_si32_get(self, _kstr, (uint32_t)_klen, _khash, &value))
2122 2           XSRETURN_UNDEF;
2123 50006           RETVAL = newSViv(value);
2124             OUTPUT:
2125             RETVAL
2126              
2127             bool
2128             remove(SV* self_sv, SV* key_sv)
2129             CODE:
2130 80003 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2131 80003 50         EXTRACT_STR_KEY(key_sv);
2132 80003           RETVAL = hashmap_si32_remove(self, _kstr, (uint32_t)_klen, _khash);
2133             OUTPUT:
2134             RETVAL
2135              
2136             bool
2137             exists(SV* self_sv, SV* key_sv)
2138             CODE:
2139 2 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2140 2 50         EXTRACT_STR_KEY(key_sv);
2141 2           RETVAL = hashmap_si32_exists(self, _kstr, (uint32_t)_klen, _khash);
2142             OUTPUT:
2143             RETVAL
2144              
2145             SV*
2146             incr(SV* self_sv, SV* key_sv)
2147             CODE:
2148 10 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2149 10 50         EXTRACT_STR_KEY(key_sv);
2150             int32_t val;
2151 10 100         if (!hashmap_si32_increment(self, _kstr, (uint32_t)_klen, _khash, _kutf8, &val))
2152 1           croak("HashMap::SI32: increment failed");
2153 9           RETVAL = newSViv(val);
2154             OUTPUT:
2155             RETVAL
2156              
2157             SV*
2158             decr(SV* self_sv, SV* key_sv)
2159             CODE:
2160 3 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2161 3 50         EXTRACT_STR_KEY(key_sv);
2162             int32_t val;
2163 3 100         if (!hashmap_si32_decrement(self, _kstr, (uint32_t)_klen, _khash, _kutf8, &val))
2164 1           croak("HashMap::SI32: decrement failed");
2165 2           RETVAL = newSViv(val);
2166             OUTPUT:
2167             RETVAL
2168              
2169             SV*
2170             incr_by(SV* self_sv, SV* key_sv, int32_t delta)
2171             CODE:
2172 6 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2173 6 50         EXTRACT_STR_KEY(key_sv);
2174             int32_t val;
2175 6 100         if (!hashmap_si32_increment_by(self, _kstr, (uint32_t)_klen, _khash, _kutf8, delta, &val))
2176 2           croak("HashMap::SI32: incr_by failed");
2177 4           RETVAL = newSViv(val);
2178             OUTPUT:
2179             RETVAL
2180              
2181             size_t
2182             size(SV* self_sv)
2183             CODE:
2184 5 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2185 5 50         RETVAL = self->size;
2186             OUTPUT:
2187             RETVAL
2188              
2189             size_t
2190             max_size(SV* self_sv)
2191             CODE:
2192 0 0         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    0          
    0          
2193 0 0         RETVAL = self->max_size;
2194             OUTPUT:
2195             RETVAL
2196              
2197             UV
2198             ttl(SV* self_sv)
2199             CODE:
2200 0 0         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    0          
    0          
2201 0 0         RETVAL = (UV)self->default_ttl;
2202             OUTPUT:
2203             RETVAL
2204              
2205             void
2206             keys(SV* self_sv)
2207             PPCODE:
2208 3 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2209 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2210 3 50         EXTEND(SP, self->size);
2211             size_t i;
2212 51 100         for (i = 0; i < self->capacity; i++) {
2213 48 100         if (SI32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    50          
    0          
    0          
2214 7           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2215 7           SV* sv = newSVpvn(self->nodes[i].key, klen);
2216 7 100         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
2217 7 50         mXPUSHs(sv);
2218             }
2219             }
2220              
2221             void
2222             values(SV* self_sv)
2223             PPCODE:
2224 1 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2225 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2226 1 50         EXTEND(SP, self->size);
2227             size_t i;
2228 17 100         for (i = 0; i < self->capacity; i++) {
2229 16 100         if (SI32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
2230 2 50         mXPUSHi(self->nodes[i].value);
2231             }
2232              
2233             void
2234             items(SV* self_sv)
2235             PPCODE:
2236 2 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2237 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2238 2 50         EXTEND(SP, self->size * 2);
2239             size_t i;
2240 34 100         for (i = 0; i < self->capacity; i++) {
2241 32 100         if (SI32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    50          
    0          
    0          
2242 7           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2243 7           SV* sv = newSVpvn(self->nodes[i].key, klen);
2244 7 100         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
2245 7 50         mXPUSHs(sv);
2246 7 50         mXPUSHi(self->nodes[i].value);
2247             }
2248             }
2249              
2250             void
2251             each(SV* self_sv)
2252             PPCODE:
2253 3 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2254 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2255 17 100         while (self->iter_pos < self->capacity) {
2256 16           size_t i = self->iter_pos++;
2257 16 100         if (SI32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2258 2 50         EXTEND(SP, 2);
2259             {
2260 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2261 2           SV* ksv = newSVpvn(self->nodes[i].key, klen);
2262 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(ksv);
2263 2 50         mXPUSHs(ksv);
2264             }
2265 2 50         mXPUSHi(self->nodes[i].value);
2266 2           XSRETURN(2);
2267             }
2268             }
2269 1           self->iter_pos = 0;
2270 1           XSRETURN_EMPTY;
2271              
2272             void
2273             iter_reset(SV* self_sv)
2274             CODE:
2275 0 0         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    0          
    0          
2276 0           self->iter_pos = 0;
2277              
2278             void
2279             clear(SV* self_sv)
2280             CODE:
2281 0 0         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    0          
    0          
2282 0           hashmap_si32_clear(self);
2283              
2284             SV*
2285             to_hash(SV* self_sv)
2286             CODE:
2287 1 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2288 1           HV* hv = newHV();
2289 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2290             size_t i;
2291 17 100         for (i = 0; i < self->capacity; i++) {
2292 16 100         if (SI32_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2293 1           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2294 1           bool kutf8 = HM_UNPACK_UTF8(self->nodes[i].key_len);
2295 1           SV* val = newSViv(self->nodes[i].value);
2296 1 50         (void)hv_store(hv, self->nodes[i].key, kutf8 ? -(I32)klen : (I32)klen, val, 0);
2297             }
2298             }
2299 1           RETVAL = newRV_noinc((SV*)hv);
2300             OUTPUT:
2301             RETVAL
2302              
2303             bool
2304             put_ttl(SV* self_sv, SV* key_sv, int32_t value, UV ttl)
2305             CODE:
2306 0 0         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    0          
    0          
2307 0 0         EXTRACT_STR_KEY(key_sv);
2308 0           RETVAL = hashmap_si32_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, value, (uint32_t)ttl);
2309             OUTPUT:
2310             RETVAL
2311              
2312             SV*
2313             get_or_set(SV* self_sv, SV* key_sv, int32_t default_value)
2314             CODE:
2315 1 50         EXTRACT_MAP(HashMapSI32, "Data::HashMap::SI32", self_sv);
    50          
    50          
2316 1 50         EXTRACT_STR_KEY(key_sv);
2317             int32_t value;
2318 1 50         if (hashmap_si32_get(self, _kstr, (uint32_t)_klen, _khash, &value)) {
2319 0           RETVAL = newSViv(value);
2320             } else {
2321 1 50         if (!hashmap_si32_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, default_value, 0))
2322 0           XSRETURN_UNDEF;
2323 1           RETVAL = newSViv(default_value);
2324             }
2325             OUTPUT:
2326             RETVAL
2327              
2328              
2329              
2330             MODULE = Data::HashMap PACKAGE = Data::HashMap::I16
2331             PROTOTYPES: DISABLE
2332              
2333             SV*
2334             new(char* class, ...)
2335             CODE:
2336 15 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
2337 15           HashMapI16* map = hashmap_i16_create(_max_size, _ttl);
2338 15 50         if (!map) croak("Failed to create HashMap::I16");
2339 15           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
2340             OUTPUT:
2341             RETVAL
2342              
2343             void
2344             DESTROY(SV* self_sv)
2345             CODE:
2346 15 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2347 15           hashmap_i16_destroy(self);
2348 15           sv_setiv(SvRV(self_sv), 0);
2349              
2350             bool
2351             put(SV* self_sv, int16_t key, int16_t value)
2352             CODE:
2353 81025 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2354 81025           RETVAL = hashmap_i16_put(self, key, value, 0);
2355             OUTPUT:
2356             RETVAL
2357              
2358             SV*
2359             get(SV* self_sv, int16_t key)
2360             CODE:
2361 30012 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2362             int16_t value;
2363 30012 100         if (!hashmap_i16_get(self, key, &value)) XSRETURN_UNDEF;
2364 30006           RETVAL = newSViv(value);
2365             OUTPUT:
2366             RETVAL
2367              
2368             bool
2369             remove(SV* self_sv, int16_t key)
2370             CODE:
2371 80005 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2372 80005           RETVAL = hashmap_i16_remove(self, key);
2373             OUTPUT:
2374             RETVAL
2375              
2376             bool
2377             exists(SV* self_sv, int16_t key)
2378             CODE:
2379 4 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2380 4           RETVAL = hashmap_i16_exists(self, key);
2381             OUTPUT:
2382             RETVAL
2383              
2384             SV*
2385             incr(SV* self_sv, int16_t key)
2386             CODE:
2387 8 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2388             int16_t val;
2389 8 100         if (!hashmap_i16_increment(self, key, &val))
2390 2           croak("HashMap::I16: increment failed");
2391 6           RETVAL = newSViv(val);
2392             OUTPUT:
2393             RETVAL
2394              
2395             SV*
2396             decr(SV* self_sv, int16_t key)
2397             CODE:
2398 6 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2399             int16_t val;
2400 6 100         if (!hashmap_i16_decrement(self, key, &val))
2401 2           croak("HashMap::I16: decrement failed");
2402 4           RETVAL = newSViv(val);
2403             OUTPUT:
2404             RETVAL
2405              
2406             SV*
2407             incr_by(SV* self_sv, int16_t key, int16_t delta)
2408             CODE:
2409 8 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2410             int16_t val;
2411 8 100         if (!hashmap_i16_increment_by(self, key, delta, &val))
2412 2           croak("HashMap::I16: incr_by failed");
2413 6           RETVAL = newSViv(val);
2414             OUTPUT:
2415             RETVAL
2416              
2417             size_t
2418             size(SV* self_sv)
2419             CODE:
2420 8 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2421 8 50         RETVAL = self->size;
2422             OUTPUT:
2423             RETVAL
2424              
2425             size_t
2426             max_size(SV* self_sv)
2427             CODE:
2428 0 0         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    0          
    0          
2429 0 0         RETVAL = self->max_size;
2430             OUTPUT:
2431             RETVAL
2432              
2433             UV
2434             ttl(SV* self_sv)
2435             CODE:
2436 0 0         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    0          
    0          
2437 0 0         RETVAL = (UV)self->default_ttl;
2438             OUTPUT:
2439             RETVAL
2440              
2441             void
2442             keys(SV* self_sv)
2443             PPCODE:
2444 3 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2445 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2446 3 50         EXTEND(SP, self->size);
2447             size_t i;
2448 51 100         for (i = 0; i < self->capacity; i++) {
2449 48 100         if (I16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
2450 4 50         mXPUSHi(self->nodes[i].key);
2451             }
2452              
2453             void
2454             values(SV* self_sv)
2455             PPCODE:
2456 2 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2457 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2458 2 50         EXTEND(SP, self->size);
2459             size_t i;
2460 34 100         for (i = 0; i < self->capacity; i++) {
2461 32 100         if (I16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
2462 4 50         mXPUSHi(self->nodes[i].value);
2463             }
2464              
2465             void
2466             items(SV* self_sv)
2467             PPCODE:
2468 1 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2469 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2470 1 50         EXTEND(SP, self->size * 2);
2471             size_t i;
2472 17 100         for (i = 0; i < self->capacity; i++) {
2473 16 100         if (I16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2474 2 50         mXPUSHi(self->nodes[i].key);
2475 2 50         mXPUSHi(self->nodes[i].value);
2476             }
2477             }
2478              
2479             void
2480             each(SV* self_sv)
2481             PPCODE:
2482 3 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2483 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2484 17 100         while (self->iter_pos < self->capacity) {
2485 16           size_t i = self->iter_pos++;
2486 16 100         if (I16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2487 2 50         EXTEND(SP, 2);
2488 2 50         mXPUSHi(self->nodes[i].key);
2489 2 50         mXPUSHi(self->nodes[i].value);
2490 2           XSRETURN(2);
2491             }
2492             }
2493 1           self->iter_pos = 0;
2494 1           XSRETURN_EMPTY;
2495              
2496             void
2497             iter_reset(SV* self_sv)
2498             CODE:
2499 0 0         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    0          
    0          
2500 0           self->iter_pos = 0;
2501              
2502             void
2503             clear(SV* self_sv)
2504             CODE:
2505 1 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2506 1           hashmap_i16_clear(self);
2507              
2508             SV*
2509             to_hash(SV* self_sv)
2510             CODE:
2511 1 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2512 1           HV* hv = newHV();
2513 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2514             size_t i;
2515 17 100         for (i = 0; i < self->capacity; i++) {
2516 16 100         if (I16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2517 1           SV* val = newSViv(self->nodes[i].value);
2518             char kbuf[24];
2519 1           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
2520 1           (void)hv_store(hv, kbuf, klen, val, 0);
2521             }
2522             }
2523 1           RETVAL = newRV_noinc((SV*)hv);
2524             OUTPUT:
2525             RETVAL
2526              
2527             bool
2528             put_ttl(SV* self_sv, int16_t key, int16_t value, UV ttl)
2529             CODE:
2530 0 0         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    0          
    0          
2531 0           RETVAL = hashmap_i16_put(self, key, value, (uint32_t)ttl);
2532             OUTPUT:
2533             RETVAL
2534              
2535             SV*
2536             get_or_set(SV* self_sv, int16_t key, int16_t default_value)
2537             CODE:
2538 3 50         EXTRACT_MAP(HashMapI16, "Data::HashMap::I16", self_sv);
    50          
    50          
2539             int16_t value;
2540 3 100         if (hashmap_i16_get(self, key, &value)) {
2541 1           RETVAL = newSViv(value);
2542             } else {
2543 2 100         if (!hashmap_i16_put(self, key, default_value, 0))
2544 1           XSRETURN_UNDEF;
2545 1           RETVAL = newSViv(default_value);
2546             }
2547             OUTPUT:
2548             RETVAL
2549              
2550              
2551              
2552             MODULE = Data::HashMap PACKAGE = Data::HashMap::I16S
2553             PROTOTYPES: DISABLE
2554              
2555             SV*
2556             new(char* class, ...)
2557             CODE:
2558 8 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    50          
2559 8           HashMapI16S* map = hashmap_i16s_create(_max_size, _ttl);
2560 8 50         if (!map) croak("Failed to create HashMap::I16S");
2561 8           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
2562             OUTPUT:
2563             RETVAL
2564              
2565             void
2566             DESTROY(SV* self_sv)
2567             CODE:
2568 8 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2569 8           hashmap_i16s_destroy(self);
2570 8           sv_setiv(SvRV(self_sv), 0);
2571              
2572             bool
2573             put(SV* self_sv, int16_t key, SV* value)
2574             CODE:
2575 60014 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2576 60014 50         EXTRACT_STR_VAL(value);
2577 60014           RETVAL = hashmap_i16s_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, 0);
2578             OUTPUT:
2579             RETVAL
2580              
2581             SV*
2582             get(SV* self_sv, int16_t key)
2583             CODE:
2584 30007 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2585             const char* val;
2586             uint32_t val_len;
2587             bool val_utf8;
2588 30007 100         if (!hashmap_i16s_get(self, key, &val, &val_len, &val_utf8))
2589 3           XSRETURN_UNDEF;
2590 30004           RETVAL = newSVpvn(val, val_len);
2591 30004 100         if (val_utf8) SvUTF8_on(RETVAL);
2592             OUTPUT:
2593             RETVAL
2594              
2595             bool
2596             remove(SV* self_sv, int16_t key)
2597             CODE:
2598 60004 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2599 60004           RETVAL = hashmap_i16s_remove(self, key);
2600             OUTPUT:
2601             RETVAL
2602              
2603             bool
2604             exists(SV* self_sv, int16_t key)
2605             CODE:
2606 4 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2607 4           RETVAL = hashmap_i16s_exists(self, key);
2608             OUTPUT:
2609             RETVAL
2610              
2611             size_t
2612             size(SV* self_sv)
2613             CODE:
2614 8 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2615 8 50         RETVAL = self->size;
2616             OUTPUT:
2617             RETVAL
2618              
2619             size_t
2620             max_size(SV* self_sv)
2621             CODE:
2622 0 0         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    0          
    0          
2623 0 0         RETVAL = self->max_size;
2624             OUTPUT:
2625             RETVAL
2626              
2627             UV
2628             ttl(SV* self_sv)
2629             CODE:
2630 0 0         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    0          
    0          
2631 0 0         RETVAL = (UV)self->default_ttl;
2632             OUTPUT:
2633             RETVAL
2634              
2635             void
2636             keys(SV* self_sv)
2637             PPCODE:
2638 2 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2639 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2640 2 50         EXTEND(SP, self->size);
2641             size_t i;
2642 34 100         for (i = 0; i < self->capacity; i++) {
2643 32 100         if (I16S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
2644 2 50         mXPUSHi(self->nodes[i].key);
2645             }
2646              
2647             void
2648             values(SV* self_sv)
2649             PPCODE:
2650 1 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2651 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2652 1 50         EXTEND(SP, self->size);
2653             size_t i;
2654 17 100         for (i = 0; i < self->capacity; i++) {
2655 16 100         if (I16S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2656 2 50         if (self->nodes[i].value) {
2657 2           SV* sv = newSVpvn(self->nodes[i].value,
2658             HM_UNPACK_LEN(self->nodes[i].val_len));
2659 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
2660 2 50         mXPUSHs(sv);
2661             } else {
2662 0 0         XPUSHs(&PL_sv_undef);
2663             }
2664             }
2665             }
2666              
2667             void
2668             items(SV* self_sv)
2669             PPCODE:
2670 1 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2671 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2672 1 50         EXTEND(SP, self->size * 2);
2673             size_t i;
2674 17 100         for (i = 0; i < self->capacity; i++) {
2675 16 100         if (I16S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2676 2 50         mXPUSHi(self->nodes[i].key);
2677 2 50         if (self->nodes[i].value) {
2678 2           SV* sv = newSVpvn(self->nodes[i].value,
2679             HM_UNPACK_LEN(self->nodes[i].val_len));
2680 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(sv);
2681 2 50         mXPUSHs(sv);
2682             } else {
2683 0 0         XPUSHs(&PL_sv_undef);
2684             }
2685             }
2686             }
2687              
2688             void
2689             each(SV* self_sv)
2690             PPCODE:
2691 3 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2692 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2693 17 100         while (self->iter_pos < self->capacity) {
2694 16           size_t i = self->iter_pos++;
2695 16 100         if (I16S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2696 2 50         EXTEND(SP, 2);
2697 2 50         mXPUSHi(self->nodes[i].key);
2698 2 50         if (self->nodes[i].value) {
2699 2           SV* vsv = newSVpvn(self->nodes[i].value,
2700             HM_UNPACK_LEN(self->nodes[i].val_len));
2701 2 50         if (HM_UNPACK_UTF8(self->nodes[i].val_len)) SvUTF8_on(vsv);
2702 2 50         mXPUSHs(vsv);
2703             } else {
2704 0 0         XPUSHs(&PL_sv_undef);
2705             }
2706 2           XSRETURN(2);
2707             }
2708             }
2709 1           self->iter_pos = 0;
2710 1           XSRETURN_EMPTY;
2711              
2712             void
2713             iter_reset(SV* self_sv)
2714             CODE:
2715 0 0         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    0          
    0          
2716 0           self->iter_pos = 0;
2717              
2718             void
2719             clear(SV* self_sv)
2720             CODE:
2721 1 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2722 1           hashmap_i16s_clear(self);
2723              
2724             SV*
2725             to_hash(SV* self_sv)
2726             CODE:
2727 0 0         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    0          
    0          
2728 0           HV* hv = newHV();
2729 0 0         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2730             size_t i;
2731 0 0         for (i = 0; i < self->capacity; i++) {
2732 0 0         if (I16S_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    0          
    0          
    0          
    0          
2733 0           uint32_t vlen = HM_UNPACK_LEN(self->nodes[i].val_len);
2734 0           bool vutf8 = HM_UNPACK_UTF8(self->nodes[i].val_len);
2735 0           SV* val = self->nodes[i].value
2736 0           ? newSVpvn(self->nodes[i].value, vlen)
2737 0 0         : newSV(0);
2738 0 0         if (self->nodes[i].value && vutf8) SvUTF8_on(val);
    0          
2739             char kbuf[24];
2740 0           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
2741 0           (void)hv_store(hv, kbuf, klen, val, 0);
2742             }
2743             }
2744 0           RETVAL = newRV_noinc((SV*)hv);
2745             OUTPUT:
2746             RETVAL
2747              
2748             bool
2749             put_ttl(SV* self_sv, int16_t key, SV* value, UV ttl)
2750             CODE:
2751 0 0         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    0          
    0          
2752 0 0         EXTRACT_STR_VAL(value);
2753 0           RETVAL = hashmap_i16s_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, (uint32_t)ttl);
2754             OUTPUT:
2755             RETVAL
2756              
2757             SV*
2758             get_or_set(SV* self_sv, int16_t key, SV* default_sv)
2759             CODE:
2760 1 50         EXTRACT_MAP(HashMapI16S, "Data::HashMap::I16S", self_sv);
    50          
    50          
2761             const char* val; uint32_t val_len; bool val_utf8;
2762 1 50         if (hashmap_i16s_get(self, key, &val, &val_len, &val_utf8)) {
2763 0           RETVAL = newSVpvn(val, val_len);
2764 0 0         if (val_utf8) SvUTF8_on(RETVAL);
2765             } else {
2766 1 50         EXTRACT_STR_VAL(default_sv);
2767 1 50         if (!hashmap_i16s_put(self, key, _vstr, (uint32_t)_vlen, _vutf8, 0))
2768 0           XSRETURN_UNDEF;
2769 1           RETVAL = SvREFCNT_inc(default_sv);
2770             }
2771             OUTPUT:
2772             RETVAL
2773              
2774              
2775              
2776             MODULE = Data::HashMap PACKAGE = Data::HashMap::SI16
2777             PROTOTYPES: DISABLE
2778              
2779             SV*
2780             new(char* class, ...)
2781             CODE:
2782 11 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
2783 11           HashMapSI16* map = hashmap_si16_create(_max_size, _ttl);
2784 11 50         if (!map) croak("Failed to create HashMap::SI16");
2785 11           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
2786             OUTPUT:
2787             RETVAL
2788              
2789             void
2790             DESTROY(SV* self_sv)
2791             CODE:
2792 11 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2793 11           hashmap_si16_destroy(self);
2794 11           sv_setiv(SvRV(self_sv), 0);
2795              
2796             bool
2797             put(SV* self_sv, SV* key_sv, int16_t value)
2798             CODE:
2799 80019 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2800 80019 50         EXTRACT_STR_KEY(key_sv);
2801 80019           RETVAL = hashmap_si16_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, value, 0);
2802             OUTPUT:
2803             RETVAL
2804              
2805             SV*
2806             get(SV* self_sv, SV* key_sv)
2807             CODE:
2808 50008 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2809 50008 50         EXTRACT_STR_KEY(key_sv);
2810             int16_t value;
2811 50008 100         if (!hashmap_si16_get(self, _kstr, (uint32_t)_klen, _khash, &value))
2812 3           XSRETURN_UNDEF;
2813 50005           RETVAL = newSViv(value);
2814             OUTPUT:
2815             RETVAL
2816              
2817             bool
2818             remove(SV* self_sv, SV* key_sv)
2819             CODE:
2820 80003 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2821 80003 50         EXTRACT_STR_KEY(key_sv);
2822 80003           RETVAL = hashmap_si16_remove(self, _kstr, (uint32_t)_klen, _khash);
2823             OUTPUT:
2824             RETVAL
2825              
2826             bool
2827             exists(SV* self_sv, SV* key_sv)
2828             CODE:
2829 4 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2830 4 50         EXTRACT_STR_KEY(key_sv);
2831 4           RETVAL = hashmap_si16_exists(self, _kstr, (uint32_t)_klen, _khash);
2832             OUTPUT:
2833             RETVAL
2834              
2835             SV*
2836             incr(SV* self_sv, SV* key_sv)
2837             CODE:
2838 8 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2839 8 50         EXTRACT_STR_KEY(key_sv);
2840             int16_t val;
2841 8 100         if (!hashmap_si16_increment(self, _kstr, (uint32_t)_klen, _khash, _kutf8, &val))
2842 1           croak("HashMap::SI16: increment failed");
2843 7           RETVAL = newSViv(val);
2844             OUTPUT:
2845             RETVAL
2846              
2847             SV*
2848             decr(SV* self_sv, SV* key_sv)
2849             CODE:
2850 5 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2851 5 50         EXTRACT_STR_KEY(key_sv);
2852             int16_t val;
2853 5 100         if (!hashmap_si16_decrement(self, _kstr, (uint32_t)_klen, _khash, _kutf8, &val))
2854 1           croak("HashMap::SI16: decrement failed");
2855 4           RETVAL = newSViv(val);
2856             OUTPUT:
2857             RETVAL
2858              
2859             SV*
2860             incr_by(SV* self_sv, SV* key_sv, int16_t delta)
2861             CODE:
2862 6 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2863 6 50         EXTRACT_STR_KEY(key_sv);
2864             int16_t val;
2865 6 100         if (!hashmap_si16_increment_by(self, _kstr, (uint32_t)_klen, _khash, _kutf8, delta, &val))
2866 2           croak("HashMap::SI16: incr_by failed");
2867 4           RETVAL = newSViv(val);
2868             OUTPUT:
2869             RETVAL
2870              
2871             size_t
2872             size(SV* self_sv)
2873             CODE:
2874 6 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2875 6 50         RETVAL = self->size;
2876             OUTPUT:
2877             RETVAL
2878              
2879             size_t
2880             max_size(SV* self_sv)
2881             CODE:
2882 0 0         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    0          
    0          
2883 0 0         RETVAL = self->max_size;
2884             OUTPUT:
2885             RETVAL
2886              
2887             UV
2888             ttl(SV* self_sv)
2889             CODE:
2890 0 0         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    0          
    0          
2891 0 0         RETVAL = (UV)self->default_ttl;
2892             OUTPUT:
2893             RETVAL
2894              
2895             void
2896             keys(SV* self_sv)
2897             PPCODE:
2898 2 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2899 2 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2900 2 50         EXTEND(SP, self->size);
2901             size_t i;
2902 34 100         for (i = 0; i < self->capacity; i++) {
2903 32 100         if (SI16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2904 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2905 2           SV* sv = newSVpvn(self->nodes[i].key, klen);
2906 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
2907 2 50         mXPUSHs(sv);
2908             }
2909             }
2910              
2911             void
2912             values(SV* self_sv)
2913             PPCODE:
2914 1 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2915 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2916 1 50         EXTEND(SP, self->size);
2917             size_t i;
2918 17 100         for (i = 0; i < self->capacity; i++) {
2919 16 100         if (SI16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
2920 2 50         mXPUSHi(self->nodes[i].value);
2921             }
2922              
2923             void
2924             items(SV* self_sv)
2925             PPCODE:
2926 1 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2927 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2928 1 50         EXTEND(SP, self->size * 2);
2929             size_t i;
2930 17 100         for (i = 0; i < self->capacity; i++) {
2931 16 100         if (SI16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2932 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2933 2           SV* sv = newSVpvn(self->nodes[i].key, klen);
2934 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
2935 2 50         mXPUSHs(sv);
2936 2 50         mXPUSHi(self->nodes[i].value);
2937             }
2938             }
2939              
2940             void
2941             each(SV* self_sv)
2942             PPCODE:
2943 3 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2944 3 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2945 17 100         while (self->iter_pos < self->capacity) {
2946 16           size_t i = self->iter_pos++;
2947 16 100         if (SI16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2948 2 50         EXTEND(SP, 2);
2949             {
2950 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2951 2           SV* ksv = newSVpvn(self->nodes[i].key, klen);
2952 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(ksv);
2953 2 50         mXPUSHs(ksv);
2954             }
2955 2 50         mXPUSHi(self->nodes[i].value);
2956 2           XSRETURN(2);
2957             }
2958             }
2959 1           self->iter_pos = 0;
2960 1           XSRETURN_EMPTY;
2961              
2962             void
2963             iter_reset(SV* self_sv)
2964             CODE:
2965 0 0         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    0          
    0          
2966 0           self->iter_pos = 0;
2967              
2968             void
2969             clear(SV* self_sv)
2970             CODE:
2971 0 0         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    0          
    0          
2972 0           hashmap_si16_clear(self);
2973              
2974             SV*
2975             to_hash(SV* self_sv)
2976             CODE:
2977 1 50         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    50          
    50          
2978 1           HV* hv = newHV();
2979 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
2980             size_t i;
2981 17 100         for (i = 0; i < self->capacity; i++) {
2982 16 100         if (SI16_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
2983 1           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
2984 1           bool kutf8 = HM_UNPACK_UTF8(self->nodes[i].key_len);
2985 1           SV* val = newSViv(self->nodes[i].value);
2986 1 50         (void)hv_store(hv, self->nodes[i].key, kutf8 ? -(I32)klen : (I32)klen, val, 0);
2987             }
2988             }
2989 1           RETVAL = newRV_noinc((SV*)hv);
2990             OUTPUT:
2991             RETVAL
2992              
2993             bool
2994             put_ttl(SV* self_sv, SV* key_sv, int16_t value, UV ttl)
2995             CODE:
2996 0 0         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    0          
    0          
2997 0 0         EXTRACT_STR_KEY(key_sv);
2998 0           RETVAL = hashmap_si16_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, value, (uint32_t)ttl);
2999             OUTPUT:
3000             RETVAL
3001              
3002             SV*
3003             get_or_set(SV* self_sv, SV* key_sv, int16_t default_value)
3004             CODE:
3005 0 0         EXTRACT_MAP(HashMapSI16, "Data::HashMap::SI16", self_sv);
    0          
    0          
3006 0 0         EXTRACT_STR_KEY(key_sv);
3007             int16_t value;
3008 0 0         if (hashmap_si16_get(self, _kstr, (uint32_t)_klen, _khash, &value)) {
3009 0           RETVAL = newSViv(value);
3010             } else {
3011 0 0         if (!hashmap_si16_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, default_value, 0))
3012 0           XSRETURN_UNDEF;
3013 0           RETVAL = newSViv(default_value);
3014             }
3015             OUTPUT:
3016             RETVAL
3017              
3018              
3019              
3020             MODULE = Data::HashMap PACKAGE = Data::HashMap::I32A
3021             PROTOTYPES: DISABLE
3022              
3023             SV*
3024             new(char* class, ...)
3025             CODE:
3026 10 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
3027 10           HashMapI32A* map = hashmap_i32a_create(_max_size, _ttl);
3028 10 50         if (!map) croak("Failed to create HashMap::I32A");
3029 10           map->free_value_fn = hm_sv_free;
3030 10           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
3031             OUTPUT:
3032             RETVAL
3033              
3034             void
3035             DESTROY(SV* self_sv)
3036             CODE:
3037 10 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3038 10           hashmap_i32a_destroy(self);
3039 10           sv_setiv(SvRV(self_sv), 0);
3040              
3041             bool
3042             put(SV* self_sv, int32_t key, SV* value)
3043             CODE:
3044 23 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3045 23           SvREFCNT_inc(value);
3046 23           RETVAL = hashmap_i32a_put(self, key, (void*)value, 0);
3047 23 100         if (!RETVAL) SvREFCNT_dec(value);
3048             OUTPUT:
3049             RETVAL
3050              
3051             SV*
3052             get(SV* self_sv, int32_t key)
3053             CODE:
3054 12 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3055             void* val;
3056 12 100         if (!hashmap_i32a_get(self, key, &val)) XSRETURN_UNDEF;
3057 9           RETVAL = SvREFCNT_inc((SV*)val);
3058             OUTPUT:
3059             RETVAL
3060              
3061             bool
3062             remove(SV* self_sv, int32_t key)
3063             CODE:
3064 3 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3065 3           RETVAL = hashmap_i32a_remove(self, key);
3066             OUTPUT:
3067             RETVAL
3068              
3069             bool
3070             exists(SV* self_sv, int32_t key)
3071             CODE:
3072 3 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3073 3           RETVAL = hashmap_i32a_exists(self, key);
3074             OUTPUT:
3075             RETVAL
3076              
3077             size_t
3078             size(SV* self_sv)
3079             CODE:
3080 6 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3081 6 50         RETVAL = self->size;
3082             OUTPUT:
3083             RETVAL
3084              
3085             size_t
3086             max_size(SV* self_sv)
3087             CODE:
3088 0 0         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    0          
    0          
3089 0 0         RETVAL = self->max_size;
3090             OUTPUT:
3091             RETVAL
3092              
3093             UV
3094             ttl(SV* self_sv)
3095             CODE:
3096 0 0         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    0          
    0          
3097 0 0         RETVAL = (UV)self->default_ttl;
3098             OUTPUT:
3099             RETVAL
3100              
3101             void
3102             keys(SV* self_sv)
3103             PPCODE:
3104 1 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3105 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3106 1 50         EXTEND(SP, self->size);
3107             size_t i;
3108 17 100         for (i = 0; i < self->capacity; i++) {
3109 16 100         if (I32A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
3110 2 50         mXPUSHi(self->nodes[i].key);
3111             }
3112              
3113             void
3114             values(SV* self_sv)
3115             PPCODE:
3116 1 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3117 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3118 1 50         EXTEND(SP, self->size);
3119             size_t i;
3120 17 100         for (i = 0; i < self->capacity; i++) {
3121 16 100         if (I32A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3122 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3123 2 50         mXPUSHs(sv);
3124             }
3125             }
3126              
3127             void
3128             items(SV* self_sv)
3129             PPCODE:
3130 1 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3131 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3132 1 50         EXTEND(SP, self->size * 2);
3133             size_t i;
3134 17 100         for (i = 0; i < self->capacity; i++) {
3135 16 100         if (I32A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3136 2 50         mXPUSHi(self->nodes[i].key);
3137 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3138 2 50         mXPUSHs(sv);
3139             }
3140             }
3141              
3142             void
3143             each(SV* self_sv)
3144             PPCODE:
3145 6 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3146 6 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3147 34 100         while (self->iter_pos < self->capacity) {
3148 32           size_t i = self->iter_pos++;
3149 32 100         if (I32A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3150 4 50         EXTEND(SP, 2);
3151 4 50         mXPUSHi(self->nodes[i].key);
3152 4 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3153 4 50         mXPUSHs(sv);
3154 4           XSRETURN(2);
3155             }
3156             }
3157 2           self->iter_pos = 0;
3158 2           XSRETURN_EMPTY;
3159              
3160             void
3161             iter_reset(SV* self_sv)
3162             CODE:
3163 0 0         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    0          
    0          
3164 0           self->iter_pos = 0;
3165              
3166             void
3167             clear(SV* self_sv)
3168             CODE:
3169 1 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3170 1           hashmap_i32a_clear(self);
3171              
3172             SV*
3173             to_hash(SV* self_sv)
3174             CODE:
3175 1 50         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    50          
    50          
3176 1           HV* hv = newHV();
3177 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3178             size_t i;
3179 17 100         for (i = 0; i < self->capacity; i++) {
3180 16 100         if (I32A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3181 1 50         SV* val = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3182             char kbuf[24];
3183 1           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
3184 1           (void)hv_store(hv, kbuf, klen, val, 0);
3185             }
3186             }
3187 1           RETVAL = newRV_noinc((SV*)hv);
3188             OUTPUT:
3189             RETVAL
3190              
3191             bool
3192             put_ttl(SV* self_sv, int32_t key, SV* value, UV ttl)
3193             CODE:
3194 0 0         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    0          
    0          
3195 0           SvREFCNT_inc(value);
3196 0           RETVAL = hashmap_i32a_put(self, key, (void*)value, (uint32_t)ttl);
3197 0 0         if (!RETVAL) SvREFCNT_dec(value);
3198             OUTPUT:
3199             RETVAL
3200              
3201             SV*
3202             get_or_set(SV* self_sv, int32_t key, SV* default_value)
3203             CODE:
3204 0 0         EXTRACT_MAP(HashMapI32A, "Data::HashMap::I32A", self_sv);
    0          
    0          
3205             void* val;
3206 0 0         if (hashmap_i32a_get(self, key, &val)) {
3207 0           RETVAL = SvREFCNT_inc((SV*)val);
3208             } else {
3209 0           SvREFCNT_inc(default_value);
3210 0 0         if (!hashmap_i32a_put(self, key, (void*)default_value, 0)) {
3211 0           SvREFCNT_dec(default_value);
3212 0           XSRETURN_UNDEF;
3213             }
3214 0           RETVAL = SvREFCNT_inc(default_value);
3215             }
3216             OUTPUT:
3217             RETVAL
3218              
3219              
3220              
3221             MODULE = Data::HashMap PACKAGE = Data::HashMap::I16A
3222             PROTOTYPES: DISABLE
3223              
3224             SV*
3225             new(char* class, ...)
3226             CODE:
3227 10 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
3228 10           HashMapI16A* map = hashmap_i16a_create(_max_size, _ttl);
3229 10 50         if (!map) croak("Failed to create HashMap::I16A");
3230 10           map->free_value_fn = hm_sv_free;
3231 10           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
3232             OUTPUT:
3233             RETVAL
3234              
3235             void
3236             DESTROY(SV* self_sv)
3237             CODE:
3238 10 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3239 10           hashmap_i16a_destroy(self);
3240 10           sv_setiv(SvRV(self_sv), 0);
3241              
3242             bool
3243             put(SV* self_sv, int16_t key, SV* value)
3244             CODE:
3245 23 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3246 23           SvREFCNT_inc(value);
3247 23           RETVAL = hashmap_i16a_put(self, key, (void*)value, 0);
3248 23 100         if (!RETVAL) SvREFCNT_dec(value);
3249             OUTPUT:
3250             RETVAL
3251              
3252             SV*
3253             get(SV* self_sv, int16_t key)
3254             CODE:
3255 12 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3256             void* val;
3257 12 100         if (!hashmap_i16a_get(self, key, &val)) XSRETURN_UNDEF;
3258 9           RETVAL = SvREFCNT_inc((SV*)val);
3259             OUTPUT:
3260             RETVAL
3261              
3262             bool
3263             remove(SV* self_sv, int16_t key)
3264             CODE:
3265 3 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3266 3           RETVAL = hashmap_i16a_remove(self, key);
3267             OUTPUT:
3268             RETVAL
3269              
3270             bool
3271             exists(SV* self_sv, int16_t key)
3272             CODE:
3273 3 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3274 3           RETVAL = hashmap_i16a_exists(self, key);
3275             OUTPUT:
3276             RETVAL
3277              
3278             size_t
3279             size(SV* self_sv)
3280             CODE:
3281 6 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3282 6 50         RETVAL = self->size;
3283             OUTPUT:
3284             RETVAL
3285              
3286             size_t
3287             max_size(SV* self_sv)
3288             CODE:
3289 0 0         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    0          
    0          
3290 0 0         RETVAL = self->max_size;
3291             OUTPUT:
3292             RETVAL
3293              
3294             UV
3295             ttl(SV* self_sv)
3296             CODE:
3297 0 0         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    0          
    0          
3298 0 0         RETVAL = (UV)self->default_ttl;
3299             OUTPUT:
3300             RETVAL
3301              
3302             void
3303             keys(SV* self_sv)
3304             PPCODE:
3305 1 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3306 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3307 1 50         EXTEND(SP, self->size);
3308             size_t i;
3309 17 100         for (i = 0; i < self->capacity; i++) {
3310 16 100         if (I16A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    50          
    50          
    0          
    0          
3311 2 50         mXPUSHi(self->nodes[i].key);
3312             }
3313              
3314             void
3315             values(SV* self_sv)
3316             PPCODE:
3317 1 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3318 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3319 1 50         EXTEND(SP, self->size);
3320             size_t i;
3321 17 100         for (i = 0; i < self->capacity; i++) {
3322 16 100         if (I16A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3323 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3324 2 50         mXPUSHs(sv);
3325             }
3326             }
3327              
3328             void
3329             items(SV* self_sv)
3330             PPCODE:
3331 1 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3332 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3333 1 50         EXTEND(SP, self->size * 2);
3334             size_t i;
3335 17 100         for (i = 0; i < self->capacity; i++) {
3336 16 100         if (I16A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3337 2 50         mXPUSHi(self->nodes[i].key);
3338 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3339 2 50         mXPUSHs(sv);
3340             }
3341             }
3342              
3343             void
3344             each(SV* self_sv)
3345             PPCODE:
3346 6 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3347 6 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3348 34 100         while (self->iter_pos < self->capacity) {
3349 32           size_t i = self->iter_pos++;
3350 32 100         if (I16A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3351 4 50         EXTEND(SP, 2);
3352 4 50         mXPUSHi(self->nodes[i].key);
3353 4 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3354 4 50         mXPUSHs(sv);
3355 4           XSRETURN(2);
3356             }
3357             }
3358 2           self->iter_pos = 0;
3359 2           XSRETURN_EMPTY;
3360              
3361             void
3362             iter_reset(SV* self_sv)
3363             CODE:
3364 0 0         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    0          
    0          
3365 0           self->iter_pos = 0;
3366              
3367             void
3368             clear(SV* self_sv)
3369             CODE:
3370 1 50         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    50          
    50          
3371 1           hashmap_i16a_clear(self);
3372              
3373             SV*
3374             to_hash(SV* self_sv)
3375             CODE:
3376 0 0         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    0          
    0          
3377 0           HV* hv = newHV();
3378 0 0         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3379             size_t i;
3380 0 0         for (i = 0; i < self->capacity; i++) {
3381 0 0         if (I16A_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    0          
    0          
    0          
    0          
3382 0 0         SV* val = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3383             char kbuf[24];
3384 0           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
3385 0           (void)hv_store(hv, kbuf, klen, val, 0);
3386             }
3387             }
3388 0           RETVAL = newRV_noinc((SV*)hv);
3389             OUTPUT:
3390             RETVAL
3391              
3392             bool
3393             put_ttl(SV* self_sv, int16_t key, SV* value, UV ttl)
3394             CODE:
3395 0 0         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    0          
    0          
3396 0           SvREFCNT_inc(value);
3397 0           RETVAL = hashmap_i16a_put(self, key, (void*)value, (uint32_t)ttl);
3398 0 0         if (!RETVAL) SvREFCNT_dec(value);
3399             OUTPUT:
3400             RETVAL
3401              
3402             SV*
3403             get_or_set(SV* self_sv, int16_t key, SV* default_value)
3404             CODE:
3405 0 0         EXTRACT_MAP(HashMapI16A, "Data::HashMap::I16A", self_sv);
    0          
    0          
3406             void* val;
3407 0 0         if (hashmap_i16a_get(self, key, &val)) {
3408 0           RETVAL = SvREFCNT_inc((SV*)val);
3409             } else {
3410 0           SvREFCNT_inc(default_value);
3411 0 0         if (!hashmap_i16a_put(self, key, (void*)default_value, 0)) {
3412 0           SvREFCNT_dec(default_value);
3413 0           XSRETURN_UNDEF;
3414             }
3415 0           RETVAL = SvREFCNT_inc(default_value);
3416             }
3417             OUTPUT:
3418             RETVAL
3419              
3420              
3421              
3422             MODULE = Data::HashMap PACKAGE = Data::HashMap::IA
3423             PROTOTYPES: DISABLE
3424              
3425             SV*
3426             new(char* class, ...)
3427             CODE:
3428 15 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
3429 15           HashMapIA* map = hashmap_ia_create(_max_size, _ttl);
3430 15 50         if (!map) croak("Failed to create HashMap::IA");
3431 15           map->free_value_fn = hm_sv_free;
3432 15           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
3433             OUTPUT:
3434             RETVAL
3435              
3436             void
3437             DESTROY(SV* self_sv)
3438             CODE:
3439 15 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3440 15           hashmap_ia_destroy(self);
3441 15           sv_setiv(SvRV(self_sv), 0);
3442              
3443             bool
3444             put(SV* self_sv, int64_t key, SV* value)
3445             CODE:
3446 26 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3447 26           SvREFCNT_inc(value);
3448 26           RETVAL = hashmap_ia_put(self, key, (void*)value, 0);
3449 26 100         if (!RETVAL) SvREFCNT_dec(value);
3450             OUTPUT:
3451             RETVAL
3452              
3453             SV*
3454             get(SV* self_sv, int64_t key)
3455             CODE:
3456 16 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3457             void* val;
3458 16 100         if (!hashmap_ia_get(self, key, &val)) XSRETURN_UNDEF;
3459 11           RETVAL = SvREFCNT_inc((SV*)val);
3460             OUTPUT:
3461             RETVAL
3462              
3463             bool
3464             remove(SV* self_sv, int64_t key)
3465             CODE:
3466 3 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3467 3           RETVAL = hashmap_ia_remove(self, key);
3468             OUTPUT:
3469             RETVAL
3470              
3471             bool
3472             exists(SV* self_sv, int64_t key)
3473             CODE:
3474 4 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3475 4           RETVAL = hashmap_ia_exists(self, key);
3476             OUTPUT:
3477             RETVAL
3478              
3479             size_t
3480             size(SV* self_sv)
3481             CODE:
3482 6 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3483 6 50         RETVAL = self->size;
3484             OUTPUT:
3485             RETVAL
3486              
3487             size_t
3488             max_size(SV* self_sv)
3489             CODE:
3490 0 0         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    0          
    0          
3491 0 0         RETVAL = self->max_size;
3492             OUTPUT:
3493             RETVAL
3494              
3495             UV
3496             ttl(SV* self_sv)
3497             CODE:
3498 0 0         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    0          
    0          
3499 0 0         RETVAL = (UV)self->default_ttl;
3500             OUTPUT:
3501             RETVAL
3502              
3503             void
3504             keys(SV* self_sv)
3505             PPCODE:
3506 3 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3507 3 100         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3508 3 50         EXTEND(SP, self->size);
3509             size_t i;
3510 51 100         for (i = 0; i < self->capacity; i++) {
3511 48 100         if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now))
    100          
    100          
    50          
    50          
3512 2 50         mXPUSHi(self->nodes[i].key);
3513             }
3514              
3515             void
3516             values(SV* self_sv)
3517             PPCODE:
3518 1 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3519 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3520 1 50         EXTEND(SP, self->size);
3521             size_t i;
3522 17 100         for (i = 0; i < self->capacity; i++) {
3523 16 100         if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3524 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3525 2 50         mXPUSHs(sv);
3526             }
3527             }
3528              
3529             void
3530             items(SV* self_sv)
3531             PPCODE:
3532 1 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3533 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3534 1 50         EXTEND(SP, self->size * 2);
3535             size_t i;
3536 17 100         for (i = 0; i < self->capacity; i++) {
3537 16 100         if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3538 2 50         mXPUSHi(self->nodes[i].key);
3539 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3540 2 50         mXPUSHs(sv);
3541             }
3542             }
3543              
3544             void
3545             each(SV* self_sv)
3546             PPCODE:
3547 6 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3548 6 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3549 34 100         while (self->iter_pos < self->capacity) {
3550 32           size_t i = self->iter_pos++;
3551 32 100         if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3552 4 50         EXTEND(SP, 2);
3553 4 50         mXPUSHi(self->nodes[i].key);
3554 4 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3555 4 50         mXPUSHs(sv);
3556 4           XSRETURN(2);
3557             }
3558             }
3559 2           self->iter_pos = 0;
3560 2           XSRETURN_EMPTY;
3561              
3562             void
3563             iter_reset(SV* self_sv)
3564             CODE:
3565 0 0         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    0          
    0          
3566 0           self->iter_pos = 0;
3567              
3568             void
3569             clear(SV* self_sv)
3570             CODE:
3571 1 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3572 1           hashmap_ia_clear(self);
3573              
3574             SV*
3575             to_hash(SV* self_sv)
3576             CODE:
3577 1 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3578 1           HV* hv = newHV();
3579 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3580             size_t i;
3581 17 100         for (i = 0; i < self->capacity; i++) {
3582 16 100         if (IA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3583 1 50         SV* val = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3584             char kbuf[24];
3585 1           int klen = my_snprintf(kbuf, sizeof(kbuf), "%" IVdf, (IV)self->nodes[i].key);
3586 1           (void)hv_store(hv, kbuf, klen, val, 0);
3587             }
3588             }
3589 1           RETVAL = newRV_noinc((SV*)hv);
3590             OUTPUT:
3591             RETVAL
3592              
3593             bool
3594             put_ttl(SV* self_sv, int64_t key, SV* value, UV ttl)
3595             CODE:
3596 1 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3597 1           SvREFCNT_inc(value);
3598 1           RETVAL = hashmap_ia_put(self, key, (void*)value, (uint32_t)ttl);
3599 1 50         if (!RETVAL) SvREFCNT_dec(value);
3600             OUTPUT:
3601             RETVAL
3602              
3603             SV*
3604             get_or_set(SV* self_sv, int64_t key, SV* default_value)
3605             CODE:
3606 2 50         EXTRACT_MAP(HashMapIA, "Data::HashMap::IA", self_sv);
    50          
    50          
3607             void* val;
3608 2 100         if (hashmap_ia_get(self, key, &val)) {
3609 1           RETVAL = SvREFCNT_inc((SV*)val);
3610             } else {
3611 1           SvREFCNT_inc(default_value);
3612 1 50         if (!hashmap_ia_put(self, key, (void*)default_value, 0)) {
3613 0           SvREFCNT_dec(default_value);
3614 0           XSRETURN_UNDEF;
3615             }
3616 1           RETVAL = SvREFCNT_inc(default_value);
3617             }
3618             OUTPUT:
3619             RETVAL
3620              
3621              
3622              
3623             MODULE = Data::HashMap PACKAGE = Data::HashMap::SA
3624             PROTOTYPES: DISABLE
3625              
3626             SV*
3627             new(char* class, ...)
3628             CODE:
3629 17 100         EXTRACT_NEW_ARGS(_max_size, _ttl);
    100          
3630 17           HashMapSA* map = hashmap_sa_create(_max_size, _ttl);
3631 17 50         if (!map) croak("Failed to create HashMap::SA");
3632 17           map->free_value_fn = hm_sv_free;
3633 17           RETVAL = sv_setref_pv(newSV(0), class, (void*)map);
3634             OUTPUT:
3635             RETVAL
3636              
3637             void
3638             DESTROY(SV* self_sv)
3639             CODE:
3640 17 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3641 17           hashmap_sa_destroy(self);
3642 17           sv_setiv(SvRV(self_sv), 0);
3643              
3644             bool
3645             put(SV* self_sv, SV* key_sv, SV* value)
3646             CODE:
3647 27 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3648 27 50         EXTRACT_STR_KEY(key_sv);
3649 27           SvREFCNT_inc(value);
3650 27           RETVAL = hashmap_sa_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, (void*)value, 0);
3651 27 50         if (!RETVAL) SvREFCNT_dec(value);
3652             OUTPUT:
3653             RETVAL
3654              
3655             SV*
3656             get(SV* self_sv, SV* key_sv)
3657             CODE:
3658 18 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3659 18 50         EXTRACT_STR_KEY(key_sv);
3660             void* val;
3661 18 100         if (!hashmap_sa_get(self, _kstr, (uint32_t)_klen, _khash, &val))
3662 4           XSRETURN_UNDEF;
3663 14           RETVAL = SvREFCNT_inc((SV*)val);
3664             OUTPUT:
3665             RETVAL
3666              
3667             bool
3668             remove(SV* self_sv, SV* key_sv)
3669             CODE:
3670 3 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3671 3 50         EXTRACT_STR_KEY(key_sv);
3672 3           RETVAL = hashmap_sa_remove(self, _kstr, (uint32_t)_klen, _khash);
3673             OUTPUT:
3674             RETVAL
3675              
3676             bool
3677             exists(SV* self_sv, SV* key_sv)
3678             CODE:
3679 5 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3680 5 50         EXTRACT_STR_KEY(key_sv);
3681 5           RETVAL = hashmap_sa_exists(self, _kstr, (uint32_t)_klen, _khash);
3682             OUTPUT:
3683             RETVAL
3684              
3685             size_t
3686             size(SV* self_sv)
3687             CODE:
3688 6 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3689 6 50         RETVAL = self->size;
3690             OUTPUT:
3691             RETVAL
3692              
3693             size_t
3694             max_size(SV* self_sv)
3695             CODE:
3696 0 0         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    0          
    0          
3697 0 0         RETVAL = self->max_size;
3698             OUTPUT:
3699             RETVAL
3700              
3701             UV
3702             ttl(SV* self_sv)
3703             CODE:
3704 0 0         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    0          
    0          
3705 0 0         RETVAL = (UV)self->default_ttl;
3706             OUTPUT:
3707             RETVAL
3708              
3709             void
3710             keys(SV* self_sv)
3711             PPCODE:
3712 3 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3713 3 100         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3714 3 50         EXTEND(SP, self->size);
3715             size_t i;
3716 51 100         for (i = 0; i < self->capacity; i++) {
3717 48 100         if (SA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    100          
    100          
    50          
    50          
3718 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
3719 2           SV* sv = newSVpvn(self->nodes[i].key, klen);
3720 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(sv);
3721 2 50         mXPUSHs(sv);
3722             }
3723             }
3724              
3725             void
3726             values(SV* self_sv)
3727             PPCODE:
3728 1 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3729 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3730 1 50         EXTEND(SP, self->size);
3731             size_t i;
3732 17 100         for (i = 0; i < self->capacity; i++) {
3733 16 100         if (SA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3734 2 50         SV* sv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3735 2 50         mXPUSHs(sv);
3736             }
3737             }
3738              
3739             void
3740             items(SV* self_sv)
3741             PPCODE:
3742 1 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3743 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3744 1 50         EXTEND(SP, self->size * 2);
3745             size_t i;
3746 17 100         for (i = 0; i < self->capacity; i++) {
3747 16 100         if (SA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3748 2           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
3749 2           SV* ksv = newSVpvn(self->nodes[i].key, klen);
3750 2 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(ksv);
3751 2 50         mXPUSHs(ksv);
3752 2 50         SV* vsv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3753 2 50         mXPUSHs(vsv);
3754             }
3755             }
3756              
3757             void
3758             each(SV* self_sv)
3759             PPCODE:
3760 6 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3761 6 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3762 34 100         while (self->iter_pos < self->capacity) {
3763 32           size_t i = self->iter_pos++;
3764 32 100         if (SA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3765 4 50         EXTEND(SP, 2);
3766             {
3767 4           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
3768 4           SV* ksv = newSVpvn(self->nodes[i].key, klen);
3769 4 50         if (HM_UNPACK_UTF8(self->nodes[i].key_len)) SvUTF8_on(ksv);
3770 4 50         mXPUSHs(ksv);
3771             }
3772 4 50         SV* vsv = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3773 4 50         mXPUSHs(vsv);
3774 4           XSRETURN(2);
3775             }
3776             }
3777 2           self->iter_pos = 0;
3778 2           XSRETURN_EMPTY;
3779              
3780             void
3781             iter_reset(SV* self_sv)
3782             CODE:
3783 0 0         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    0          
    0          
3784 0           self->iter_pos = 0;
3785              
3786             void
3787             clear(SV* self_sv)
3788             CODE:
3789 1 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3790 1           hashmap_sa_clear(self);
3791              
3792             SV*
3793             to_hash(SV* self_sv)
3794             CODE:
3795 1 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3796 1           HV* hv = newHV();
3797 1 50         uint32_t now = self->expires_at ? (uint32_t)time(NULL) : 0;
3798             size_t i;
3799 17 100         for (i = 0; i < self->capacity; i++) {
3800 16 100         if (SA_NODE_LIVE(self->nodes[i]) && !HM_TTL_SKIP_EXPIRED(self, i, now)) {
    50          
    50          
    0          
    0          
3801 1           uint32_t klen = HM_UNPACK_LEN(self->nodes[i].key_len);
3802 1           bool kutf8 = HM_UNPACK_UTF8(self->nodes[i].key_len);
3803 1 50         SV* val = self->nodes[i].value ? SvREFCNT_inc((SV*)self->nodes[i].value) : &PL_sv_undef;
3804 1 50         (void)hv_store(hv, self->nodes[i].key, kutf8 ? -(I32)klen : (I32)klen, val, 0);
3805             }
3806             }
3807 1           RETVAL = newRV_noinc((SV*)hv);
3808             OUTPUT:
3809             RETVAL
3810              
3811             bool
3812             put_ttl(SV* self_sv, SV* key_sv, SV* value, UV ttl)
3813             CODE:
3814 1 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3815 1 50         EXTRACT_STR_KEY(key_sv);
3816 1           SvREFCNT_inc(value);
3817 1           RETVAL = hashmap_sa_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, (void*)value, (uint32_t)ttl);
3818 1 50         if (!RETVAL) SvREFCNT_dec(value);
3819             OUTPUT:
3820             RETVAL
3821              
3822             SV*
3823             get_or_set(SV* self_sv, SV* key_sv, SV* default_value)
3824             CODE:
3825 2 50         EXTRACT_MAP(HashMapSA, "Data::HashMap::SA", self_sv);
    50          
    50          
3826 2 50         EXTRACT_STR_KEY(key_sv);
3827             void* val;
3828 2 100         if (hashmap_sa_get(self, _kstr, (uint32_t)_klen, _khash, &val)) {
3829 1           RETVAL = SvREFCNT_inc((SV*)val);
3830             } else {
3831 1           SvREFCNT_inc(default_value);
3832 1 50         if (!hashmap_sa_put(self, _kstr, (uint32_t)_klen, _khash, _kutf8, (void*)default_value, 0)) {
3833 0           SvREFCNT_dec(default_value);
3834 0           XSRETURN_UNDEF;
3835             }
3836 1           RETVAL = SvREFCNT_inc(default_value);
3837             }
3838             OUTPUT:
3839             RETVAL
3840