Linux Audio

Check our new training course

Loading...
v5.4
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Based on strlist.c by:
  4 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
  5 */
  6
  7#include <errno.h>
  8#include <stdio.h>
  9#include <stdlib.h>
 10
 11#include "rblist.h"
 12
 13int rblist__add_node(struct rblist *rblist, const void *new_entry)
 14{
 15	struct rb_node **p = &rblist->entries.rb_root.rb_node;
 16	struct rb_node *parent = NULL, *new_node;
 17	bool leftmost = true;
 18
 19	while (*p != NULL) {
 20		int rc;
 21
 22		parent = *p;
 23
 24		rc = rblist->node_cmp(parent, new_entry);
 25		if (rc > 0)
 26			p = &(*p)->rb_left;
 27		else if (rc < 0) {
 28			p = &(*p)->rb_right;
 29			leftmost = false;
 30		}
 31		else
 32			return -EEXIST;
 33	}
 34
 35	new_node = rblist->node_new(rblist, new_entry);
 36	if (new_node == NULL)
 37		return -ENOMEM;
 38
 39	rb_link_node(new_node, parent, p);
 40	rb_insert_color_cached(new_node, &rblist->entries, leftmost);
 41	++rblist->nr_entries;
 42
 43	return 0;
 44}
 45
 46void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
 47{
 48	rb_erase_cached(rb_node, &rblist->entries);
 49	--rblist->nr_entries;
 50	rblist->node_delete(rblist, rb_node);
 51}
 52
 53static struct rb_node *__rblist__findnew(struct rblist *rblist,
 54					 const void *entry,
 55					 bool create)
 56{
 57	struct rb_node **p = &rblist->entries.rb_root.rb_node;
 58	struct rb_node *parent = NULL, *new_node = NULL;
 59	bool leftmost = true;
 60
 61	while (*p != NULL) {
 62		int rc;
 63
 64		parent = *p;
 65
 66		rc = rblist->node_cmp(parent, entry);
 67		if (rc > 0)
 68			p = &(*p)->rb_left;
 69		else if (rc < 0) {
 70			p = &(*p)->rb_right;
 71			leftmost = false;
 72		}
 73		else
 74			return parent;
 75	}
 76
 77	if (create) {
 78		new_node = rblist->node_new(rblist, entry);
 79		if (new_node) {
 80			rb_link_node(new_node, parent, p);
 81			rb_insert_color_cached(new_node,
 82					       &rblist->entries, leftmost);
 83			++rblist->nr_entries;
 84		}
 85	}
 86
 87	return new_node;
 88}
 89
 90struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
 91{
 92	return __rblist__findnew(rblist, entry, false);
 93}
 94
 95struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry)
 96{
 97	return __rblist__findnew(rblist, entry, true);
 98}
 99
100void rblist__init(struct rblist *rblist)
101{
102	if (rblist != NULL) {
103		rblist->entries	 = RB_ROOT_CACHED;
104		rblist->nr_entries = 0;
105	}
106
107	return;
108}
109
110void rblist__exit(struct rblist *rblist)
111{
112	struct rb_node *pos, *next = rb_first_cached(&rblist->entries);
113
114	while (next) {
115		pos = next;
116		next = rb_next(pos);
117		rblist__remove_node(rblist, pos);
118	}
119}
120
121void rblist__delete(struct rblist *rblist)
122{
123	if (rblist != NULL) {
124		rblist__exit(rblist);
125		free(rblist);
126	}
127}
128
129struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx)
130{
131	struct rb_node *node;
132
133	for (node = rb_first_cached(&rblist->entries); node;
134	     node = rb_next(node)) {
135		if (!idx--)
136			return node;
137	}
138
139	return NULL;
140}
v6.8
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Based on strlist.c by:
  4 * (c) 2009 Arnaldo Carvalho de Melo <acme@redhat.com>
  5 */
  6
  7#include <errno.h>
  8#include <stdio.h>
  9#include <stdlib.h>
 10
 11#include "rblist.h"
 12
 13int rblist__add_node(struct rblist *rblist, const void *new_entry)
 14{
 15	struct rb_node **p = &rblist->entries.rb_root.rb_node;
 16	struct rb_node *parent = NULL, *new_node;
 17	bool leftmost = true;
 18
 19	while (*p != NULL) {
 20		int rc;
 21
 22		parent = *p;
 23
 24		rc = rblist->node_cmp(parent, new_entry);
 25		if (rc > 0)
 26			p = &(*p)->rb_left;
 27		else if (rc < 0) {
 28			p = &(*p)->rb_right;
 29			leftmost = false;
 30		}
 31		else
 32			return -EEXIST;
 33	}
 34
 35	new_node = rblist->node_new(rblist, new_entry);
 36	if (new_node == NULL)
 37		return -ENOMEM;
 38
 39	rb_link_node(new_node, parent, p);
 40	rb_insert_color_cached(new_node, &rblist->entries, leftmost);
 41	++rblist->nr_entries;
 42
 43	return 0;
 44}
 45
 46void rblist__remove_node(struct rblist *rblist, struct rb_node *rb_node)
 47{
 48	rb_erase_cached(rb_node, &rblist->entries);
 49	--rblist->nr_entries;
 50	rblist->node_delete(rblist, rb_node);
 51}
 52
 53static struct rb_node *__rblist__findnew(struct rblist *rblist,
 54					 const void *entry,
 55					 bool create)
 56{
 57	struct rb_node **p = &rblist->entries.rb_root.rb_node;
 58	struct rb_node *parent = NULL, *new_node = NULL;
 59	bool leftmost = true;
 60
 61	while (*p != NULL) {
 62		int rc;
 63
 64		parent = *p;
 65
 66		rc = rblist->node_cmp(parent, entry);
 67		if (rc > 0)
 68			p = &(*p)->rb_left;
 69		else if (rc < 0) {
 70			p = &(*p)->rb_right;
 71			leftmost = false;
 72		}
 73		else
 74			return parent;
 75	}
 76
 77	if (create) {
 78		new_node = rblist->node_new(rblist, entry);
 79		if (new_node) {
 80			rb_link_node(new_node, parent, p);
 81			rb_insert_color_cached(new_node,
 82					       &rblist->entries, leftmost);
 83			++rblist->nr_entries;
 84		}
 85	}
 86
 87	return new_node;
 88}
 89
 90struct rb_node *rblist__find(struct rblist *rblist, const void *entry)
 91{
 92	return __rblist__findnew(rblist, entry, false);
 93}
 94
 95struct rb_node *rblist__findnew(struct rblist *rblist, const void *entry)
 96{
 97	return __rblist__findnew(rblist, entry, true);
 98}
 99
100void rblist__init(struct rblist *rblist)
101{
102	if (rblist != NULL) {
103		rblist->entries	 = RB_ROOT_CACHED;
104		rblist->nr_entries = 0;
105	}
106
107	return;
108}
109
110void rblist__exit(struct rblist *rblist)
111{
112	struct rb_node *pos, *next = rb_first_cached(&rblist->entries);
113
114	while (next) {
115		pos = next;
116		next = rb_next(pos);
117		rblist__remove_node(rblist, pos);
118	}
119}
120
121void rblist__delete(struct rblist *rblist)
122{
123	if (rblist != NULL) {
124		rblist__exit(rblist);
125		free(rblist);
126	}
127}
128
129struct rb_node *rblist__entry(const struct rblist *rblist, unsigned int idx)
130{
131	struct rb_node *node;
132
133	for (node = rb_first_cached(&rblist->entries); node;
134	     node = rb_next(node)) {
135		if (!idx--)
136			return node;
137	}
138
139	return NULL;
140}