blob: 6ed7a3208cd34879bd8bc507ae3883caa1825ef8 [file] [log] [blame]
/* **********************************************************
* Copyright (c) 2012 Google, Inc. All rights reserved.
* Copyright (c) 2007-2010 VMware, Inc. All rights reserved.
* **********************************************************/
/* Dr. Memory: the memory debugger
*
* 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;
* version 2.1 of the License, and no 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
* Library 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
*/
#ifndef _REDBLACK_H_
#define _REDBLACK_H_
/* Interval tree for address ranges implemented as a red-black binary tree.
* Assumes that no intervals in the tree overlap and they are all
* open at the upper end.
*/
#include "dr_api.h"
/* opaque structs */
struct _rb_node_t;
typedef struct _rb_node_t rb_node_t;
struct _rb_tree_t;
typedef struct _rb_tree_t rb_tree_t;
/* Synchronization is up to the caller. A lock should be held from
* the point of a call to any routine here to the last use of any
* returned rb_node_t*.
*/
/* Allocate a new, empy tree. free_payload_func, if non-null, will be called
* to free the client field whenever a node is freed.
*/
rb_tree_t *
rb_tree_create(void (*free_payload_func)(void*));
/* Remove and free all nodes in the tree and free the tree itself */
void
rb_tree_destroy(rb_tree_t *tree);
/* Retrieve copies of fields. The node pointer is then no longer needed. */
void
rb_node_fields(rb_node_t *node, byte **base OUT, size_t *size OUT, void **client OUT);
/* Modify the client field of a node. */
void
rb_node_set_client(rb_node_t *node, void *client);
/* Insert a node into the tree. If an existing node overlaps with [base,base+size),
* returns that node; else, adds a new node and returns NULL.
*/
rb_node_t *
rb_insert(rb_tree_t *tree, byte *base, size_t size, void *client);
/* Find the node with base 'base' */
rb_node_t *
rb_find(rb_tree_t *tree, byte *base);
/* Find the first node with client field == 'client' */
rb_node_t *
rb_find_client_node(rb_tree_t *tree, void *client);
/* Check if 'addr' is in the [base,base+size) of any node */
rb_node_t *
rb_in_node(rb_tree_t *tree, byte *addr);
/* Check if the range [start, end] overlaps with [base,base+size) of any node */
rb_node_t *
rb_overlaps_node(rb_tree_t *tree, byte *start, byte *end);
/* Finds the node [base,base+size) with smallest base such that base+size >= addr */
rb_node_t *
rb_next_higher_node(rb_tree_t *tree, byte *addr);
/* Finds the node [base,base+size) with largest base such that base <= addr */
rb_node_t *
rb_next_lower_node(rb_tree_t *tree, byte *addr);
/* Remove a node from the RB tree */
void
rb_delete(rb_tree_t *tree, rb_node_t *node);
/* Remove and free all nodes in the tree */
void
rb_clear(rb_tree_t *tree);
/* Returns node with highest base+size */
rb_node_t *
rb_max_node(rb_tree_t *tree);
/* Returns node with lowest base */
rb_node_t *
rb_min_node(rb_tree_t *tree);
/* Performs an in-order traversal, calling iter_cb on each node. */
void
rb_iterate(rb_tree_t *tree, bool (*iter_cb)(rb_node_t *, void *), void *iter_data);
#ifdef DEBUG_UNIT_TEST
void
rb_print(rb_tree_t *tree, char *filename);
bool
rb_check_tree(rb_tree_t *tree);
#endif
#endif /* _REDBLACK_H_ */