|
@@ -4,12 +4,10 @@
|
|
|
|
|
|
namespace Framework
|
|
|
{
|
|
|
- template<class T> class Trie;
|
|
|
-
|
|
|
- template<class T> struct TrieIteratorData
|
|
|
+ template<class T, class M> struct TrieIteratorData
|
|
|
{
|
|
|
- CharMap<Trie<T>, T>* map;
|
|
|
- TrieIteratorData<T>* parent;
|
|
|
+ M* map;
|
|
|
+ TrieIteratorData* parent;
|
|
|
|
|
|
TrieIteratorData()
|
|
|
{
|
|
@@ -17,10 +15,10 @@ namespace Framework
|
|
|
parent = 0;
|
|
|
}
|
|
|
|
|
|
- TrieIteratorData(CharMap<Trie<T>, T>* zMap, TrieIteratorData<T> parent)
|
|
|
+ TrieIteratorData(M* zMap, TrieIteratorData parent)
|
|
|
{
|
|
|
map = zMap;
|
|
|
- this->parent = new TrieIteratorData<T>(parent);
|
|
|
+ this->parent = new TrieIteratorData(parent);
|
|
|
}
|
|
|
|
|
|
TrieIteratorData(const TrieIteratorData& data)
|
|
@@ -49,20 +47,20 @@ namespace Framework
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
- void set(CharMap<Trie<T>, T>* zMap, TrieIteratorData parent)
|
|
|
+ void set(M* zMap, TrieIteratorData parent)
|
|
|
{
|
|
|
map = zMap;
|
|
|
parent = new TrieIteratorData(parent);
|
|
|
}
|
|
|
};
|
|
|
|
|
|
- template<class T> class TrieIterator
|
|
|
+ template<class T, class M> class TrieIterator
|
|
|
{
|
|
|
private:
|
|
|
- TrieIteratorData<T> data;
|
|
|
+ TrieIteratorData<T, M> data;
|
|
|
|
|
|
public:
|
|
|
- TrieIterator(TrieIteratorData<T> data)
|
|
|
+ TrieIterator(TrieIteratorData<T, M> data)
|
|
|
{
|
|
|
this->data = data;
|
|
|
}
|
|
@@ -73,13 +71,13 @@ namespace Framework
|
|
|
{
|
|
|
if (data.map->z(i))
|
|
|
return TrieIterator(
|
|
|
- TrieIteratorData<T>(data.map->z(i)->map, data));
|
|
|
+ TrieIteratorData<T, M>(data.map->z(i)->map, data));
|
|
|
if (i == 255) break;
|
|
|
}
|
|
|
if (!data.parent || !data.parent->map)
|
|
|
return TrieIterator(
|
|
|
- TrieIteratorData<T>(0, TrieIteratorData<T>()));
|
|
|
- TrieIteratorData<T> d = data;
|
|
|
+ TrieIteratorData<T, M>(0, TrieIteratorData<T, M>()));
|
|
|
+ TrieIteratorData<T, M> d = data;
|
|
|
do
|
|
|
{
|
|
|
for (unsigned char i = 0; true; i++)
|
|
@@ -93,7 +91,7 @@ namespace Framework
|
|
|
j++)
|
|
|
{
|
|
|
if (d.parent->map->z(j))
|
|
|
- return TrieIterator(TrieIteratorData<T>(
|
|
|
+ return TrieIterator(TrieIteratorData<T, M>(
|
|
|
d.parent->map->z(j)->map, *d.parent));
|
|
|
if (j == 255) break;
|
|
|
}
|
|
@@ -104,18 +102,18 @@ namespace Framework
|
|
|
if (i == 255) break;
|
|
|
}
|
|
|
} while (d.parent && d.parent->map);
|
|
|
- return TrieIterator(TrieIteratorData<T>(0, TrieIteratorData<T>()));
|
|
|
+ return TrieIterator(TrieIteratorData<T, M>(0, TrieIteratorData<T, M>()));
|
|
|
}
|
|
|
|
|
|
- TrieIterator<T>& operator++() //! prefix
|
|
|
+ TrieIterator& operator++() //! prefix
|
|
|
{
|
|
|
data = next().data;
|
|
|
return *this;
|
|
|
}
|
|
|
|
|
|
- TrieIterator<T> operator++(int) //! postfix
|
|
|
+ TrieIterator operator++(int) //! postfix
|
|
|
{
|
|
|
- TrieIterator<T> temp(*this);
|
|
|
+ TrieIterator temp(*this);
|
|
|
data = next().data;
|
|
|
return temp;
|
|
|
}
|
|
@@ -158,7 +156,7 @@ namespace Framework
|
|
|
map->release();
|
|
|
}
|
|
|
|
|
|
- void set(const char* addr, int addrLen, T* value)
|
|
|
+ void set(const char* addr, int addrLen, T value)
|
|
|
{
|
|
|
if (!addrLen)
|
|
|
map->setValue(value);
|
|
@@ -180,6 +178,72 @@ namespace Framework
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+ T get(const char* addr, int addrLen)
|
|
|
+ {
|
|
|
+ if (!addrLen)
|
|
|
+ return map->getValue();
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (!map->z(*addr)) return 0;
|
|
|
+ return map->z(*addr)->get(addr + 1, addrLen - 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void leeren()
|
|
|
+ {
|
|
|
+ map->release();
|
|
|
+ map = new CharMap<Trie<T>, T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ TrieIterator<T, CharMap<Trie<T>, T>> getIterator()
|
|
|
+ {
|
|
|
+ return TrieIterator<T, CharMap<Trie<T>, T>>(
|
|
|
+ TrieIteratorData<T, CharMap<Trie<T>, T>>(
|
|
|
+ map, TrieIteratorData<T, CharMap<Trie<T>, T>>()));
|
|
|
+ }
|
|
|
+
|
|
|
+ friend TrieIterator<T, CharMap<Trie<T>, T>>;
|
|
|
+ };
|
|
|
+
|
|
|
+ template<class T> class RCTrie : public virtual ReferenceCounter
|
|
|
+ {
|
|
|
+ private:
|
|
|
+ RCCharMap<RCTrie<T>, T>* map;
|
|
|
+
|
|
|
+ public:
|
|
|
+ RCTrie()
|
|
|
+ : ReferenceCounter()
|
|
|
+ {
|
|
|
+ map = new RCCharMap<RCTrie<T>, T>();
|
|
|
+ }
|
|
|
+
|
|
|
+ ~RCTrie()
|
|
|
+ {
|
|
|
+ map->release();
|
|
|
+ }
|
|
|
+
|
|
|
+ void set(const char* addr, int addrLen, T* value)
|
|
|
+ {
|
|
|
+ if (!addrLen)
|
|
|
+ map->setValue(value);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (!map->z(*addr)) map->set(*addr, new RCTrie<T>());
|
|
|
+ map->z(*addr)->set(addr + 1, addrLen - 1, value);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ void remove(const char* addr, int addrLen)
|
|
|
+ {
|
|
|
+ if (!addrLen)
|
|
|
+ map->setValue(0);
|
|
|
+ else
|
|
|
+ {
|
|
|
+ if (!map->z(*addr)) return;
|
|
|
+ map->z(*addr)->remove(addr + 1, addrLen - 1);
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
T* get(const char* addr, int addrLen)
|
|
|
{
|
|
|
if (!addrLen)
|
|
@@ -205,15 +269,16 @@ namespace Framework
|
|
|
void leeren()
|
|
|
{
|
|
|
map->release();
|
|
|
- map = new CharMap<Trie<T>, T>();
|
|
|
+ map = new RCCharMap<RCTrie<T>, T>();
|
|
|
}
|
|
|
|
|
|
- TrieIterator<T> getIterator()
|
|
|
+ TrieIterator<T, RCCharMap<RCTrie<T>, T>> getIterator()
|
|
|
{
|
|
|
- return TrieIterator<T>(
|
|
|
- TrieIteratorData<T>(map, TrieIteratorData<T>()));
|
|
|
+ return TrieIterator<T, RCCharMap<RCTrie<T>, T>>(
|
|
|
+ TrieIteratorData<T, RCCharMap<RCTrie<T>, T>>(
|
|
|
+ map, TrieIteratorData<T, RCCharMap<RCTrie<T>, T>>()));
|
|
|
}
|
|
|
|
|
|
- friend TrieIterator<T>;
|
|
|
+ friend TrieIterator<T, RCCharMap<RCTrie<T>, T>>;
|
|
|
};
|
|
|
} // namespace Framework
|