Commit 5d731b74 authored by Michal Vaner's avatar Michal Vaner
Browse files

Update documentation of RBNode

git-svn-id: svn://bind10.isc.org/svn/bind10/branches/trac469@4128 e5f2f494-b856-4b98-b285-d166d9295462
parent 8a9a510e
......@@ -17,11 +17,11 @@
//! \file datasrc/rbtree.h
///
/// \note The purpose of the RBTree is to provide a generic map with
/// domain names as the key that can be used by various BIND 10 modules or
/// even by other applications. However, because of some unresolved design
/// issue, the design and interface are not fixed, and RBTree isn't ready to
/// be used as a base data structure by other modules.
/// \note The purpose of the RBTree is to provide a generic map with
/// domain names as the key that can be used by various BIND 10 modules or
/// even by other applications. However, because of some unresolved design
/// issue, the design and interface are not fixed, and RBTree isn't ready
/// to be used as a base data structure by other modules.
#include <dns/name.h>
#include <boost/utility.hpp>
......@@ -35,16 +35,18 @@ namespace datasrc {
namespace helper {
/// Helper function to remove the base domain from super domain
/// \brief Helper function to remove the base domain from super domain.
///
/// the precondition of this function is the super_name contains the
/// The precondition of this function is the super_name contains the
/// sub_name so
/// \code Name a("a.b.c");
/// Name b("b.c");
/// Name c = a - b;
/// \endcode
/// c will contain "a".
///
/// \note function in this namespace is not intended to be used outside.
/// \note Functions in this namespace is not intended to be used outside of
/// RBTree implementation.
inline isc::dns::Name
operator-(const isc::dns::Name& super_name, const isc::dns::Name& sub_name) {
return (super_name.split(0, super_name.getLabelCount() -
......@@ -55,63 +57,94 @@ operator-(const isc::dns::Name& super_name, const isc::dns::Name& sub_name) {
template <typename T>
class RBTree;
/// \brief \c RBNode use by RBTree to store any data related to one domain name
/// \brief \c RBNode is use by RBTree to store any data related to one domain
/// name.
///
/// It has two roles, the first one is as one node in the \c RBTree,
/// the second one is to store the data related to one domain name and maintain
/// the domain name hierarchy struct in one domain name space.
/// As for the first role, it has left, right, parent and color members
/// which is used to keep the balance of the \c RBTree.
/// As for the second role, \c RBNode use down pointer to refer to all its sub
/// domains, so the name of current node always relative to the up node. since
/// we only has down pointer without up pointer, so we can only walk down from
/// top domain to sub domain.
/// One special kind of node is non-terminal node
/// which has subdomains with RRset but itself doesn't have any RRsets.
/// This is meant to be used only from RBTree. It is meaningless to inherit it
/// or create instances of it from elsewhere. For that reason, the constructor
/// is private.
///
/// \note \c RBNode basically used internally by RBTree, it is meaningless to
/// inherited from it or create it without \c RBTree.
/// It serves three roles. One is to keep structure of the \c RBTree as a
/// red-black tree. For that purpose, it has left, right and parent pointers
/// and color member. These are private and accessed only from within the tree.
///
/// The second one is to store data for one domain name. The data related
/// functions can be used to access and set the data.
///
/// The third role is to keep the hierarchy of domains. The down pointer points
/// to a subtree of subdomains. Note that we can traverse the hierarchy down,
/// but not up.
///
/// One special kind of node is non-terminal node. It has subdomains with
/// RRsets, but doesn't have any RRsets itself.
template <typename T>
class RBNode : public boost::noncopyable {
public:
/// only \c RBTree can create and destroy \c RBNode
private:
/// The RBNode is meant for use from within RBTree, so it has access to
/// it.
friend class RBTree<T>;
typedef boost::shared_ptr<T> NodeDataPtr;
/// \name Destructor
/// \note it's seems a little strange that constructor is private
/// but deconstructor left public, the reason is for some smart pointer
/// like std::auto_ptr, they needs to delete RBNode in sometimes, but
/// \code delete *pointer_to_node \endcode shouldn't be called directly
/// \name Constructors
///
/// \note The existence of a RBNode without a RBTree is meaningless.
/// Therefore the constructors are private.
//@{
~RBNode();
/// \brief Default constructor.
///
/// This constructor is provided specifically for generating a special
/// "null" node.
RBNode();
/// \brief Constructor from the node name.
///
/// \param name The *relative* domain name (if this will live inside
/// a.b.c and is called d.e.a.b.c, then you pass d.e).
RBNode(const isc::dns::Name& name);
//@}
/// \name Test functions
public:
/// \brief Alias for shared pointer to the data.
typedef boost::shared_ptr<T> NodeDataPtr;
/// \brief Destructor
///
/// It might seem strange that constructors are private and destructor
/// public, but this is needed because of shared pointers need access
/// to the destructor.
///
/// You should never call \code delete pointer_to_node; \endcode, the
/// RBTree handles both creation and destructoion of nodes.
~RBNode();
/// \name Getter functions.
//@{
/// \brief return the name of current node, it's relative to its top node
/// \brief Return the name of current node.
///
/// It's relative to its containing node.
///
/// To get the absolute name of one node, the node path from the top node
/// to current node has to be recorded
/// to current node has to be recorded.
const isc::dns::Name& getName() const { return (name_); }
/// \brief return the data store in this node
/// \note, since the data is managed by RBNode, developer should not
/// free the pointer
/// \brief Return the data stored in this node.
///
/// You should not delete the data, it is handled by shared pointers.
NodeDataPtr& getData() { return (data_); }
/// \brief return the data stored in this node, read-only version
/// \brief Return the data stored in this node.
const NodeDataPtr& getData() const { return (data_); }
/// \brief return whether the node has related data
/// \note it's meaningless has empty \c RBNode in one RBTree, the only
/// exception is for non-terminal node which has sub domain nodes who
/// has data(rrset)
/// \brief return whether the node has related data.
///
/// There can be empty nodes inside the RBTree. They are usually the
/// non-terminal domains, but it is possible (yet probably meaningless)
/// empty nodes anywhere.
bool isEmpty() const { return (data_.get() == NULL); }
//@}
/// \name Modify functions
/// \name Setter functions.
//@{
/// \breif set the data stored in the node
/// \brief Set the data stored in the node.
void setData(const NodeDataPtr& data) { data_ = data; }
//@}
......@@ -122,8 +155,6 @@ public:
/// These methods never throw an exception.
//@{
/// Return if callback is enabled at the node.
///
/// This method never throws an exception.
bool isCallbackEnabled() const { return (callback_required_); }
/// Enable callback at the node.
......@@ -137,55 +168,45 @@ public:
private:
/// \brief Define rbnode color
enum RBNodeColor {BLACK, RED};
/// \name Constructors
/// \note \c Single RBNode is meaningless without living inside one \c RBTree
/// the creation and destroy of one \c RBNode is handle by host \c RBTree, so
/// the constructors and destructor of \c RBNode is left private
//@{
/// \brief Default constructor.
///
/// This constructor is provided specifically for generating a special
/// "null" node, and is intended be used only internally.
RBNode();
/// \brief Constructor from the node name.
///
/// \param name The domain name corresponding to the node.
RBNode(const isc::dns::Name& name);
//@}
/// This is a factory class method of a special singleton null node.
static RBNode<T>* NULL_NODE() {
static RBNode<T> null_node;
return (&null_node);
}
/// data to maintain the rbtree balance
/// \name Data to maintain the rbtree structure.
//@{
RBNode<T>* parent_;
RBNode<T>* left_;
RBNode<T>* right_;
RBNodeColor color_;
//@}
/// \brief Relative name of the node.
isc::dns::Name name_;
/// \brief Data stored here.
NodeDataPtr data_;
/// the down pointer points to the root node of sub domains of current
/// domain
/// \par Adding down pointer to \c RBNode is for two purpose:
/// \li Accelerate the search process, with sub domain tree, it split the
/// big flat tree into several hierarchy trees
/// \li It save memory useage, so same label won't be saved several times
/// \brief The subdomain tree.
///
/// This points to the root node of trees of subdomains of this domain.
///
/// \par Adding down pointer to \c RBNode has two purposes:
/// \li Accelerate the search process, with sub domain tree, it splits the
/// big flat tree into several hierarchy trees.
/// \li It saves memory useage as it allows storing only relative names,
/// avoiding storage of the same domain labels multiple times.
RBNode<T>* down_;
// If true, callback should be called at this node in search.
// (This may have to become part of more general "attribute flags")
/// \brief If callback should be called when traversing this node in
/// RBTree::find().
///
/// \todo It might be needed to put it into more general attributes field.
bool callback_required_;
};
// typically each node should has a name associate with it
// this construction is only used to create \c NULLNODE
// This is only to support NULL nodes.
template <typename T>
RBNode<T>::RBNode() :
parent_(this),
......
Supports Markdown
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