Browse Source

add non reference counting tries

Kolja Strohm 1 year ago
parent
commit
0ebdbde86d

+ 55 - 1
CharMap.h

@@ -7,7 +7,7 @@ namespace Framework
     template<class T, class V> class CharMap : public virtual ReferenceCounter
     {
     private:
-        V* value;
+        V value;
         T** entries;
 
     public:
@@ -21,6 +21,60 @@ namespace Framework
         }
 
         ~CharMap()
+        {
+            for (int i = 0; i < 256; i++)
+            {
+                if (entries[i]) entries[i]->release();
+            }
+            delete[] entries;
+        }
+
+        T* get(unsigned char c)
+        {
+            return entries[(int)c]
+                     ? dynamic_cast<T*>(entries[(int)c]->getThis())
+                     : 0;
+        }
+
+        T* z(unsigned char c)
+        {
+            return entries[(int)c];
+        }
+
+        void set(unsigned char c, T* t)
+        {
+            if (entries[(int)c]) entries[(int)c]->release();
+            entries[(int)c] = t;
+        }
+
+        void setValue(V v)
+        {
+            value = v;
+        }
+
+        V getValue()
+        {
+            return value;
+        }
+    };
+
+    template<class T, class V> class RCCharMap : public virtual ReferenceCounter
+    {
+    private:
+        V* value;
+        T** entries;
+
+    public:
+        RCCharMap()
+            : ReferenceCounter()
+        {
+            entries = new T*[256];
+            for (int i = 0; i < 256; i++)
+                entries[i] = 0;
+            value = 0;
+        }
+
+        ~RCCharMap()
         {
             for (int i = 0; i < 256; i++)
             {

+ 1 - 0
Framework Tests/Framework Tests.vcxproj

@@ -176,6 +176,7 @@
       <PrecompiledHeader Condition="'$(Configuration)|$(Platform)'=='Release|x64'">Create</PrecompiledHeader>
     </ClCompile>
     <ClCompile Include="Text.cpp" />
+    <ClCompile Include="Trie.cpp" />
     <ClCompile Include="XML.cpp" />
   </ItemGroup>
   <ItemGroup>

+ 3 - 0
Framework Tests/Framework Tests.vcxproj.filters

@@ -36,6 +36,9 @@
     <ClCompile Include="Text.cpp">
       <Filter>Quelldateien</Filter>
     </ClCompile>
+    <ClCompile Include="Trie.cpp">
+      <Filter>Quelldateien</Filter>
+    </ClCompile>
   </ItemGroup>
   <ItemGroup>
     <ClInclude Include="pch.h">

BIN
Framework Tests/Framwork.dll


+ 34 - 0
Framework Tests/Trie.cpp

@@ -0,0 +1,34 @@
+#include "pch.h"
+
+#include <Trie.h>
+#include <Text.h>
+
+#include "CppUnitTest.h"
+
+using namespace Microsoft::VisualStudio::CppUnitTestFramework;
+using namespace Framework;
+
+namespace FrameworkTests
+{
+    TEST_CLASS (TrieTests)
+    {
+    public:
+        TEST_METHOD (SimpleTrieTest)
+        {
+            Trie<int> trie;
+            trie.set("test", 4, 1);
+            int x = trie.get("test", 4);
+            Assert::AreEqual(1, x, L"trie get returned invalid value");
+        }
+
+        TEST_METHOD (RCTrieTest)
+        {
+            RCTrie<Text> trie;
+            trie.set("test", 4, new Text("test"));
+            Text *t = trie.get("test", 4);
+            Assert::AreEqual(
+                t->getReferenceCount(), 2, L"RCTrie get did not increase reference count");
+            Assert::IsTrue(t->istGleich("test"), L"RCTrie get returned invalid value");
+        }
+    };
+} // namespace FrameworkTests

+ 90 - 25
Trie.h

@@ -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

+ 1 - 1
UIMLView.cpp

@@ -652,7 +652,7 @@ UIMLView::UIMLView()
 {
     style = Style::MEIgnoreInside | Style::MEIgnoreParentInside
           | Style::MEIgnoreSichtbar | Style::MEIgnoreVerarbeitet;
-    members = new Trie<Zeichnung>();
+    members = new RCTrie<Zeichnung>();
     dom = 0;
     nextId = 0;
     memset(&init, 0, sizeof(UIInit));

+ 1 - 1
UIMLView.h

@@ -215,7 +215,7 @@ namespace Framework
     private:
         RCArray<UIMLElement> knownElements;
         UIInit init;
-        Trie<Zeichnung>* members;
+        RCTrie<Zeichnung>* members;
         XML::Element* dom;
         int nextId;