mirror of
https://salsa.debian.org/ha-team/libqb
synced 2025-08-26 23:44:41 +00:00

* doxygen2man: Add option to read copyright line from the header file This should help make builds reproducible. I tried various methods of getting the date, using 'git' is no use as it could be run from a tarball, using the file date doesn't work either so this seems a reasonable compromise. * man: Use SOURCE_EPOCH to make manpage dates reproducible Also add build-aux/update-copyright.sh to keep header file copyright lines up-to-date. All code taken from knet
285 lines
7.2 KiB
C
285 lines
7.2 KiB
C
/*
|
|
* Copyright (C) 2010-2020 Red Hat, Inc.
|
|
*
|
|
* Author: Angus Salkeld <asalkeld@redhat.com>
|
|
*
|
|
* This file is part of libqb.
|
|
*
|
|
* libqb is free software: you can redistribute it and/or modify
|
|
* it under the terms of the GNU Lesser General Public License as published by
|
|
* the Free Software Foundation, either version 2.1 of the License, or
|
|
* (at your option) any later version.
|
|
*
|
|
* libqb is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General Public License
|
|
* along with libqb. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
#ifndef QB_MAP_H_DEFINED
|
|
#define QB_MAP_H_DEFINED
|
|
|
|
#include <stdint.h>
|
|
#ifndef S_SPLINT_S
|
|
#include <unistd.h>
|
|
#endif /* S_SPLINT_S */
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
extern "C" {
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
/**
|
|
* @file qbmap.h
|
|
* This provides a map interface to a Patricia trie, hashtable or skiplist.
|
|
*
|
|
* @par Ordering
|
|
* The hashtable is NOT ordered, but ptrie and skiplist are.
|
|
*
|
|
* @par Iterating
|
|
* Below is a simple example of how to iterate over a map.
|
|
* @code
|
|
* const char *p;
|
|
* void *data;
|
|
* qb_map_iter_t *it = qb_map_iter_create(m);
|
|
* for (p = qb_map_iter_next(it, &data); p; p = qb_map_iter_next(it, &data)) {
|
|
* printf("%s > %s\n", p, (char*) data);
|
|
* }
|
|
* qb_map_iter_free(it);
|
|
* @endcode
|
|
*
|
|
* Deletion of items within the iterator is supported. But note do not
|
|
* free the item memory in the iterator. If you need to free the data
|
|
* items then register for a notifier and free the memory there. This
|
|
* is required as the items are reference counted.
|
|
* @code
|
|
* qb_map_notify_add(m, NULL, my_map_free_handler,
|
|
* QB_MAP_NOTIFY_FREE, NULL);
|
|
* @endcode
|
|
*
|
|
* @par Notifications
|
|
* These allow you to get callbacks when values are inserted/removed or
|
|
* replaced.
|
|
* @note hashtable only supports deletion and replacement notificatins.
|
|
* There is also a special global callback for freeing deleted and replaced
|
|
* values (QB_MAP_NOTIFY_FREE).
|
|
* @see qb_map_notify_add() qb_map_notify_del_2()
|
|
*
|
|
* @par Prefix matching
|
|
* The ptrie supports prefixes in the iterator:
|
|
*
|
|
* @code
|
|
* it = qb_map_pref_iter_create(m, "aa");
|
|
* while ((p = qb_map_iter_next(it, &data)) != NULL) {
|
|
* printf("%s > %s\n", p, (char*)data);
|
|
* }
|
|
* qb_map_iter_free(it);
|
|
* @endcode
|
|
*
|
|
* The ptrie also supports prefixes in notifications:
|
|
* (remember to pass QB_MAP_NOTIFY_RECURSIVE into the notify_add.
|
|
* @code
|
|
* qb_map_notify_add(m, "root", my_map_notification,
|
|
* (QB_MAP_NOTIFY_INSERTED|
|
|
* QB_MAP_NOTIFY_DELETED|
|
|
* QB_MAP_NOTIFY_REPLACED|
|
|
* QB_MAP_NOTIFY_RECURSIVE),
|
|
* NULL);
|
|
*
|
|
* @endcode
|
|
*/
|
|
|
|
/**
|
|
* This is an opaque data type representing an instance of a map.
|
|
*/
|
|
typedef struct qb_map qb_map_t;
|
|
|
|
/**
|
|
* This is an opaque data type representing an iterator instance.
|
|
*/
|
|
typedef struct qb_map_iter qb_map_iter_t;
|
|
|
|
#define QB_MAP_NOTIFY_DELETED 1
|
|
#define QB_MAP_NOTIFY_REPLACED 2
|
|
#define QB_MAP_NOTIFY_INSERTED 4
|
|
#define QB_MAP_NOTIFY_RECURSIVE 8
|
|
#define QB_MAP_NOTIFY_FREE 16
|
|
|
|
typedef void (*qb_map_notify_fn)(uint32_t event,
|
|
char* key,
|
|
void* old_value,
|
|
void* value,
|
|
void* user_data);
|
|
|
|
typedef int32_t (*qb_map_transverse_fn)(const char* key,
|
|
void* value,
|
|
void* user_data);
|
|
|
|
/**
|
|
* Create an unsorted map based on a hashtable.
|
|
*
|
|
* @param max_size maximum size of the hashtable
|
|
*
|
|
* @return the map instance
|
|
*/
|
|
qb_map_t* qb_hashtable_create(size_t max_size);
|
|
|
|
/**
|
|
* Create a sorted map using a skiplist.
|
|
*
|
|
* @return the map instance
|
|
*/
|
|
qb_map_t* qb_skiplist_create(void);
|
|
|
|
/**
|
|
* Create a sorted map using a Patricia trie or "Radix tree".
|
|
*
|
|
* @htmlonly
|
|
* See the wikipedia <a href="http://en.wikipedia.org/wiki/Radix_Tree">Radix_tree</a>
|
|
* and <a href="http://en.wikipedia.org/wiki/Trie">Trie</a> pages.
|
|
* @endhtmlonly
|
|
*/
|
|
qb_map_t* qb_trie_create(void);
|
|
|
|
/**
|
|
* print out the nodes in the trie
|
|
*
|
|
* (for debug purposes)
|
|
*/
|
|
void
|
|
qb_trie_dump(qb_map_t* m);
|
|
|
|
/**
|
|
* Add a notifier to the map.
|
|
*
|
|
* @param m the map instance
|
|
* @param key the key (or prefix) to attach the notification to.
|
|
* @param fn the callback
|
|
* @param events the type of events to register for.
|
|
* @param user_data a pointer to be passed into the callback
|
|
*
|
|
* @note QB_MAP_NOTIFY_INSERTED is only valid on tries.
|
|
* @note you can use key prefixes with trie maps.
|
|
*
|
|
* @retval 0 success
|
|
* @retval -errno failure
|
|
*/
|
|
int32_t qb_map_notify_add(qb_map_t* m, const char* key,
|
|
qb_map_notify_fn fn, int32_t events,
|
|
void *user_data);
|
|
|
|
/**
|
|
* Delete a notifier from the map.
|
|
*
|
|
* @note the key,fn and events must match those you added.
|
|
*
|
|
* @param m the map instance
|
|
* @param key the key (or prefix) to attach the notification to.
|
|
* @param fn the callback
|
|
* @param events the type of events to register for.
|
|
*
|
|
* @retval 0 success
|
|
* @retval -errno failure
|
|
*/
|
|
int32_t qb_map_notify_del(qb_map_t* m, const char* key,
|
|
qb_map_notify_fn fn, int32_t events);
|
|
|
|
/**
|
|
* Delete a notifier from the map (including the userdata).
|
|
*
|
|
* @note the key, fn, events and userdata must match those you added.
|
|
*
|
|
* @param m the map instance
|
|
* @param key the key (or prefix) to attach the notification to.
|
|
* @param fn the callback
|
|
* @param events the type of events to register for.
|
|
* @param user_data a pointer to be passed into the callback
|
|
*
|
|
* @retval 0 success
|
|
* @retval -errno failure
|
|
*/
|
|
int32_t qb_map_notify_del_2(qb_map_t* m, const char* key,
|
|
qb_map_notify_fn fn, int32_t events,
|
|
void *user_data);
|
|
|
|
/**
|
|
* Inserts a new key and value into a qb_map_t.
|
|
*
|
|
* If the key already exists in the qb_map_t, it gets replaced by the new key.
|
|
*/
|
|
void qb_map_put(qb_map_t *map, const char* key, const void* value);
|
|
|
|
/**
|
|
* Gets the value corresponding to the given key.
|
|
*
|
|
* @retval NULL (if the key does not exist)
|
|
* @retval a pointer to the value
|
|
*/
|
|
void* qb_map_get(qb_map_t *map, const char* key);
|
|
|
|
/**
|
|
* Removes a key/value pair from a map.
|
|
*/
|
|
int32_t qb_map_rm(qb_map_t *map, const char* key);
|
|
|
|
/**
|
|
* Get the number of items in the map.
|
|
*/
|
|
size_t qb_map_count_get(qb_map_t *map);
|
|
|
|
/**
|
|
* Calls the given function for each of the key/value pairs in the map.
|
|
*
|
|
* The function is passed the key and value of each pair, and the given data
|
|
* parameter. The map is traversed in sorted order.
|
|
*/
|
|
void qb_map_foreach(qb_map_t *map, qb_map_transverse_fn func, void* user_data);
|
|
|
|
/**
|
|
* Create an iterator
|
|
*/
|
|
qb_map_iter_t* qb_map_iter_create(qb_map_t *map);
|
|
|
|
/**
|
|
* Create a prefix iterator.
|
|
*
|
|
* This will iterate over all items with the given
|
|
* prefix.
|
|
* @note this is only supported by the trie.
|
|
*/
|
|
qb_map_iter_t* qb_map_pref_iter_create(qb_map_t *map, const char* prefix);
|
|
|
|
/**
|
|
* Get the next item
|
|
*
|
|
* @param i the iterator
|
|
* @param value (out) the next item's value
|
|
*
|
|
* @retval the next key
|
|
* @retval NULL - the end of the iteration
|
|
*/
|
|
const char* qb_map_iter_next(qb_map_iter_t* i, void** value);
|
|
|
|
/**
|
|
* free the iterator
|
|
*
|
|
* @param i the iterator
|
|
*/
|
|
void qb_map_iter_free(qb_map_iter_t* i);
|
|
|
|
/**
|
|
* Destroy the map, removes all the items from the map.
|
|
*/
|
|
void qb_map_destroy(qb_map_t *map);
|
|
|
|
/* *INDENT-OFF* */
|
|
#ifdef __cplusplus
|
|
}
|
|
#endif
|
|
/* *INDENT-ON* */
|
|
|
|
#endif /* QB_MAP_H_DEFINED */
|