Commit a8824182 authored by sunny's avatar sunny

branches/innodb+: Port red-black tree code from branches/fts:r2283

parent fceb78e6
......@@ -130,7 +130,7 @@ noinst_HEADERS = include/btr0btr.h include/btr0btr.ic \
include/ut0list.ic include/ut0wqueue.h \
include/ha_prototypes.h handler/ha_innodb.h \
include/handler0alter.h \
handler/i_s.h
handler/i_s.h include/ut0rbt.h
EXTRA_LIBRARIES = libinnobase.a
noinst_LIBRARIES = @plugin_innobase_static_target@
......@@ -173,7 +173,7 @@ libinnobase_a_SOURCES = btr/btr0btr.c btr/btr0cur.c btr/btr0pcur.c \
ut/ut0ut.c ut/ut0vec.c ut/ut0wqueue.c \
handler/ha_innodb.cc handler/handler0alter.cc \
handler/i_s.cc \
handler/mysql_addons.cc
handler/mysql_addons.cc ut/ut0rbt.c
libinnobase_a_CXXFLAGS= $(AM_CFLAGS) $(INNODB_CFLAGS)
libinnobase_a_CFLAGS = $(AM_CFLAGS) $(INNODB_CFLAGS)
......
/******************************************************
Red-Black tree implementation.
(c) 2007 Oracle/Innobase Oy
Created 2007-03-20 Sunny Bains
*******************************************************/
#ifndef INNOBASE_UT0RBT_H
#define INNOBASE_UT0RBT_H
#if !defined(IB_RBT_TESTING)
#include "univ.i"
#include "ut0mem.h"
#else
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <assert.h>
#define ut_malloc malloc
#define ut_free free
#define ulint unsigned long
#define ut_a(c) assert(c)
#define ut_error assert(0)
#define ibool unsigned int
#define TRUE 1
#define FALSE 0
#endif
/* Red black tree typedefs */
typedef struct ib_rbt_struct ib_rbt_t;
typedef struct ib_rbt_node_struct ib_rbt_node_t;
// FIXME: Iterator is a better name than _bound_
typedef struct ib_rbt_bound_struct ib_rbt_bound_t;
typedef void (*ib_rbt_print_node)(const ib_rbt_node_t* node);
typedef int (*ib_rbt_compare)(const void* p1, const void* p2);
/* Red black tree color types */
enum ib_rbt_color_enum {
IB_RBT_RED,
IB_RBT_BLACK
};
typedef enum ib_rbt_color_enum ib_rbt_color_t;
/* Red black tree node */
struct ib_rbt_node_struct {
ib_rbt_color_t color; /* color of this node */
ib_rbt_node_t* left; /* points left child */
ib_rbt_node_t* right; /* points right child */
ib_rbt_node_t* parent; /* points parent node */
char value[1]; /* Data value */
};
/* Red black tree instance.*/
struct ib_rbt_struct {
ib_rbt_node_t* nil; /* Black colored node that is
used as a sentinel. This is
pre-allocated too.*/
ib_rbt_node_t* root; /* Root of the tree, this is
pre-allocated and the first
data node is the left child.*/
ulint n_nodes; /* Total number of data nodes */
ib_rbt_compare compare; /* Fn. to use for comparison */
ulint sizeof_value; /* Sizeof the item in bytes */
};
/* The result of searching for a key in the tree, this is useful for
a speedy lookup and insert if key doesn't exist.*/
struct ib_rbt_bound_struct {
const ib_rbt_node_t*
last; /* Last node visited */
int result; /* Result of comparing with
the last non-nil node that
was visited */
};
/* Size in elements (t is an rb tree instance) */
#define rbt_size(t) (t->n_nodes)
/* Check whether the rb tree is empty (t is an rb tree instance) */
#define rbt_empty(t) (rbt_size(t) == 0)
/* Get data value (t is the data type, n is an rb tree node instance) */
#define rbt_value(t, n) ((t*) &n->value[0])
/* Compare a key with the node value (t is tree, k is key, n is node)*/
#define rbt_compare(t, k, n) (t->compare(k, n->value))
/************************************************************************
Free an instance of a red black tree */
extern
void
rbt_free(
/*=====*/
ib_rbt_t* tree); /* in: rb tree to free */
/************************************************************************
Create an instance of a red black tree */
extern
ib_rbt_t*
rbt_create(
/*=======*/
/* out: rb tree instance */
size_t sizeof_value, /* in: size in bytes */
ib_rbt_compare compare); /* in: comparator */
/************************************************************************
Delete a node from the red black tree, identified by key */
extern
ibool
rbt_delete(
/*=======*/
/* in: TRUE on success */
ib_rbt_t* tree, /* in: rb tree */
const void* key); /* in: key to delete */
/************************************************************************
Remove a node from the red black tree, NOTE: This function will not delete
the node instance, THAT IS THE CALLERS RESPONSIBILITY.*/
extern
ib_rbt_node_t*
rbt_remove_node(
/*============*/
/* out: the deleted node
with the const.*/
ib_rbt_t* tree, /* in: rb tree */
const ib_rbt_node_t*
node); /* in: node to delete, this
is a fudge and declared const
because the caller has access
only to const nodes.*/
/************************************************************************
Return a node from the red black tree, identified by
key, NULL if not found */
extern
const ib_rbt_node_t*
rbt_lookup(
/*=======*/
/* out: node if found else
return NULL*/
const ib_rbt_t* tree, /* in: rb tree to search */
const void* key); /* in: key to lookup */
/************************************************************************
Add data to the red black tree, identified by key (no dups yet!)*/
extern
const ib_rbt_node_t*
rbt_insert(
/*=======*/
/* out: inserted node */
ib_rbt_t* tree, /* in: rb tree */
const void* key, /* in: key for ordering */
const void* value); /* in: data that will be
copied to the node.*/
/************************************************************************
Add a new node to the tree, useful for data that is pre-sorted.*/
extern
const ib_rbt_node_t*
rbt_add_node(
/*=========*/
/* out: appended node */
ib_rbt_t* tree, /* in: rb tree */
ib_rbt_bound_t* parent, /* in: parent */
const void* value); /* in: this value is copied
to the node */
/************************************************************************
Return the left most data node in the tree*/
extern
const ib_rbt_node_t*
rbt_first(
/*======*/
/* out: left most node */
const ib_rbt_t* tree); /* in: rb tree */
/************************************************************************
Return the right most data node in the tree*/
extern
const ib_rbt_node_t*
rbt_last(
/*=====*/
/* out: right most node */
const ib_rbt_t* tree); /* in: rb tree */
/************************************************************************
Return the next node from current.*/
extern
const ib_rbt_node_t*
rbt_next(
/*=====*/
/* out: successor node to
current that is passed in.*/
const ib_rbt_t* tree, /* in: rb tree */
const ib_rbt_node_t* /* in: current node */
current);
/************************************************************************
Return the prev node from current.*/
extern
const ib_rbt_node_t*
rbt_prev(
/*=====*/
/* out: precedessor node to
current that is passed in */
const ib_rbt_t* tree, /* in: rb tree */
const ib_rbt_node_t* /* in: current node */
current);
/************************************************************************
Find the node that has the lowest key that is >= key.*/
extern
const ib_rbt_node_t*
rbt_lower_bound(
/*============*/
/* out: node that satisfies
the lower bound constraint or
NULL */
const ib_rbt_t* tree, /* in: rb tree */
const void* key); /* in: key to search */
/************************************************************************
Find the node that has the greatest key that is <= key.*/
extern
const ib_rbt_node_t*
rbt_upper_bound(
/*============*/
/* out: node that satisifies
the upper bound constraint or
NULL */
const ib_rbt_t* tree, /* in: rb tree */
const void* key); /* in: key to search */
/************************************************************************
Search for the key, a node will be retuned in parent.last, whether it
was found or not. If not found then parent.last will contain the
parent node for the possibly new key otherwise the matching node.*/
extern
int
rbt_search(
/*=======*/
/* out: result of last
comparison */
const ib_rbt_t* tree, /* in: rb tree */
ib_rbt_bound_t* parent, /* in: search bounds */
const void* key); /* in: key to search */
/************************************************************************
Search for the key, a node will be retuned in parent.last, whether it
was found or not. If not found then parent.last will contain the
parent node for the possibly new key otherwise the matching node.*/
extern
int
rbt_search_cmp(
/*===========*/
/* out: result of last
comparison */
const ib_rbt_t* tree, /* in: rb tree */
ib_rbt_bound_t* parent, /* in: search bounds */
const void* key, /* in: key to search */
ib_rbt_compare compare); /* in: comparator */
/************************************************************************
Clear the tree, deletes (and free's) all the nodes.*/
extern
void
rbt_clear(
/*======*/
ib_rbt_t* tree); /* in: rb tree */
/************************************************************************
Merge the node from dst into src. Return the number of nodes merged.*/
extern
ulint
rbt_merge_uniq(
/*===========*/
/* out: no. of recs merged */
ib_rbt_t* dst, /* in: dst rb tree */
const ib_rbt_t* src); /* in: src rb tree */
/************************************************************************
Merge the node from dst into src. Return the number of nodes merged.
Delete the nodes from src after copying node to dst. As a side effect
the duplicates will be left untouched in the src, since we don't support
duplicates (yet). NOTE: src and dst must be similar, the function doesn't
check for this condition (yet).*/
extern
ulint
rbt_merge_uniq_destructive(
/*=======================*/
/* out: no. of recs merged */
ib_rbt_t* dst, /* in: dst rb tree */
ib_rbt_t* src); /* in: src rb tree */
/************************************************************************
Verify the integrity of the RB tree. For debugging. 0 failure else height
of tree (in count of black nodes).*/
extern
ibool
rbt_validate(
/*=========*/
/* out: TRUE if OK
FALSE if tree invalid.*/
const ib_rbt_t* tree); /* in: tree to validate */
/************************************************************************
Iterate over the tree in depth first order.*/
extern
void
rbt_print(
/*======*/
const ib_rbt_t* tree, /* in: tree to traverse */
ib_rbt_print_node print); /* in: print function */
#endif /* INNOBASE_UT0RBT_H */
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment