/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (C) B.A.T.M.A.N. contributors:
 *
 * Simon Wunderlich, Marek Lindner
 */

#ifndef _NET_BATMAN_ADV_HASH_H_
#define _NET_BATMAN_ADV_HASH_H_

#include "main.h"

#include <linux/atomic.h>
#include <linux/compiler.h>
#include <linux/list.h>
#include <linux/lockdep.h>
#include <linux/rculist.h>
#include <linux/spinlock.h>
#include <linux/stddef.h>
#include <linux/types.h>

/* callback to a compare function.  should compare 2 element datas for their
 * keys
 *
 * Return: true if same and false if not same
 */
typedef bool (*batadv_hashdata_compare_cb)(const struct hlist_node *,
					   const void *);

/* the hashfunction
 *
 * Return: an index based on the key in the data of the first argument and the
 * size the second
 */
typedef u32 (*batadv_hashdata_choose_cb)(const void *, u32);
typedef void (*batadv_hashdata_free_cb)(struct hlist_node *, void *);

/**
 * struct batadv_hashtable - Wrapper of simple hlist based hashtable
 */
struct batadv_hashtable {
	/** @table: the hashtable itself with the buckets */
	struct hlist_head *table;

	/** @list_locks: spinlock for each hash list entry */
	spinlock_t *list_locks;

	/** @size: size of hashtable */
	u32 size;

	/** @generation: current (generation) sequence number */
	atomic_t generation;
};

/* allocates and clears the hash */
struct batadv_hashtable *batadv_hash_new(u32 size);

/* set class key for all locks */
void batadv_hash_set_lock_class(struct batadv_hashtable *hash,
				struct lock_class_key *key);

/* free only the hashtable and the hash itself. */
void batadv_hash_destroy(struct batadv_hashtable *hash);

/**
 *	batadv_hash_add() - adds data to the hashtable
 *	@hash: storage hash table
 *	@compare: callback to determine if 2 hash elements are identical
 *	@choose: callback calculating the hash index
 *	@data: data passed to the aforementioned callbacks as argument
 *	@data_node: to be added element
 *
 *	Return: 0 on success, 1 if the element already is in the hash
 *	and -1 on error.
 */
static inline int batadv_hash_add(struct batadv_hashtable *hash,
				  batadv_hashdata_compare_cb compare,
				  batadv_hashdata_choose_cb choose,
				  const void *data,
				  struct hlist_node *data_node)
{
	u32 index;
	int ret = -1;
	struct hlist_head *head;
	struct hlist_node *node;
	spinlock_t *list_lock; /* spinlock to protect write access */

	if (!hash)
		goto out;

	index = choose(data, hash->size);
	head = &hash->table[index];
	list_lock = &hash->list_locks[index];

	spin_lock_bh(list_lock);

	hlist_for_each(node, head) {
		if (!compare(node, data))
			continue;

		ret = 1;
		goto unlock;
	}

	/* no duplicate found in list, add new element */
	hlist_add_head_rcu(data_node, head);
	atomic_inc(&hash->generation);

	ret = 0;

unlock:
	spin_unlock_bh(list_lock);
out:
	return ret;
}

/**
 * batadv_hash_remove() - Removes data from hash, if found
 * @hash: hash table
 * @compare: callback to determine if 2 hash elements are identical
 * @choose: callback calculating the hash index
 * @data: data passed to the aforementioned callbacks as argument
 *
 * ata could be the structure you use with  just the key filled, we just need
 * the key for comparing.
 *
 * Return: returns pointer do data on success, so you can remove the used
 * structure yourself, or NULL on error
 */
static inline void *batadv_hash_remove(struct batadv_hashtable *hash,
				       batadv_hashdata_compare_cb compare,
				       batadv_hashdata_choose_cb choose,
				       void *data)
{
	u32 index;
	struct hlist_node *node;
	struct hlist_head *head;
	void *data_save = NULL;

	index = choose(data, hash->size);
	head = &hash->table[index];

	spin_lock_bh(&hash->list_locks[index]);
	hlist_for_each(node, head) {
		if (!compare(node, data))
			continue;

		data_save = node;
		hlist_del_rcu(node);
		atomic_inc(&hash->generation);
		break;
	}
	spin_unlock_bh(&hash->list_locks[index]);

	return data_save;
}

#endif /* _NET_BATMAN_ADV_HASH_H_ */
