mirror of
https://gitlab.freedesktop.org/monado/monado.git
synced 2024-12-28 02:26:16 +00:00
aux/util: Add string hashset
This commit is contained in:
parent
b8e4a5f8d1
commit
a36565c5b7
|
@ -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
|
||||
)
|
||||
|
|
125
src/xrt/auxiliary/util/u_hashset.cpp
Normal file
125
src/xrt/auxiliary/util/u_hashset.cpp
Normal 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);
|
||||
}
|
||||
}
|
88
src/xrt/auxiliary/util/u_hashset.h
Normal file
88
src/xrt/auxiliary/util/u_hashset.h
Normal 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
|
Loading…
Reference in a new issue