20 #ifndef KERNEL_UTILITIES_RADIX_TREE_H 21 #define KERNEL_UTILITIES_RADIX_TREE_H 23 #include "pedigree/kernel/Log.h" 24 #include "pedigree/kernel/compiler.h" 25 #include "pedigree/kernel/processor/types.h" 26 #include "pedigree/kernel/utilities/Iterator.h" 27 #include "pedigree/kernel/utilities/ObjectPool.h" 28 #include "pedigree/kernel/utilities/Result.h" 29 #include "pedigree/kernel/utilities/String.h" 30 #include "pedigree/kernel/utilities/Vector.h" 31 #include "pedigree/kernel/utilities/utility.h" 61 Node(
bool bCaseSensitive)
62 : m_Key(), value(T()), m_Children(), m_pParent(0),
63 m_bCaseSensitive(bCaseSensitive), m_pParentTree(0),
71 void returnAllChildren();
89 Node *findChild(
const char *cpKey)
const;
92 void addChild(
Node *pNode);
95 void replaceChild(
Node *pNodeOld,
Node *pNodeNew);
98 void removeChild(
Node *pChild);
103 MatchType matchKey(
const char *cpKey,
size_t &offset)
const;
106 Node *getFirstChild()
const;
111 void prependKey(
const char *cpKey);
113 void setKey(
const char *cpKey);
115 void setKey(
const char *cpKey,
size_t lengthHint);
116 inline const char *getKey()
const 120 inline void setValue(
const T &pV)
125 inline void removeValue()
130 inline const T &getValue()
const 134 inline void setParent(
Node *pP)
138 inline Node *getParent()
const 142 inline bool hasValue()
const 147 void dump(
void (*emit_line)(
const char *s))
const;
176 Node *doNext()
const;
180 Node *getNextSibling()
const;
206 size_t count()
const;
210 void insert(
const String &key,
const T &value);
216 void remove(
const String &key);
225 Node *next = iterNode->next();
226 remove(
String(iterNode->getKey()));
237 Iterator it(m_pRoot->next());
245 return ConstIterator(0);
246 ConstIterator it(m_pRoot->next());
257 inline ConstIterator
end()
const 259 return ConstIterator(0);
263 void dump(
void (*emit_line)(
const char *s))
const;
267 Node *cloneNode(Node *node, Node *parent);
271 Node *p = m_NodePool.allocate(m_bCaseSensitive);
272 p->m_pParentTree =
this;
283 p->m_bHasValue =
false;
284 m_NodePool.deallocate(p);
301 : m_nItems(0), m_pRoot(0), m_bCaseSensitive(true), m_NodePool()
359 const char *cpKey =
static_cast<const char *
>(key);
360 const char *cpKeyOrig = cpKey;
361 size_t cpKeyLength = key.length();
365 size_t partialOffset = 0;
366 switch (pNode->
matchKey(cpKey, partialOffset))
370 if (!pNode->hasValue())
375 pNode->setValue(value);
380 FATAL(
"RadixTree: algorithmic error!");
389 size_t i = partialOffset;
394 pInter->
m_Key.assign(cpKey, partialOffset);
400 size_t len = pNode->
m_Key.length();
407 &pNode->getKey()[partialOffset], len - partialOffset);
411 if (cpKey[partialOffset] != 0)
415 &cpKey[partialOffset],
416 (cpKeyLength - partialOffset - (cpKey - cpKeyOrig)));
417 pChild->setValue(value);
418 pChild->setParent(pInter);
423 pInter->setValue(value);
426 pInter->setParent(pNode->getParent());
428 pNode->setParent(pInter);
435 cpKey += pNode->
m_Key.length();
448 pChild->setKey(cpKey, cpKeyLength - (cpKey - cpKeyOrig));
449 pChild->setValue(value);
450 pChild->setParent(pNode);
466 return LookupType::withError(
true);
471 const char *cpKey =
static_cast<const char *
>(key);
476 switch (pNode->
matchKey(cpKey, offset))
479 if (!pNode->hasValue())
484 return LookupType::withError(
true);
486 return LookupType::withValue(pNode->getValue());
489 return LookupType::withError(
true);
492 cpKey += pNode->
m_Key.length();
503 return LookupType::withError(
true);
523 const char *cpKey =
static_cast<const char *
>(key);
536 switch (pNode->
matchKey(cpKey, offset))
543 pNode->removeValue();
562 pParent = pNode->getParent();
583 pParent = pNode->getParent();
599 pParent = pNode->getParent();
606 pChild->setParent(pParent);
620 cpKey += pNode->
m_Key.length();
644 n->setKey(pNode->
m_Key);
645 n->setValue(pNode->
value);
646 n->setParent(pParent);
691 for (
auto it : m_Children)
693 it->returnAllChildren();
704 for (
auto it : m_Children)
707 if (it->matchKey(cpKey, offset) != NoMatch)
719 m_Children.pushBack(pNode);
725 for (
auto it = m_Children.begin(); it != m_Children.end(); ++it)
740 it != m_Children.end();)
744 it = m_Children.erase(it);
762 const char *myKey = getKey();
773 int r = StringCompareCase(
781 else if (m_Key[i] == 0)
802 m_Key.assign(cpKey, lengthHint);
808 return *(m_Children.begin());
823 Node const *pNode =
this;
824 while ((pNode ==
this) || (pNode && (!pNode->
value)))
843 return const_cast<Node *
>(pNode);
854 m_pParent->m_Children.begin();
855 it != m_pParent->m_Children.end(); ++it)
869 for (
auto it : m_Children)
877 " \"Node<%p: %s>\" -> \"Node<%p: %s>\";",
878 static_cast<const void *>(it), it->getKey(),
879 static_cast<const void *
>(
this), static_cast<const char *>(m_Key));
880 emit_line(static_cast<const char *>(s));
ConstIterator end() const
ConstIterator begin() const
MatchType matchKey(const char *cpKey, size_t &offset) const
::Iterator< T, Node > Iterator
A key/value dictionary for string keys.
void insert(const String &key, const T &value)
Node * findChild(const char *cpKey) const
Node * getNextSibling() const
Key matched node key, and had extra characters.
Key matched node key exactly.
Iterator erase(Iterator iter)
Iterator::Const ConstIterator
Key didn't match node key at all.
Result< T, bool > lookup(const String &key) const
void dump(void(*emit_line)(const char *s)) const
const bool m_bCaseSensitive
A subset of key matched the node key.
RadixTree & operator=(const RadixTree &x)
void prependKey(const char *cpKey)
An iterator applicable for many data structures.
void removeChild(Node *pChild)
const bool m_bCaseSensitive
RadixTree * m_pParentTree
Node * getFirstChild() const
void replaceChild(Node *pNodeOld, Node *pNodeNew)
void remove(const String &key)
Node * cloneNode(Node *node, Node *parent)
void addChild(Node *pNode)
ObjectPool< Node > m_NodePool