mirror of
https://github.com/CPunch/Laika.git
synced 2024-11-23 13:20:10 +00:00
Updated hashmap.c
This commit is contained in:
parent
fab6c5b4f6
commit
10a36df090
@ -1,3 +1,4 @@
|
|||||||
|
// https://github.com/tidwall/hashmap.c
|
||||||
// Copyright 2020 Joshua J Baker. All rights reserved.
|
// Copyright 2020 Joshua J Baker. All rights reserved.
|
||||||
// Use of this source code is governed by an MIT-style
|
// Use of this source code is governed by an MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
@ -11,42 +12,30 @@
|
|||||||
|
|
||||||
struct hashmap;
|
struct hashmap;
|
||||||
|
|
||||||
struct hashmap *hashmap_new(size_t elsize, size_t cap,
|
struct hashmap *hashmap_new(size_t elsize, size_t cap, uint64_t seed0, uint64_t seed1,
|
||||||
uint64_t seed0, uint64_t seed1,
|
uint64_t (*hash)(const void *item, uint64_t seed0, uint64_t seed1),
|
||||||
uint64_t (*hash)(const void *item,
|
int (*compare)(const void *a, const void *b, void *udata),
|
||||||
uint64_t seed0, uint64_t seed1),
|
void (*elfree)(void *item), void *udata);
|
||||||
int (*compare)(const void *a, const void *b,
|
struct hashmap *
|
||||||
void *udata),
|
hashmap_new_with_allocator(void *(*malloc)(size_t), void *(*realloc)(void *, size_t),
|
||||||
void (*elfree)(void *item),
|
void (*free)(void *), size_t elsize, size_t cap, uint64_t seed0,
|
||||||
void *udata);
|
uint64_t seed1,
|
||||||
struct hashmap *hashmap_new_with_allocator(
|
uint64_t (*hash)(const void *item, uint64_t seed0, uint64_t seed1),
|
||||||
void *(*malloc)(size_t),
|
int (*compare)(const void *a, const void *b, void *udata),
|
||||||
void *(*realloc)(void *, size_t),
|
void (*elfree)(void *item), void *udata);
|
||||||
void (*free)(void*),
|
|
||||||
size_t elsize, size_t cap,
|
|
||||||
uint64_t seed0, uint64_t seed1,
|
|
||||||
uint64_t (*hash)(const void *item,
|
|
||||||
uint64_t seed0, uint64_t seed1),
|
|
||||||
int (*compare)(const void *a, const void *b,
|
|
||||||
void *udata),
|
|
||||||
void (*elfree)(void *item),
|
|
||||||
void *udata);
|
|
||||||
void hashmap_free(struct hashmap *map);
|
void hashmap_free(struct hashmap *map);
|
||||||
void hashmap_clear(struct hashmap *map, bool update_cap);
|
void hashmap_clear(struct hashmap *map, bool update_cap);
|
||||||
size_t hashmap_count(struct hashmap *map);
|
size_t hashmap_count(struct hashmap *map);
|
||||||
bool hashmap_oom(struct hashmap *map);
|
bool hashmap_oom(struct hashmap *map);
|
||||||
void *hashmap_get(struct hashmap *map, const void *item);
|
void *hashmap_get(struct hashmap *map, const void *item);
|
||||||
void *hashmap_set(struct hashmap *map, void *item);
|
void *hashmap_set(struct hashmap *map, const void *item);
|
||||||
void *hashmap_delete(struct hashmap *map, void *item);
|
void *hashmap_delete(struct hashmap *map, void *item);
|
||||||
void *hashmap_probe(struct hashmap *map, uint64_t position);
|
void *hashmap_probe(struct hashmap *map, uint64_t position);
|
||||||
bool hashmap_scan(struct hashmap *map,
|
bool hashmap_scan(struct hashmap *map, bool (*iter)(const void *item, void *udata), void *udata);
|
||||||
bool (*iter)(const void *item, void *udata), void *udata);
|
bool hashmap_iter(struct hashmap *map, size_t *i, void **item);
|
||||||
|
|
||||||
uint64_t hashmap_sip(const void *data, size_t len,
|
|
||||||
uint64_t seed0, uint64_t seed1);
|
|
||||||
uint64_t hashmap_murmur(const void *data, size_t len,
|
|
||||||
uint64_t seed0, uint64_t seed1);
|
|
||||||
|
|
||||||
|
uint64_t hashmap_sip(const void *data, size_t len, uint64_t seed0, uint64_t seed1);
|
||||||
|
uint64_t hashmap_murmur(const void *data, size_t len, uint64_t seed0, uint64_t seed1);
|
||||||
|
|
||||||
// DEPRECATED: use `hashmap_new_with_allocator`
|
// DEPRECATED: use `hashmap_new_with_allocator`
|
||||||
void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void *));
|
void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void *));
|
||||||
|
58
lib/vendor/hashmap.c
vendored
58
lib/vendor/hashmap.c
vendored
@ -2,13 +2,14 @@
|
|||||||
// Use of this source code is governed by an MIT-style
|
// Use of this source code is governed by an MIT-style
|
||||||
// license that can be found in the LICENSE file.
|
// license that can be found in the LICENSE file.
|
||||||
|
|
||||||
#include <stdio.h>
|
|
||||||
#include <string.h>
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <stddef.h>
|
|
||||||
#include "hashmap.h"
|
#include "hashmap.h"
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
static void *(*_malloc)(size_t) = NULL;
|
static void *(*_malloc)(size_t) = NULL;
|
||||||
static void *(*_realloc)(void *, size_t) = NULL;
|
static void *(*_realloc)(void *, size_t) = NULL;
|
||||||
static void (*_free)(void *) = NULL;
|
static void (*_free)(void *) = NULL;
|
||||||
@ -23,7 +24,7 @@ void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void*))
|
|||||||
}
|
}
|
||||||
|
|
||||||
#define panic(_msg_) { \
|
#define panic(_msg_) { \
|
||||||
/*fprintf(stderr, "panic: %s (%s:%d)\n", (_msg_), __FILE__, __LINE__);*/ \
|
fprintf(stderr, "panic: %s (%s:%d)\n", (_msg_), __FILE__, __LINE__); \
|
||||||
exit(1); \
|
exit(1); \
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -248,7 +249,7 @@ static bool resize(struct hashmap *map, size_t new_cap) {
|
|||||||
// replaced then it is returned otherwise NULL is returned. This operation
|
// replaced then it is returned otherwise NULL is returned. This operation
|
||||||
// may allocate memory. If the system is unable to allocate additional
|
// may allocate memory. If the system is unable to allocate additional
|
||||||
// memory then NULL is returned and hashmap_oom() returns true.
|
// memory then NULL is returned and hashmap_oom() returns true.
|
||||||
void *hashmap_set(struct hashmap *map, void *item) {
|
void *hashmap_set(struct hashmap *map, const void *item) {
|
||||||
if (!item) {
|
if (!item) {
|
||||||
panic("item is null");
|
panic("item is null");
|
||||||
}
|
}
|
||||||
@ -408,6 +409,42 @@ bool hashmap_scan(struct hashmap *map,
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// hashmap_iter iterates one key at a time yielding a reference to an
|
||||||
|
// entry at each iteration. Useful to write simple loops and avoid writing
|
||||||
|
// dedicated callbacks and udata structures, as in hashmap_scan.
|
||||||
|
//
|
||||||
|
// map is a hash map handle. i is a pointer to a size_t cursor that
|
||||||
|
// should be initialized to 0 at the beginning of the loop. item is a void
|
||||||
|
// pointer pointer that is populated with the retrieved item. Note that this
|
||||||
|
// is NOT a copy of the item stored in the hash map and can be directly
|
||||||
|
// modified.
|
||||||
|
//
|
||||||
|
// Note that if hashmap_delete() is called on the hashmap being iterated,
|
||||||
|
// the buckets are rearranged and the iterator must be reset to 0, otherwise
|
||||||
|
// unexpected results may be returned after deletion.
|
||||||
|
//
|
||||||
|
// This function has not been tested for thread safety.
|
||||||
|
//
|
||||||
|
// The function returns true if an item was retrieved; false if the end of the
|
||||||
|
// iteration has been reached.
|
||||||
|
bool hashmap_iter(struct hashmap *map, size_t *i, void **item)
|
||||||
|
{
|
||||||
|
struct bucket *bucket;
|
||||||
|
|
||||||
|
do {
|
||||||
|
if (*i >= map->nbuckets) return false;
|
||||||
|
|
||||||
|
bucket = bucket_at(map, *i);
|
||||||
|
(*i)++;
|
||||||
|
} while (!bucket->dib);
|
||||||
|
|
||||||
|
*item = bucket_item(bucket);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------
|
//-----------------------------------------------------------------------------
|
||||||
// SipHash reference C implementation
|
// SipHash reference C implementation
|
||||||
//
|
//
|
||||||
@ -738,6 +775,13 @@ static void all() {
|
|||||||
while (!(vals2 = xmalloc(N * sizeof(int)))) {}
|
while (!(vals2 = xmalloc(N * sizeof(int)))) {}
|
||||||
memset(vals2, 0, N * sizeof(int));
|
memset(vals2, 0, N * sizeof(int));
|
||||||
assert(hashmap_scan(map, iter_ints, &vals2));
|
assert(hashmap_scan(map, iter_ints, &vals2));
|
||||||
|
|
||||||
|
// Test hashmap_iter. This does the same as hashmap_scan above.
|
||||||
|
size_t iter = 0;
|
||||||
|
void *iter_val;
|
||||||
|
while (hashmap_iter (map, &iter, &iter_val)) {
|
||||||
|
assert (iter_ints(iter_val, &vals2));
|
||||||
|
}
|
||||||
for (int i = 0; i < N; i++) {
|
for (int i = 0; i < N; i++) {
|
||||||
assert(vals2[i] == 1);
|
assert(vals2[i] == 1);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user