blob: 812c9168a9190d0a579cb07c2e4510d312d92fa8 [file] [log] [blame]
HYuana9b85752014-02-26 02:32:30 -06001/* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2/**
3 * Copyright (C) 2014 Named Data Networking Project
4 * See COPYING for copyright and distribution information.
5 */
6
7// Name Tree (Name Prefix Hash Table)
8
9#ifndef NFD_TABLE_NAME_TREE_HPP
10#define NFD_TABLE_NAME_TREE_HPP
11
12#include "common.hpp"
13#include "name-tree-entry.hpp"
14
15namespace nfd {
16namespace name_tree {
17
18/**
19 * @brief Compute the hash value of the given name prefix.
20 * @todo 1) have another parameter that specifies the number of components
21 * 2) optimize the hash function to return a list of have values for all
22 * the (or a certain number of, like a batch operation) prefixes. 3) move
23 * the hash-related code to a separate file in /core or ndn-cpp-dev lib.
24 */
25uint32_t
26hashName(const Name& prefix);
27
Junxiao Shi40631842014-03-01 13:52:37 -070028/// a predicate to accept or reject an Entry in find operations
29typedef function<bool (const Entry& entry)> EntrySelector;
30
31struct AnyEntry {
32 bool
33 operator()(const Entry& entry)
34 {
35 return true;
36 }
37};
38
HYuana9b85752014-02-26 02:32:30 -060039} // namespace name_tree
40
41/**
42 * @brief Class Name Tree
43 */
44class NameTree : noncopyable
45{
46public:
47 explicit
48 NameTree(size_t nBuckets);
49
50 ~NameTree();
51
52 /**
53 * @brief Get the number of occupied entries in the Name Tree
54 */
55 size_t
56 size() const;
57
58 /**
59 * @brief Get the number of buckets in the Name Tree (NPHT)
60 * @details The number of buckets is the one that used to create the hash
61 * table, i.e., m_nBuckets.
62 */
63 size_t
64 getNBuckets() const;
65
66 /**
67 * @brief Look for the Name Tree Entry that contains this name prefix.
68 * @details Starts from the shortest name prefix, and then increase the
69 * number of name components by one each time. All non-existing Name Tree
70 * Entries will be created.
71 * @param prefix The querying name prefix.
72 * @return The pointer to the Name Tree Entry that contains this full name
73 * prefix.
74 */
75 shared_ptr<name_tree::Entry>
76 lookup(const Name& prefix);
77
78 /**
79 * @brief Exact match lookup for the given name prefix.
80 * @return a null shared_ptr if this prefix is not found;
81 * otherwise return the Name Tree Entry address
82 */
83 shared_ptr<name_tree::Entry>
84 findExactMatch(const Name& prefix) const;
85
86 /**
87 * @brief Erase a Name Tree Entry if this entry is empty.
88 * @details If a Name Tree Entry contains no Children, no FIB, no PIT, and
89 * no Measurements entries, then it can be erased. In addition, its parent entry
90 * will also be examined by following the parent pointer until all empty entries
91 * are erased.
92 * @param entry The pointer to the entry to be erased. The entry pointer should
93 * returned by the findExactMatch(), lookup(), or findLongestPrefixMatch() functions.
94 */
95 bool
96 eraseEntryIfEmpty(shared_ptr<name_tree::Entry> entry);
97
98 /**
99 * @brief Longest prefix matching for the given name
100 * @details Starts from the full name string, reduce the number of name component
101 * by one each time, until an Entry is found.
102 */
103 shared_ptr<name_tree::Entry>
Junxiao Shi40631842014-03-01 13:52:37 -0700104 findLongestPrefixMatch(const Name& prefix,
105 const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry());
HYuana9b85752014-02-26 02:32:30 -0600106
107 /**
108 * @brief Resize the hash table size when its load factor reaches a threshold.
109 * @details As we are currently using a hand-written hash table implementation
110 * for the Name Tree, the hash table resize() function should be kept in the
111 * name-tree.hpp file.
112 * @param newNBuckets The number of buckets for the new hash table.
113 */
114 void
115 resize(size_t newNBuckets);
116
117 /**
118 * @brief Enumerate all the name prefixes stored in the Name Tree.
119 */
120 shared_ptr<std::vector<shared_ptr<name_tree::Entry> > >
Junxiao Shi40631842014-03-01 13:52:37 -0700121 fullEnumerate(const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry());
HYuana9b85752014-02-26 02:32:30 -0600122
123 /**
124 * @brief Enumerate all the name prefixes under a specific name prefix
125 * @todo It might be better to have functions like fullEnemerateFib() to reduce the
126 * number of entries stored in the vector.
127 */
128 shared_ptr<std::vector<shared_ptr<name_tree::Entry> > >
Junxiao Shi40631842014-03-01 13:52:37 -0700129 partialEnumerate(const Name& prefix,
130 const name_tree::EntrySelector& entrySelector = name_tree::AnyEntry());
HYuana9b85752014-02-26 02:32:30 -0600131
132 /**
133 * @brief Dump all the information stored in the Name Tree for debugging.
134 */
135 void
136 dump(std::ostream& output);
137
138private:
139 size_t m_nItems; // Number of items being stored
140 size_t m_nBuckets; // Number of hash buckets
141 double m_loadFactor;
142 size_t m_resizeThreshold;
143 int m_resizeFactor;
144 name_tree::Node** m_buckets; // Name Tree Buckets in the NPHT
145
146 /**
147 * @brief Create a Name Tree Entry if it does not exist, or return the existing
148 * Name Tree Entry address.
149 * @details Called by lookup() only.
150 * @return The first item is the Name Tree Entry address, the second item is
151 * a bool value indicates whether this is an old entry (false) or a new
152 * entry (true).
153 */
154 std::pair<shared_ptr<name_tree::Entry>, bool>
155 insert(const Name& prefix);
156
157 /**
158 * @brief Helper function for partialEnumerate()
159 */
160 void
161 partialEnumerateAddChildren(shared_ptr<name_tree::Entry> entry,
Junxiao Shi40631842014-03-01 13:52:37 -0700162 const name_tree::EntrySelector& entrySelector,
163 std::vector<shared_ptr<name_tree::Entry> >& results);
HYuana9b85752014-02-26 02:32:30 -0600164
165};
166
167inline size_t
168NameTree::size() const
169{
170 return m_nItems;
171}
172
173inline size_t
174NameTree::getNBuckets() const
175{
176 return m_nBuckets;
177}
178
179} // namespace nfd
180
181#endif // NFD_TABLE_NAME_TREE_HPP