Data-HashMap

 view release on metacpan or  search on metacpan

CLAUDE.md  view on Meta::CPAN

| `Data::HashMap::SA` | string | any SV* | ~32 bytes |
| `Data::HashMap::SI16` | string | int16 | ~24 bytes |
| `Data::HashMap::SI32` | string | int32 | ~24 bytes |
| `Data::HashMap::SI` | string | int64 | ~24 bytes |
| `Data::HashMap::SS` | string | string | ~32 bytes |

**Layer structure:**
- `lib/Data/HashMap.pm` — Main module, loads XS via XSLoader, POD documentation
- `lib/Data/HashMap/{I16,I16A,I16S,I32,I32A,I32S,IA,II,IS,SA,SI16,SI32,SI,SS}.pm` — Variant modules, enable keywords via `$^H` hints
- `HashMap.xs` — XS bindings + XS::Parse::Keyword integration for all 14 variants
- `hashmap_generic.h` — Macro-template C implementation (included 14 times with different defines)
- `hashmap_{i16,i16a,i16s,i32,i32a,i32s,ia,ii,is,sa,si16,si32,si,ss}.h` — Variant instantiation headers
- `typemap` — XS type mappings

**Key implementation details:**
- Open addressing with linear probing, xxHash-based hash functions
- Automatic resize at 75% load factor, initial capacity 16
- Tombstone deletion with automatic compaction (>25% tombstones or tombstones > live)
- Sentinel values for integer keys (INT_MIN, INT_MIN+1 are reserved)
- UTF-8 flag packed into high bit of uint32_t length fields
- OOM-safe put: all memory pre-allocated before modifying map state

HashMap.xs  view on Meta::CPAN

static const struct XSParseKeywordPieceType pieces_3expr[] = {
    XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, {0}
};
static const struct XSParseKeywordPieceType pieces_4expr[] = {
    XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, XPK_COMMA, XPK_TERMEXPR, {0}
};


/* ---- Keyword hook definitions ----
 *
 * Macro to define a keyword hook struct.
 * variant = i16, i16a, i16s, i32, i32a, i32s, ia, ii, is, sa, si16, si32, si, ss
 * kw = keyword name (e.g., put, get)
 * nargs = 1, 2, or 3
 * builder = build function (build_kw_1arg, build_kw_2arg, etc.)
 */
#define DEFINE_KW_HOOK(variant, PKG, kw, nargs, builder) \
    static const struct XSParseKeywordHooks hooks_hm_##variant##_##kw = { \
        .flags = XPK_FLAG_EXPR, \
        .permit_hintkey = "Data::HashMap::" PKG "/hm_" #variant "_" #kw, \
        .pieces = pieces_##nargs##expr, \

HashMap.xs  view on Meta::CPAN

DEFINE_KW_HOOK(sa, "SA", max_size, 1, build_kw_1arg)
DEFINE_KW_HOOK(sa, "SA", ttl,      1, build_kw_1arg)
DEFINE_KW_HOOK(sa, "SA", lru_skip, 1, build_kw_1arg)
DEFINE_KW_HOOK(sa, "SA", each,       1, build_kw_1arg_list)
DEFINE_KW_HOOK(sa, "SA", iter_reset, 1, build_kw_1arg)
DEFINE_KW_HOOK(sa, "SA", clear,      1, build_kw_1arg)
DEFINE_KW_HOOK(sa, "SA", to_hash,    1, build_kw_1arg)
DEFINE_KW_HOOK(sa, "SA", put_ttl,    4, build_kw_4arg)
DEFINE_KW_HOOK(sa, "SA", get_or_set, 3, build_kw_3arg)

/* ---- Macro to register a keyword ---- */
#define REGISTER_KW(variant, kw, func_name) \
    register_xs_parse_keyword("hm_" #variant "_" #kw, \
        &hooks_hm_##variant##_##kw, (void*)func_name)

/* ---- Live node checks ---- */
#define I16_NODE_LIVE(n)  ((n).key != INT16_MIN && (n).key != (INT16_MIN + 1))
#define I16S_NODE_LIVE(n) I16_NODE_LIVE(n)  /* I16S keys are int16_t */
#define I32_NODE_LIVE(n)  ((n).key != INT32_MIN && (n).key != (INT32_MIN + 1))
#define I32S_NODE_LIVE(n) I32_NODE_LIVE(n)  /* I32S keys are int32_t */
#define II_NODE_LIVE(n)   ((n).key != INT64_MIN && (n).key != (INT64_MIN + 1))

hashmap_generic.h  view on Meta::CPAN

/*
 * hashmap_generic.h — Macro-template for type-specialized hashmaps.
 *
 * Before including this file, define:
 *   HM_PREFIX      — function name prefix (e.g., hashmap_ii)
 *   HM_NODE_TYPE   — node struct name
 *   HM_MAP_TYPE    — map struct name
 *
 * Key type (choose one):
 *   HM_KEY_IS_INT  — define for integer keys
 *   (leave undefined for string keys: char* + uint32_t len + uint32_t hash)
 *

hashmap_generic.h  view on Meta::CPAN

 * Optional:
 *   HM_HAS_COUNTERS — define to generate incr/decr functions (int values only)
 */

#include <stdint.h>
#include <stdbool.h>
#include <stdlib.h>
#include <string.h>
#include <time.h>

/* ---- Macro helpers ---- */

#define HM_PASTE2(a, b)  a##_##b
#define HM_PASTE(a, b)   HM_PASTE2(a, b)
#define HM_FN(name)      HM_PASTE(HM_PREFIX, name)

/* ---- Integer type defaults ---- */

#ifndef HM_INT_TYPE
#define HM_INT_TYPE  int64_t
#define HM_INT_MIN   INT64_MIN

xxhash.h  view on Meta::CPAN

    return one.c[0];
}
#   define XXH_CPU_LITTLE_ENDIAN   XXH_isLittleEndian()
#  endif
#endif




/* ****************************************
*  Compiler-specific Functions and Macros
******************************************/
#define XXH_GCC_VERSION (__GNUC__ * 100 + __GNUC_MINOR__)

#ifdef __has_builtin
#  define XXH_HAS_BUILTIN(x) __has_builtin(x)
#else
#  define XXH_HAS_BUILTIN(x) 0
#endif




( run in 0.870 second using v1.01-cache-2.11-cpan-483215c6ad5 )