mirror of
https://github.com/attractivechaos/klib
synced 2025-01-15 15:09:19 +03:00
updated khashl to r30
This commit is contained in:
parent
2944549526
commit
ba6b352f2d
2
kexpr.c
2
kexpr.c
@ -553,11 +553,11 @@ int main(int argc, char *argv[])
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
ke = ke_parse(argv[optind], &err);
|
ke = ke_parse(argv[optind], &err);
|
||||||
ke_set_default_func(ke);
|
|
||||||
if (err) {
|
if (err) {
|
||||||
fprintf(stderr, "Parse error: 0x%x\n", err);
|
fprintf(stderr, "Parse error: 0x%x\n", err);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
ke_set_default_func(ke);
|
||||||
if (!to_print) {
|
if (!to_print) {
|
||||||
int64_t vi;
|
int64_t vi;
|
||||||
double vr;
|
double vr;
|
||||||
|
136
khashl.h
136
khashl.h
@ -1,6 +1,6 @@
|
|||||||
/* The MIT License
|
/* The MIT License
|
||||||
|
|
||||||
Copyright (c) 2019-2024 by Attractive Chaos <attractor@live.co.uk>
|
Copyright (c) 2019- by Attractive Chaos <attractor@live.co.uk>
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining
|
Permission is hereby granted, free of charge, to any person obtaining
|
||||||
a copy of this software and associated documentation files (the
|
a copy of this software and associated documentation files (the
|
||||||
@ -26,7 +26,7 @@
|
|||||||
#ifndef __AC_KHASHL_H
|
#ifndef __AC_KHASHL_H
|
||||||
#define __AC_KHASHL_H
|
#define __AC_KHASHL_H
|
||||||
|
|
||||||
#define AC_VERSION_KHASHL_H "r20"
|
#define AC_VERSION_KHASHL_H "r30"
|
||||||
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
@ -73,25 +73,19 @@ typedef const char *kh_cstr_t;
|
|||||||
* Configurable macros *
|
* Configurable macros *
|
||||||
***********************/
|
***********************/
|
||||||
|
|
||||||
#ifndef kh_max_count
|
#ifndef kh_max_count /* set the max load factor */
|
||||||
#define kh_max_count(cap) (((cap)>>1) + ((cap)>>2)) /* default load factor: 75% */
|
#define kh_max_count(cap) (((cap)>>1) + ((cap)>>2)) /* default load factor: 75% */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef kh_packed
|
#ifndef kh_packed /* pack the key-value struct */
|
||||||
#define kh_packed __attribute__ ((__packed__))
|
#define kh_packed __attribute__ ((__packed__))
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifndef kcalloc
|
#if !defined(Kmalloc) || !defined(Kcalloc) || !defined(Krealloc) || !defined(Kfree)
|
||||||
#define kcalloc(N,Z) calloc(N,Z)
|
#define Kmalloc(km, type, cnt) ((type*)malloc((cnt) * sizeof(type)))
|
||||||
#endif
|
#define Kcalloc(km, type, cnt) ((type*)calloc((cnt), sizeof(type)))
|
||||||
#ifndef kmalloc
|
#define Krealloc(km, type, ptr, cnt) ((type*)realloc((ptr), (cnt) * sizeof(type)))
|
||||||
#define kmalloc(Z) malloc(Z)
|
#define Kfree(km, ptr) free(ptr)
|
||||||
#endif
|
|
||||||
#ifndef krealloc
|
|
||||||
#define krealloc(P,Z) realloc(P,Z)
|
|
||||||
#endif
|
|
||||||
#ifndef kfree
|
|
||||||
#define kfree(P) free(P)
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/****************************
|
/****************************
|
||||||
@ -104,7 +98,7 @@ typedef const char *kh_cstr_t;
|
|||||||
|
|
||||||
#define __kh_fsize(m) ((m) < 32? 1 : (m)>>5)
|
#define __kh_fsize(m) ((m) < 32? 1 : (m)>>5)
|
||||||
|
|
||||||
static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 2654435769U >> (32 - bits); }
|
static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 2654435769U >> (32 - bits); } /* Fibonacci hashing */
|
||||||
|
|
||||||
/*******************
|
/*******************
|
||||||
* Hash table base *
|
* Hash table base *
|
||||||
@ -112,6 +106,7 @@ static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 26
|
|||||||
|
|
||||||
#define __KHASHL_TYPE(HType, khkey_t) \
|
#define __KHASHL_TYPE(HType, khkey_t) \
|
||||||
typedef struct HType { \
|
typedef struct HType { \
|
||||||
|
void *km; \
|
||||||
khint_t bits, count; \
|
khint_t bits, count; \
|
||||||
khint32_t *used; \
|
khint32_t *used; \
|
||||||
khkey_t *keys; \
|
khkey_t *keys; \
|
||||||
@ -119,6 +114,7 @@ static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 26
|
|||||||
|
|
||||||
#define __KHASHL_PROTOTYPES(HType, prefix, khkey_t) \
|
#define __KHASHL_PROTOTYPES(HType, prefix, khkey_t) \
|
||||||
extern HType *prefix##_init(void); \
|
extern HType *prefix##_init(void); \
|
||||||
|
extern HType *prefix##_init2(void *km); \
|
||||||
extern void prefix##_destroy(HType *h); \
|
extern void prefix##_destroy(HType *h); \
|
||||||
extern void prefix##_clear(HType *h); \
|
extern void prefix##_clear(HType *h); \
|
||||||
extern khint_t prefix##_getp(const HType *h, const khkey_t *key); \
|
extern khint_t prefix##_getp(const HType *h, const khkey_t *key); \
|
||||||
@ -127,13 +123,16 @@ static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 26
|
|||||||
extern void prefix##_del(HType *h, khint_t k);
|
extern void prefix##_del(HType *h, khint_t k);
|
||||||
|
|
||||||
#define __KHASHL_IMPL_BASIC(SCOPE, HType, prefix) \
|
#define __KHASHL_IMPL_BASIC(SCOPE, HType, prefix) \
|
||||||
SCOPE HType *prefix##_init(void) { \
|
SCOPE HType *prefix##_init2(void *km) { \
|
||||||
return (HType*)kcalloc(1, sizeof(HType)); \
|
HType *h = Kcalloc(km, HType, 1); \
|
||||||
|
h->km = km; \
|
||||||
|
return h; \
|
||||||
} \
|
} \
|
||||||
|
SCOPE HType *prefix##_init(void) { return prefix##_init2(0); } \
|
||||||
SCOPE void prefix##_destroy(HType *h) { \
|
SCOPE void prefix##_destroy(HType *h) { \
|
||||||
if (!h) return; \
|
if (!h) return; \
|
||||||
kfree((void *)h->keys); kfree(h->used); \
|
Kfree(h->km, (void*)h->keys); Kfree(h->km, h->used); \
|
||||||
kfree(h); \
|
Kfree(h->km, h); \
|
||||||
} \
|
} \
|
||||||
SCOPE void prefix##_clear(HType *h) { \
|
SCOPE void prefix##_clear(HType *h) { \
|
||||||
if (h && h->used) { \
|
if (h && h->used) { \
|
||||||
@ -168,13 +167,13 @@ static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 26
|
|||||||
new_bits = j > 2? j : 2; \
|
new_bits = j > 2? j : 2; \
|
||||||
new_n_buckets = (khint_t)1U << new_bits; \
|
new_n_buckets = (khint_t)1U << new_bits; \
|
||||||
if (h->count > kh_max_count(new_n_buckets)) return 0; /* requested size is too small */ \
|
if (h->count > kh_max_count(new_n_buckets)) return 0; /* requested size is too small */ \
|
||||||
new_used = (khint32_t*)kmalloc(__kh_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
new_used = Kmalloc(h->km, khint32_t, __kh_fsize(new_n_buckets)); \
|
||||||
memset(new_used, 0, __kh_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
memset(new_used, 0, __kh_fsize(new_n_buckets) * sizeof(khint32_t)); \
|
||||||
if (!new_used) return -1; /* not enough memory */ \
|
if (!new_used) return -1; /* not enough memory */ \
|
||||||
n_buckets = h->keys? (khint_t)1U<<h->bits : 0U; \
|
n_buckets = h->keys? (khint_t)1U<<h->bits : 0U; \
|
||||||
if (n_buckets < new_n_buckets) { /* expand */ \
|
if (n_buckets < new_n_buckets) { /* expand */ \
|
||||||
khkey_t *new_keys = (khkey_t*)krealloc((void*)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
khkey_t *new_keys = Krealloc(h->km, khkey_t, h->keys, new_n_buckets); \
|
||||||
if (!new_keys) { kfree(new_used); return -1; } \
|
if (!new_keys) { Kfree(h->km, new_used); return -1; } \
|
||||||
h->keys = new_keys; \
|
h->keys = new_keys; \
|
||||||
} /* otherwise shrink */ \
|
} /* otherwise shrink */ \
|
||||||
new_mask = new_n_buckets - 1; \
|
new_mask = new_n_buckets - 1; \
|
||||||
@ -198,8 +197,8 @@ static kh_inline khint_t __kh_h2b(khint_t hash, khint_t bits) { return hash * 26
|
|||||||
} \
|
} \
|
||||||
} \
|
} \
|
||||||
if (n_buckets > new_n_buckets) /* shrink the hash table */ \
|
if (n_buckets > new_n_buckets) /* shrink the hash table */ \
|
||||||
h->keys = (khkey_t*)krealloc((void *)h->keys, new_n_buckets * sizeof(khkey_t)); \
|
h->keys = Krealloc(h->km, khkey_t, (void*)h->keys, new_n_buckets); \
|
||||||
kfree(h->used); /* free the working space */ \
|
Kfree(h->km, h->used); /* free the working space */ \
|
||||||
h->used = new_used, h->bits = new_bits; \
|
h->used = new_used, h->bits = new_bits; \
|
||||||
return 0; \
|
return 0; \
|
||||||
}
|
}
|
||||||
@ -272,21 +271,23 @@ typedef struct {
|
|||||||
#define KHASHE_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
#define KHASHE_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
||||||
KHASHL_INIT(KH_LOCAL, HType##_sub, prefix##_sub, khkey_t, __hash_fn, __hash_eq) \
|
KHASHL_INIT(KH_LOCAL, HType##_sub, prefix##_sub, khkey_t, __hash_fn, __hash_eq) \
|
||||||
typedef struct HType { \
|
typedef struct HType { \
|
||||||
|
void *km; \
|
||||||
khint64_t count:54, bits:8; \
|
khint64_t count:54, bits:8; \
|
||||||
HType##_sub *sub; \
|
HType##_sub *sub; \
|
||||||
} HType; \
|
} HType; \
|
||||||
SCOPE HType *prefix##_init(int bits) { \
|
SCOPE HType *prefix##_init2(void *km, int bits) { \
|
||||||
HType *g; \
|
HType *g; \
|
||||||
g = (HType*)kcalloc(1, sizeof(*g)); \
|
g = Kcalloc(km, HType, 1); \
|
||||||
g->bits = bits; \
|
g->bits = bits, g->km = km; \
|
||||||
g->sub = (HType##_sub*)kcalloc(1U<<bits, sizeof(*g->sub)); \
|
g->sub = Kcalloc(km, HType##_sub, 1U<<bits); \
|
||||||
return g; \
|
return g; \
|
||||||
} \
|
} \
|
||||||
|
SCOPE HType *prefix##_init(int bits) { return prefix##_init2(0, bits); } \
|
||||||
SCOPE void prefix##_destroy(HType *g) { \
|
SCOPE void prefix##_destroy(HType *g) { \
|
||||||
int t; \
|
int t; \
|
||||||
if (!g) return; \
|
if (!g) return; \
|
||||||
for (t = 0; t < 1<<g->bits; ++t) { kfree((void*)g->sub[t].keys); kfree(g->sub[t].used); } \
|
for (t = 0; t < 1<<g->bits; ++t) { Kfree(g->km, (void*)g->sub[t].keys); Kfree(g->km, g->sub[t].used); } \
|
||||||
kfree(g->sub); kfree(g); \
|
Kfree(g->km, g->sub); Kfree(g->km, g); \
|
||||||
} \
|
} \
|
||||||
SCOPE kh_ensitr_t prefix##_getp(const HType *g, const khkey_t *key) { \
|
SCOPE kh_ensitr_t prefix##_getp(const HType *g, const khkey_t *key) { \
|
||||||
khint_t hash, low, ret; \
|
khint_t hash, low, ret; \
|
||||||
@ -320,16 +321,32 @@ typedef struct {
|
|||||||
ret = prefix##_sub_del(h, itr.pos); \
|
ret = prefix##_sub_del(h, itr.pos); \
|
||||||
if (ret) --g->count; \
|
if (ret) --g->count; \
|
||||||
return ret; \
|
return ret; \
|
||||||
|
} \
|
||||||
|
SCOPE void prefix##_clear(HType *g) { \
|
||||||
|
int i; \
|
||||||
|
for (i = 0; i < 1U<<g->bits; ++i) prefix##_sub_clear(&g->sub[i]); \
|
||||||
|
g->count = 0; \
|
||||||
}
|
}
|
||||||
|
|
||||||
/*****************************
|
/*****************************
|
||||||
* More convenient interface *
|
* More convenient interface *
|
||||||
*****************************/
|
*****************************/
|
||||||
|
|
||||||
#define __kh_cached_hash(x) ((x).hash)
|
/* common */
|
||||||
|
|
||||||
#define KHASHL_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
#define KHASHL_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
||||||
KHASHL_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq)
|
typedef struct { khkey_t key; } kh_packed HType##_s_bucket_t; \
|
||||||
|
static kh_inline khint_t prefix##_s_hash(HType##_s_bucket_t x) { return __hash_fn(x.key); } \
|
||||||
|
static kh_inline int prefix##_s_eq(HType##_s_bucket_t x, HType##_s_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
||||||
|
KHASHL_INIT(KH_LOCAL, HType, prefix##_s, HType##_s_bucket_t, prefix##_s_hash, prefix##_s_eq) \
|
||||||
|
SCOPE HType *prefix##_init(void) { return prefix##_s_init(); } \
|
||||||
|
SCOPE HType *prefix##_init2(void *km) { return prefix##_s_init2(km); } \
|
||||||
|
SCOPE void prefix##_destroy(HType *h) { prefix##_s_destroy(h); } \
|
||||||
|
SCOPE void prefix##_resize(HType *h, khint_t new_n_buckets) { prefix##_s_resize(h, new_n_buckets); } \
|
||||||
|
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_s_bucket_t t; t.key = key; return prefix##_s_getp(h, &t); } \
|
||||||
|
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_s_del(h, k); } \
|
||||||
|
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_s_bucket_t t; t.key = key; return prefix##_s_putp(h, &t, absent); } \
|
||||||
|
SCOPE void prefix##_clear(HType *h) { prefix##_s_clear(h); }
|
||||||
|
|
||||||
#define KHASHL_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
#define KHASHL_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
||||||
typedef struct { khkey_t key; kh_val_t val; } kh_packed HType##_m_bucket_t; \
|
typedef struct { khkey_t key; kh_val_t val; } kh_packed HType##_m_bucket_t; \
|
||||||
@ -337,10 +354,17 @@ typedef struct {
|
|||||||
static kh_inline int prefix##_m_eq(HType##_m_bucket_t x, HType##_m_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
static kh_inline int prefix##_m_eq(HType##_m_bucket_t x, HType##_m_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
||||||
KHASHL_INIT(KH_LOCAL, HType, prefix##_m, HType##_m_bucket_t, prefix##_m_hash, prefix##_m_eq) \
|
KHASHL_INIT(KH_LOCAL, HType, prefix##_m, HType##_m_bucket_t, prefix##_m_hash, prefix##_m_eq) \
|
||||||
SCOPE HType *prefix##_init(void) { return prefix##_m_init(); } \
|
SCOPE HType *prefix##_init(void) { return prefix##_m_init(); } \
|
||||||
|
SCOPE HType *prefix##_init2(void *km) { return prefix##_m_init2(km); } \
|
||||||
SCOPE void prefix##_destroy(HType *h) { prefix##_m_destroy(h); } \
|
SCOPE void prefix##_destroy(HType *h) { prefix##_m_destroy(h); } \
|
||||||
|
SCOPE void prefix##_resize(HType *h, khint_t new_n_buckets) { prefix##_m_resize(h, new_n_buckets); } \
|
||||||
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_m_bucket_t t; t.key = key; return prefix##_m_getp(h, &t); } \
|
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_m_bucket_t t; t.key = key; return prefix##_m_getp(h, &t); } \
|
||||||
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_m_del(h, k); } \
|
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_m_del(h, k); } \
|
||||||
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_m_bucket_t t; t.key = key; return prefix##_m_putp(h, &t, absent); }
|
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_m_bucket_t t; t.key = key; return prefix##_m_putp(h, &t, absent); } \
|
||||||
|
SCOPE void prefix##_clear(HType *h) { prefix##_m_clear(h); }
|
||||||
|
|
||||||
|
/* cached hashes to trade memory for performance when hashing and comparison are expensive */
|
||||||
|
|
||||||
|
#define __kh_cached_hash(x) ((x).hash)
|
||||||
|
|
||||||
#define KHASHL_CSET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
#define KHASHL_CSET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
||||||
typedef struct { khkey_t key; khint_t hash; } kh_packed HType##_cs_bucket_t; \
|
typedef struct { khkey_t key; khint_t hash; } kh_packed HType##_cs_bucket_t; \
|
||||||
@ -350,7 +374,8 @@ typedef struct {
|
|||||||
SCOPE void prefix##_destroy(HType *h) { prefix##_cs_destroy(h); } \
|
SCOPE void prefix##_destroy(HType *h) { prefix##_cs_destroy(h); } \
|
||||||
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cs_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cs_getp(h, &t); } \
|
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cs_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cs_getp(h, &t); } \
|
||||||
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cs_del(h, k); } \
|
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cs_del(h, k); } \
|
||||||
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cs_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cs_putp(h, &t, absent); }
|
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cs_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cs_putp(h, &t, absent); } \
|
||||||
|
SCOPE void prefix##_clear(HType *h) { prefix##_cs_clear(h); }
|
||||||
|
|
||||||
#define KHASHL_CMAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
#define KHASHL_CMAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
||||||
typedef struct { khkey_t key; kh_val_t val; khint_t hash; } kh_packed HType##_cm_bucket_t; \
|
typedef struct { khkey_t key; kh_val_t val; khint_t hash; } kh_packed HType##_cm_bucket_t; \
|
||||||
@ -360,21 +385,34 @@ typedef struct {
|
|||||||
SCOPE void prefix##_destroy(HType *h) { prefix##_cm_destroy(h); } \
|
SCOPE void prefix##_destroy(HType *h) { prefix##_cm_destroy(h); } \
|
||||||
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cm_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cm_getp(h, &t); } \
|
SCOPE khint_t prefix##_get(const HType *h, khkey_t key) { HType##_cm_bucket_t t; t.key = key; t.hash = __hash_fn(key); return prefix##_cm_getp(h, &t); } \
|
||||||
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cm_del(h, k); } \
|
SCOPE int prefix##_del(HType *h, khint_t k) { return prefix##_cm_del(h, k); } \
|
||||||
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cm_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cm_putp(h, &t, absent); }
|
SCOPE khint_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_cm_bucket_t t; t.key = key, t.hash = __hash_fn(key); return prefix##_cm_putp(h, &t, absent); } \
|
||||||
|
SCOPE void prefix##_clear(HType *h) { prefix##_cm_clear(h); }
|
||||||
|
|
||||||
|
/* ensemble for huge hash tables */
|
||||||
|
|
||||||
#define KHASHE_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
#define KHASHE_SET_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq) \
|
||||||
KHASHE_INIT(SCOPE, HType, prefix, khkey_t, __hash_fn, __hash_eq)
|
typedef struct { khkey_t key; } kh_packed HType##_es_bucket_t; \
|
||||||
|
static kh_inline khint_t prefix##_es_hash(HType##_es_bucket_t x) { return __hash_fn(x.key); } \
|
||||||
|
static kh_inline int prefix##_es_eq(HType##_es_bucket_t x, HType##_es_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
||||||
|
KHASHE_INIT(KH_LOCAL, HType, prefix##_es, HType##_es_bucket_t, prefix##_es_hash, prefix##_es_eq) \
|
||||||
|
SCOPE HType *prefix##_init(int bits) { return prefix##_es_init(bits); } \
|
||||||
|
SCOPE void prefix##_destroy(HType *h) { prefix##_es_destroy(h); } \
|
||||||
|
SCOPE kh_ensitr_t prefix##_get(const HType *h, khkey_t key) { HType##_es_bucket_t t; t.key = key; return prefix##_es_getp(h, &t); } \
|
||||||
|
SCOPE int prefix##_del(HType *h, kh_ensitr_t k) { return prefix##_es_del(h, k); } \
|
||||||
|
SCOPE kh_ensitr_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_es_bucket_t t; t.key = key; return prefix##_es_putp(h, &t, absent); } \
|
||||||
|
SCOPE void prefix##_clear(HType *h) { prefix##_es_clear(h); }
|
||||||
|
|
||||||
#define KHASHE_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
#define KHASHE_MAP_INIT(SCOPE, HType, prefix, khkey_t, kh_val_t, __hash_fn, __hash_eq) \
|
||||||
typedef struct { khkey_t key; kh_val_t val; } kh_packed HType##_m_bucket_t; \
|
typedef struct { khkey_t key; kh_val_t val; } kh_packed HType##_em_bucket_t; \
|
||||||
static kh_inline khint_t prefix##_m_hash(HType##_m_bucket_t x) { return __hash_fn(x.key); } \
|
static kh_inline khint_t prefix##_em_hash(HType##_em_bucket_t x) { return __hash_fn(x.key); } \
|
||||||
static kh_inline int prefix##_m_eq(HType##_m_bucket_t x, HType##_m_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
static kh_inline int prefix##_em_eq(HType##_em_bucket_t x, HType##_em_bucket_t y) { return __hash_eq(x.key, y.key); } \
|
||||||
KHASHE_INIT(KH_LOCAL, HType, prefix##_m, HType##_m_bucket_t, prefix##_m_hash, prefix##_m_eq) \
|
KHASHE_INIT(KH_LOCAL, HType, prefix##_em, HType##_em_bucket_t, prefix##_em_hash, prefix##_em_eq) \
|
||||||
SCOPE HType *prefix##_init(int bits) { return prefix##_m_init(bits); } \
|
SCOPE HType *prefix##_init(int bits) { return prefix##_em_init(bits); } \
|
||||||
SCOPE void prefix##_destroy(HType *h) { prefix##_m_destroy(h); } \
|
SCOPE void prefix##_destroy(HType *h) { prefix##_em_destroy(h); } \
|
||||||
SCOPE kh_ensitr_t prefix##_get(const HType *h, khkey_t key) { HType##_m_bucket_t t; t.key = key; return prefix##_m_getp(h, &t); } \
|
SCOPE kh_ensitr_t prefix##_get(const HType *h, khkey_t key) { HType##_em_bucket_t t; t.key = key; return prefix##_em_getp(h, &t); } \
|
||||||
SCOPE int prefix##_del(HType *h, kh_ensitr_t k) { return prefix##_m_del(h, k); } \
|
SCOPE int prefix##_del(HType *h, kh_ensitr_t k) { return prefix##_em_del(h, k); } \
|
||||||
SCOPE kh_ensitr_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_m_bucket_t t; t.key = key; return prefix##_m_putp(h, &t, absent); }
|
SCOPE kh_ensitr_t prefix##_put(HType *h, khkey_t key, int *absent) { HType##_em_bucket_t t; t.key = key; return prefix##_em_putp(h, &t, absent); } \
|
||||||
|
SCOPE void prefix##_clear(HType *h) { prefix##_em_clear(h); }
|
||||||
|
|
||||||
/**************************
|
/**************************
|
||||||
* Public macro functions *
|
* Public macro functions *
|
||||||
@ -425,10 +463,8 @@ static kh_inline khint_t kh_hash_uint64(khint64_t x) { /* splitmix64; see https:
|
|||||||
return (khint_t)x;
|
return (khint_t)x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define KH_FNV_SEED 11
|
|
||||||
|
|
||||||
static kh_inline khint_t kh_hash_str(kh_cstr_t s) { /* FNV1a */
|
static kh_inline khint_t kh_hash_str(kh_cstr_t s) { /* FNV1a */
|
||||||
khint_t h = KH_FNV_SEED ^ 2166136261U;
|
khint_t h = 2166136261U;
|
||||||
const unsigned char *t = (const unsigned char*)s;
|
const unsigned char *t = (const unsigned char*)s;
|
||||||
for (; *t; ++t)
|
for (; *t; ++t)
|
||||||
h ^= *t, h *= 16777619;
|
h ^= *t, h *= 16777619;
|
||||||
@ -436,7 +472,7 @@ static kh_inline khint_t kh_hash_str(kh_cstr_t s) { /* FNV1a */
|
|||||||
}
|
}
|
||||||
|
|
||||||
static kh_inline khint_t kh_hash_bytes(int len, const unsigned char *s) {
|
static kh_inline khint_t kh_hash_bytes(int len, const unsigned char *s) {
|
||||||
khint_t h = KH_FNV_SEED ^ 2166136261U;
|
khint_t h = 2166136261U;
|
||||||
int i;
|
int i;
|
||||||
for (i = 0; i < len; ++i)
|
for (i = 0; i < len; ++i)
|
||||||
h ^= s[i], h *= 16777619;
|
h ^= s[i], h *= 16777619;
|
||||||
|
Loading…
Reference in New Issue
Block a user