1
0
mirror of git://projects.qi-hardware.com/wernermisc.git synced 2024-11-25 02:26:16 +02:00
wernermisc/qpkg/jrb.h
Werner Almesberger 03c5e4ffe7 qpkg: optimize duplicate lookup when inserting a new name
- jrb.h, jrb.c (jrb_find_or_insert): new function to look for a node and
  to insert a new one if not found
- id.c (make_id): use jrb_find_or_insert to avoid looking up new nodes
  twice
- TODO: report the improvement
2010-11-19 22:20:15 -03:00

127 lines
3.9 KiB
C

/*
Libraries for fields, doubly-linked lists and red-black trees.
Copyright (C) 2001 James S. Plank
This library 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.
This library 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 this library; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
---------------------------------------------------------------------------
Please see http://www.cs.utk.edu/~plank/plank/classes/cs360/360/notes/Libfdr/
for instruction on how to use this library.
Jim Plank
plank@cs.utk.edu
http://www.cs.utk.edu/~plank
Associate Professor
Department of Computer Science
University of Tennessee
203 Claxton Complex
1122 Volunteer Blvd.
Knoxville, TN 37996-3450
865-974-4397
Fax: 865-974-4404
*/
/* Heavily edited and reformatted to K&R style 2010 by Werner Almesberger */
#ifndef _JRB_H_
#define _JRB_H_
/* Main jrb_node. You only ever use the fields
flink
blink
k.key or k.ikey
v.val
*/
struct jrb {
unsigned char red;
unsigned char internal;
unsigned char left;
unsigned char roothead; /* (bit 1 is root, bit 2 is head) */
struct jrb *flink;
struct jrb *blink;
struct jrb *parent;
void *key;
void *val;
};
struct jrb *make_jrb(void); /* Creates a new rb-tree */
/* Creates a node with key key and val val and inserts it into the tree.
jrb_insert uses strcmp() as comparison funcion. jrb_inserti uses <>=,
jrb_insertg uses func() */
struct jrb *jrb_insert(struct jrb *tree, void *key, void *val,
int (*func)(const void *a, const void *b));
/* If the key already exists, return the node (without altering it).
Otherwise, insert a new node. */
struct jrb *jrb_find_or_insert(struct jrb *tree, void *key, void *val,
int (*func)(const void *a, const void *b));
/* returns an external node in t whose value is equal k. Returns NULL if
there is no such node in the tree */
struct jrb *jrb_find(struct jrb *root, const void *key,
int (*func)(const void *a, const void *b));
/* returns an external node in t whose value is equal
k or whose value is the smallest value greater than k. Sets found to
1 if the key was found, and 0 otherwise. */
struct jrb *jrb_find_gte(struct jrb *root, const void *key,
int (*func)(const void *a, const void *b), int *found);
/* Creates a node with key key and val val and inserts it into the
tree before/after node nd. Does not check to ensure that you are
keeping the correct order */
void jrb_delete_node(struct jrb *node); /* Deletes and frees a node (but
not the key or val) */
void jrb_free_tree(struct jrb *root); /* Deletes and frees an entire tree */
void *jrb_val(struct jrb *node); /* Returns node->v.val -- this is to shut
lint up */
int jrb_nblack(struct jrb *n); /* returns # of black nodes in path from
n to the root */
int jrb_plength(struct jrb *n); /* returns the # of nodes in path from
n to the root */
#define jrb_first(n) ((n)->flink)
#define jrb_last(n) ((n)->blink)
#define jrb_next(n) ((n)->flink)
#define jrb_prev(n) ((n)->blink)
#define jrb_empty(t) ((t)->flink == (t))
#ifndef jrb_nil
#define jrb_nil(t) (t)
#endif
#define jrb_traverse(ptr, lst) \
for (ptr = jrb_first(lst); ptr != jrb_nil(lst); ptr = jrb_next(ptr))
#define jrb_rtraverse(ptr, lst) \
for (ptr = jrb_last(lst); ptr != jrb_nil(lst); ptr = jrb_prev(ptr))
#endif