name-tree-hashtable.hpp
Go to the documentation of this file.
1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3  * Copyright (c) 2014-2022, Regents of the University of California,
4  * Arizona Board of Regents,
5  * Colorado State University,
6  * University Pierre & Marie Curie, Sorbonne University,
7  * Washington University in St. Louis,
8  * Beijing Institute of Technology,
9  * The University of Memphis.
10  *
11  * This file is part of NFD (Named Data Networking Forwarding Daemon).
12  * See AUTHORS.md for complete list of NFD authors and contributors.
13  *
14  * NFD is free software: you can redistribute it and/or modify it under the terms
15  * of the GNU General Public License as published by the Free Software Foundation,
16  * either version 3 of the License, or (at your option) any later version.
17  *
18  * NFD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY;
19  * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
20  * PURPOSE. See the GNU General Public License for more details.
21  *
22  * You should have received a copy of the GNU General Public License along with
23  * NFD, e.g., in COPYING.md file. If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 #ifndef NFD_DAEMON_TABLE_NAME_TREE_HASHTABLE_HPP
27 #define NFD_DAEMON_TABLE_NAME_TREE_HASHTABLE_HPP
28 
29 #include "name-tree-entry.hpp"
30 
31 namespace nfd::name_tree {
32 
33 class Entry;
34 
37 using HashValue = size_t;
38 
42 using HashSequence = std::vector<HashValue>;
43 
47 computeHash(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max());
48 
53 computeHashes(const Name& name, size_t prefixLen = std::numeric_limits<size_t>::max());
54 
60 class Node : noncopyable
61 {
62 public:
66  Node(HashValue h, const Name& name);
67 
71  ~Node();
72 
73 public:
74  const HashValue hash;
77  mutable Entry entry;
78 };
79 
83 Node*
84 getNode(const Entry& entry);
85 
91 template<typename N, typename F>
92 void
93 foreachNode(N* head, const F& func)
94 {
95  N* node = head;
96  while (node != nullptr) {
97  N* next = node->next;
98  func(node);
99  node = next;
100  }
101 }
102 
107 {
112  explicit
113  HashtableOptions(size_t size = 16);
114 
117  size_t initialSize;
118 
121  size_t minSize;
122 
125  float expandLoadFactor = 0.5f;
126 
129  float expandFactor = 2.0f;
130 
133  float shrinkLoadFactor = 0.1f;
134 
137  float shrinkFactor = 0.5f;
138 };
139 
149 {
150 public:
152 
153  explicit
154  Hashtable(const Options& options);
155 
158  ~Hashtable();
159 
162  size_t
163  size() const
164  {
165  return m_size;
166  }
167 
170  size_t
171  getNBuckets() const
172  {
173  return m_buckets.size();
174  }
175 
178  size_t
180  {
181  return h % this->getNBuckets();
182  }
183 
187  const Node*
188  getBucket(size_t bucket) const
189  {
190  BOOST_ASSERT(bucket < this->getNBuckets());
191  return m_buckets[bucket]; // don't use m_bucket.at() for better performance
192  }
193 
197  const Node*
198  find(const Name& name, size_t prefixLen) const;
199 
204  const Node*
205  find(const Name& name, size_t prefixLen, const HashSequence& hashes) const;
206 
211  std::pair<const Node*, bool>
212  insert(const Name& name, size_t prefixLen, const HashSequence& hashes);
213 
217  void
218  erase(Node* node);
219 
220 private:
223  void
224  attach(size_t bucket, Node* node);
225 
228  void
229  detach(size_t bucket, Node* node);
230 
231  std::pair<const Node*, bool>
232  findOrInsert(const Name& name, size_t prefixLen, HashValue h, bool allowInsert);
233 
234  void
235  computeThresholds();
236 
237  void
238  resize(size_t newNBuckets);
239 
240 private:
241  std::vector<Node*> m_buckets;
242  Options m_options;
243  size_t m_size;
244  size_t m_expandThreshold;
245  size_t m_shrinkThreshold;
246 };
247 
248 } // namespace nfd::name_tree
249 
250 #endif // NFD_DAEMON_TABLE_NAME_TREE_HASHTABLE_HPP
An entry in the name tree.
A hashtable for fast exact name lookup.
void erase(Node *node)
Delete node.
std::pair< const Node *, bool > insert(const Name &name, size_t prefixLen, const HashSequence &hashes)
Find or insert node for name.getPrefix(prefixLen).
const Node * find(const Name &name, size_t prefixLen) const
Find node for name.getPrefix(prefixLen).
Hashtable(const Options &options)
const Node * getBucket(size_t bucket) const
~Hashtable()
Deallocates all nodes.
size_t computeBucketIndex(HashValue h) const
Node(HashValue h, const Name &name)
std::vector< HashValue > HashSequence
A sequence of hash values.
HashValue computeHash(const Name &name, size_t prefixLen)
Computes hash value of name.getPrefix(prefixLen).
Node * getNode(const Entry &entry)
void foreachNode(N *head, const F &func)
Invoke a function for each node in a doubly linked list.
size_t HashValue
A single hash value.
HashSequence computeHashes(const Name &name, size_t prefixLen)
Computes hash values for each prefix of name.getPrefix(prefixLen).
Provides options for Hashtable.
float expandFactor
When the hashtable is expanded, its new size will be nBuckets*expandFactor.
float shrinkLoadFactor
If the hashtable has less than nBuckets*shrinkLoadFactor nodes, it will be shrunk.
float shrinkFactor
When the hashtable is shrunk, its new size will be max(nBuckets*shrinkFactor, minSize).
float expandLoadFactor
If the hashtable has more than nBuckets*expandLoadFactor nodes, it will be expanded.
HashtableOptions(size_t size=16)
Constructor.
size_t minSize
Minimal number of buckets.
size_t initialSize
Initial number of buckets.