mirror of
https://github.com/MariaDB/server.git
synced 2025-01-21 06:22:28 +01:00
branches/innodb+: Port red-black tree code from branches/fts:r2283
This commit is contained in:
parent
35d626f098
commit
95c241b5a0
3 changed files with 1559 additions and 2 deletions
|
@ -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)
|
||||
|
|
304
include/ut0rbt.h
Normal file
304
include/ut0rbt.h
Normal file
|
@ -0,0 +1,304 @@
|
|||
/******************************************************
|
||||
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 */
|
1253
ut/ut0rbt.c
Normal file
1253
ut/ut0rbt.c
Normal file
File diff suppressed because it is too large
Load diff
Loading…
Reference in a new issue