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 ]]======================================= */
|
/* =======================================[[ Peer Iter ]]======================================= */
|
||||||
|
|
||||||
struct sWrapperData
|
bool laikaC_iterPeersNext(struct sLaika_cnc *cnc, size_t *i, struct sLaika_peer **peer)
|
||||||
{
|
{
|
||||||
tLaika_peerIter iter;
|
tCNC_PeerHashElem *elem;
|
||||||
void *uData;
|
|
||||||
};
|
|
||||||
|
|
||||||
/* wrapper iterator */
|
if (hashmap_iter(cnc->peers, i, (void *)&elem)) {
|
||||||
bool iterWrapper(const void *rawItem, void *uData)
|
*peer = elem->peer;
|
||||||
{
|
return true;
|
||||||
struct sWrapperData *data = (struct sWrapperData *)uData;
|
}
|
||||||
tCNC_PeerHashElem *item = (tCNC_PeerHashElem *)rawItem;
|
|
||||||
return data->iter(item->peer, data->uData);
|
*peer = NULL;
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData)
|
void laikaC_iterPeers(struct sLaika_cnc *cnc, tLaika_peerIter iter, void *uData)
|
||||||
{
|
{
|
||||||
struct sWrapperData wrapper;
|
size_t i = 0;
|
||||||
wrapper.iter = iter;
|
struct sLaika_peer *peer;
|
||||||
wrapper.uData = uData;
|
|
||||||
|
|
||||||
/* iterate over hashmap calling our iterWrapper, pass the *real* iterator to
|
/* call iter for every peer in cnc->peers */
|
||||||
itemWrapper so that it can call it. probably a better way to do this
|
while (laikaC_iterPeersNext(cnc, &i, &peer))
|
||||||
but w/e lol */
|
iter(peer, uData);
|
||||||
hashmap_scan(cnc->peers, iterWrapper, &wrapper);
|
|
||||||
}
|
}
|
@ -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,44 +12,32 @@
|
|||||||
|
|
||||||
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 *));
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
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