NetworkManager/src/nm-multi-index.h
Thomas Haller 9bd4cf340d core: add NMMultiIndex class
A class to do efficient lookup for multiple values based on a key.

The values are opaque pointers (void*). These values can be
associated with keys. The keys are an opaque type NMMultiIndexId
with arbitrary hash/equal functions.

Think of the keys being a set of buckets. A value can be associated with multiple
keys, just like with a regular GHashTable (i.e. it can be in multiple buckets).
But one key can also be associated with multiple values (i.e. one bucket can contain
multiple values). Hence the name "multi".
One bucket can only either contain a value or not. It cannot contain the same
value multiple times.

This is implemented as a hash of hashes with the outer keys being
NMMultiIndexId. The inner hashes are the "buckets".

This class will be used as an efficient lookup index to find all values
that belong to a certain key (bucket). Later we will ask for example
"Which IP4-Addresses are associated with a certain ifindex" and
efficiently retrieve the cached result list.

(cherry picked from commit f99723eda5)
2015-06-21 15:21:56 +02:00

109 lines
4 KiB
C

/* -*- Mode: C; tab-width: 4; indent-tabs-mode: t; c-basic-offset: 4 -*- */
/* NetworkManager -- Network link manager
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 General Public License for more details.
*
* You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Copyright (C) 2015 Red Hat, Inc.
*/
#ifndef __NM_MULTI_INDEX__
#define __NM_MULTI_INDEX__
#include <glib.h>
G_BEGIN_DECLS
typedef struct {
char _dummy;
} NMMultiIndexId;
typedef struct NMMultiIndex NMMultiIndex;
typedef struct {
GHashTableIter _iter;
const NMMultiIndex *_index;
gconstpointer _value;
} NMMultiIndexIter;
typedef struct {
GHashTableIter _iter;
guint _state;
} NMMultiIndexIdIter;
typedef gboolean (*NMMultiIndexFuncEqual) (const NMMultiIndexId *id_a, const NMMultiIndexId *id_b);
typedef guint (*NMMultiIndexFuncHash) (const NMMultiIndexId *id);
typedef NMMultiIndexId *(*NMMultiIndexFuncClone) (const NMMultiIndexId *id);
typedef void (*NMMultiIndexFuncDestroy) (NMMultiIndexId *id);
typedef gboolean (*NMMultiIndexFuncForeach) (const NMMultiIndexId *id, void *const* values, guint len, gpointer user_data);
NMMultiIndex *nm_multi_index_new (NMMultiIndexFuncHash hash_fcn,
NMMultiIndexFuncEqual equal_fcn,
NMMultiIndexFuncClone clone_fcn,
NMMultiIndexFuncDestroy destroy_fcn);
void nm_multi_index_free (NMMultiIndex *index);
gboolean nm_multi_index_add (NMMultiIndex *index,
const NMMultiIndexId *id,
gconstpointer value);
gboolean nm_multi_index_remove (NMMultiIndex *index,
const NMMultiIndexId *id,
gconstpointer value);
gboolean nm_multi_index_move (NMMultiIndex *index,
const NMMultiIndexId *id_old,
const NMMultiIndexId *id_new,
gconstpointer value);
guint nm_multi_index_get_num_groups (const NMMultiIndex *index);
void *const*nm_multi_index_lookup (const NMMultiIndex *index,
const NMMultiIndexId *id,
guint *out_len);
gboolean nm_multi_index_contains (const NMMultiIndex *index,
const NMMultiIndexId *id,
gconstpointer value);
const NMMultiIndexId *nm_multi_index_lookup_first_by_value (const NMMultiIndex *index,
gconstpointer value);
void nm_multi_index_foreach (const NMMultiIndex *index,
gconstpointer value,
NMMultiIndexFuncForeach foreach_func,
gpointer user_data);
void nm_multi_index_iter_init (NMMultiIndexIter *iter,
const NMMultiIndex *index,
gconstpointer value);
gboolean nm_multi_index_iter_next (NMMultiIndexIter *iter,
const NMMultiIndexId **out_id,
void *const**out_values,
guint *out_len);
void nm_multi_index_id_iter_init (NMMultiIndexIdIter *iter,
const NMMultiIndex *index,
const NMMultiIndexId *id);
gboolean nm_multi_index_id_iter_next (NMMultiIndexIdIter *iter,
void **out_value);
G_END_DECLS
#endif /* __NM_MULTI_INDEX__ */