mirror of
https://github.com/CPunch/Laika.git
synced 2024-12-04 19:52:48 +00:00
Compare commits
2 Commits
fab6c5b4f6
...
68f8e80c75
Author | SHA1 | Date | |
---|---|---|---|
68f8e80c75 | |||
10a36df090 |
@ -451,28 +451,25 @@ void laikaC_sweepPeersTask(struct sLaika_taskService *service, struct sLaika_tas
|
||||
|
||||
/* =======================================[[ Peer Iter ]]======================================= */
|
||||
|
||||
struct sWrapperData
|
||||
bool laikaC_iterPeersNext(struct sLaika_cnc *cnc, size_t *i, struct sLaika_peer **peer)
|
||||
{
|
||||
tLaika_peerIter iter;
|
||||
void *uData;
|
||||
};
|
||||
tCNC_PeerHashElem *elem;
|
||||
|
||||
/* wrapper iterator */
|
||||
bool iterWrapper(const void *rawItem, void *uData)
|
||||
{
|
||||
struct sWrapperData *data = (struct sWrapperData *)uData;
|
||||
tCNC_PeerHashElem *item = (tCNC_PeerHashElem *)rawItem;
|
||||
return data->iter(item->peer, data->uData);
|
||||
if (hashmap_iter(cnc->peers, i, (void *)&elem)) {
|
||||
*peer = elem->peer;
|
||||
return true;
|
||||
}
|
||||
|
||||
*peer = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData)
|
||||
{
|
||||
struct sWrapperData wrapper;
|
||||
wrapper.iter = iter;
|
||||
wrapper.uData = uData;
|
||||
size_t i = 0;
|
||||
struct sLaika_peer *peer;
|
||||
|
||||
/* iterate over hashmap calling our iterWrapper, pass the *real* iterator to
|
||||
itemWrapper so that it can call it. probably a better way to do this
|
||||
but w/e lol */
|
||||
hashmap_scan(cnc->peers, iterWrapper, &wrapper);
|
||||
/* call iter for every peer in cnc->peers */
|
||||
while (laikaC_iterPeersNext(cnc, &i, &peer))
|
||||
iter(peer, uData);
|
||||
}
|
@ -1,3 +1,4 @@
|
||||
// https://github.com/tidwall/hashmap.c
|
||||
// Copyright 2020 Joshua J Baker. All rights reserved.
|
||||
// Use of this source code is governed by an MIT-style
|
||||
// license that can be found in the LICENSE file.
|
||||
@ -11,42 +12,30 @@
|
||||
|
||||
struct hashmap;
|
||||
|
||||
struct hashmap *hashmap_new(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);
|
||||
struct hashmap *hashmap_new_with_allocator(
|
||||
void *(*malloc)(size_t),
|
||||
void *(*realloc)(void *, size_t),
|
||||
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);
|
||||
struct hashmap *hashmap_new(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);
|
||||
struct hashmap *
|
||||
hashmap_new_with_allocator(void *(*malloc)(size_t), void *(*realloc)(void *, size_t),
|
||||
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_clear(struct hashmap *map, bool update_cap);
|
||||
size_t hashmap_count(struct hashmap *map);
|
||||
bool hashmap_oom(struct hashmap *map);
|
||||
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_probe(struct hashmap *map, uint64_t position);
|
||||
bool hashmap_scan(struct hashmap *map,
|
||||
bool (*iter)(const void *item, void *udata), void *udata);
|
||||
|
||||
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);
|
||||
bool hashmap_scan(struct hashmap *map, 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);
|
||||
|
||||
// DEPRECATED: use `hashmap_new_with_allocator`
|
||||
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
|
||||
// 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 <stddef.h>
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
static void *(*_malloc)(size_t) = NULL;
|
||||
static void *(*_realloc)(void *, size_t) = NULL;
|
||||
static void (*_free)(void *) = NULL;
|
||||
@ -23,7 +24,7 @@ void hashmap_set_allocator(void *(*malloc)(size_t), void (*free)(void*))
|
||||
}
|
||||
|
||||
#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); \
|
||||
}
|
||||
|
||||
@ -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
|
||||
// may allocate memory. If the system is unable to allocate additional
|
||||
// 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) {
|
||||
panic("item is null");
|
||||
}
|
||||
@ -408,6 +409,42 @@ bool hashmap_scan(struct hashmap *map,
|
||||
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
|
||||
//
|
||||
@ -738,6 +775,13 @@ static void all() {
|
||||
while (!(vals2 = xmalloc(N * sizeof(int)))) {}
|
||||
memset(vals2, 0, N * sizeof(int));
|
||||
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++) {
|
||||
assert(vals2[i] == 1);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user