aux/util: Add string hashset

This commit is contained in:
Jakob Bornecrantz 2019-04-06 12:33:01 +01:00
parent b8e4a5f8d1
commit a36565c5b7
3 changed files with 215 additions and 0 deletions

View file

@ -18,6 +18,8 @@ set(SOURCE_FILES
util/u_device.c
util/u_device.h
util/u_documentation.h
util/u_hashset.cpp
util/u_hashset.h
util/u_time.cpp
util/u_time.h
)

View file

@ -0,0 +1,125 @@
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Hashset struct header.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup aux_util
*/
#include "util/u_hashset.h"
#include <cstring>
#include <unordered_map>
#include <vector>
/*
*
* Private structs and defines.
*
*/
struct u_hashset
{
std::unordered_map<std::string, struct u_hashset_item *> map = {};
};
/*
*
* "Exported" functions.
*
*/
extern "C" int
u_hashset_create(struct u_hashset **out_hashset)
{
auto hs = new u_hashset;
*out_hashset = hs;
return 0;
}
extern "C" int
u_hashset_destroy(struct u_hashset **hs)
{
delete *hs;
*hs = NULL;
return 0;
}
extern "C" int
u_hashset_find_str(struct u_hashset *hs,
const char *str,
size_t length,
struct u_hashset_item **out_item)
{
std::string key = std::string(str, length);
auto search = hs->map.find(key);
if (search != hs->map.end()) {
*out_item = search->second;
return 0;
} else {
return -1;
}
}
extern "C" int
u_hashset_find_c_str(struct u_hashset *hs,
const char *c_str,
struct u_hashset_item **out_item)
{
size_t length = strlen(c_str);
return u_hashset_find_str(hs, c_str, length, out_item);
}
extern "C" int
u_hashset_insert_item(struct u_hashset *hs, struct u_hashset_item *item)
{
std::string key = std::string(item->c_str, item->length);
hs->map[key] = item;
return 0;
}
extern "C" int
u_hashset_erase_item(struct u_hashset *hs, struct u_hashset_item *item)
{
std::string key = std::string(item->c_str, item->length);
hs->map.erase(key);
return 0;
}
extern "C" int
u_hashset_erase_str(struct u_hashset *hs, const char *str, size_t length)
{
std::string key = std::string(str, length);
hs->map.erase(key);
return 0;
}
extern "C" int
u_hashset_erase_c_str(struct u_hashset *hs, const char *c_str)
{
size_t length = strlen(c_str);
return u_hashset_erase_str(hs, c_str, length);
}
extern "C" void
u_hashset_clear_and_call_for_each(struct u_hashset *hs,
u_hashset_callback cb,
void *priv)
{
std::vector<struct u_hashset_item *> tmp;
tmp.reserve(hs->map.size());
for (auto &n : hs->map) {
tmp.push_back(n.second);
}
hs->map.clear();
for (auto n : tmp) {
cb(n, priv);
}
}

View file

@ -0,0 +1,88 @@
// Copyright 2019, Collabora, Ltd.
// SPDX-License-Identifier: BSL-1.0
/*!
* @file
* @brief Hashset struct header.
* @author Jakob Bornecrantz <jakob@collabora.com>
* @ingroup aux_util
*/
#pragma once
#include "xrt/xrt_compiler.h"
#ifdef __cplusplus
extern "C" {
#endif
/*!
* @struct u_hashset
* @ingroup aux_util
*
* Kind of bespoke hashset implementation, where the user is responsible for
* allocating and freeing the items themselves.
*
* This allows embedding the @ref u_hashset_item at the end of structs.
*/
struct u_hashset;
/*!
* A embeddable hashset item, note that the string directly follows the
* @ref u_hashset_item.
*
* @ingroup aux_util
*/
struct u_hashset_item
{
size_t hash;
size_t length;
const char c_str[];
};
typedef void (*u_hashset_callback)(struct u_hashset_item *item, void *priv);
int
u_hashset_create(struct u_hashset **out_hashset);
int
u_hashset_destroy(struct u_hashset **hs);
int
u_hashset_find_str(struct u_hashset *hs,
const char *str,
size_t length,
struct u_hashset_item **out_item);
int
u_hashset_find_c_str(struct u_hashset *hs,
const char *c_str,
struct u_hashset_item **out_item);
int
u_hashset_insert_item(struct u_hashset *hs, struct u_hashset_item *item);
int
u_hashset_erase_item(struct u_hashset *hs, struct u_hashset_item *item);
int
u_hashset_erase_str(struct u_hashset *hs, const char *str, size_t length);
int
u_hashset_erase_c_str(struct u_hashset *hs, const char *c_str);
/*!
* First clear the hashset and then call the given callback with each item that
* was in the hashset.
*
* @ingroup aux_util
*/
void
u_hashset_clear_and_call_for_each(struct u_hashset *hs,
u_hashset_callback cb,
void *priv);
#ifdef __cplusplus
}
#endif