Browse Source

add hashmap implementation

Kolja Strohm 3 years ago
parent
commit
334e3f6d53
4 changed files with 192 additions and 0 deletions
  1. 50 0
      Array.h
  2. 1 0
      Framework Linux.vcxproj
  3. 3 0
      Framework Linux.vcxproj.filters
  4. 138 0
      HashMap.h

+ 50 - 0
Array.h

@@ -184,6 +184,23 @@ namespace Framework
             }
             return current->var;
         }
+
+        void set( TYP val )
+        {
+            if( current )
+            {
+                current->var = val;
+                current->set = true;
+            }
+            else
+            {
+                Text err = "Index out of Range Exception File: ";
+                err += __FILE__;
+                err += " Line: ";
+                err += __LINE__;
+                throw std::out_of_range( (char *)err );
+            }
+        }
     };
 #define _ val()
 
@@ -372,6 +389,39 @@ namespace Framework
             }
         }
 
+        //! Löscht ein Bestimmtes Element
+        //! \param i Der Index des Elementes das gelöscht werden soll
+        void removeValue( TYP value )
+        {
+            ArrayEintrag< TYP > *e = entries;
+            for( int a = 0; e->var != value; ++a )
+            {
+                if( !e->next )
+                    return;
+                e = e->next;
+            }
+            if( !e )
+                return;
+            if( e->next )
+            {
+                e->var = e->next->var;
+                e->set = e->next->set;
+            }
+            else
+                e->set = 0;
+            ArrayEintrag< TYP > *del = e->next;
+            if( e->next )
+                e->next = e->next->next;
+            else
+                e->next = 0;
+            if( del )
+            {
+                del->set = 0;
+                del->next = 0;
+                delete del;
+            }
+        }
+
         //! Vertauscht zwei Elemente in der Liste
         //! \param vi Der Index des ersten Elementes
         //! \param ni Der Index des zweiten Elementes

+ 1 - 0
Framework Linux.vcxproj

@@ -189,6 +189,7 @@
     <ClInclude Include="FrameworkMath.h" />
     <ClInclude Include="Globals.h" />
     <ClInclude Include="GraphicsApi.h" />
+    <ClInclude Include="HashMap.h" />
     <ClInclude Include="InitDatei.h" />
     <ClInclude Include="InMemoryBuffer.h" />
     <ClInclude Include="JSON.h" />

+ 3 - 0
Framework Linux.vcxproj.filters

@@ -303,6 +303,9 @@
     <ClInclude Include="InMemoryBuffer.h">
       <Filter>Headerdateien\Framework\IO</Filter>
     </ClInclude>
+    <ClInclude Include="HashMap.h">
+      <Filter>Headerdateien\Framework\Data</Filter>
+    </ClInclude>
   </ItemGroup>
   <ItemGroup>
     <ClCompile Include="Prozess.cpp">

+ 138 - 0
HashMap.h

@@ -0,0 +1,138 @@
+#pragma once
+
+#include <functional>
+
+#include "Array.h"
+
+namespace Framework
+{
+    template<typename K, typename V>
+    class MapEntry
+    {
+    private:
+        K key;
+        V value;
+
+    public:
+        MapEntry()
+        {}
+
+        MapEntry( K key, V value )
+            : key( key ),
+            value( value )
+        {}
+
+        K getKey()
+        {
+            return key;
+        }
+
+        V getValue()
+        {
+            return value;
+        }
+
+        template<typename K2, typename V2>
+        friend class HashMap;
+    };
+
+    template<typename K, typename V>
+    class HashMap : public virtual ReferenceCounter
+    {
+    private:
+        Array< MapEntry<K, V> > **buckets;
+        int bucketCount;
+        std::function<int( K )> hash;
+
+    public:
+        HashMap( int bucketCount, std::function<int( K )> hash )
+            : ReferenceCounter(),
+            buckets( new Array< MapEntry<K, V> > *[ bucketCount ] ),
+            bucketCount( bucketCount ),
+            hash( hash )
+        {
+            memset( buckets, 0, sizeof( Array< MapEntry<K, V> > * ) * bucketCount );
+        }
+
+        ~HashMap()
+        {
+            for( int i = 0; i < bucketCount; i++ )
+            {
+                if( buckets[ i ] )
+                    buckets[ i ]->release();
+            }
+            delete[] buckets;
+        }
+
+        void put( K key, V value )
+        {
+            int index = hash( key ) % bucketCount;
+            if( !buckets[ index ] )
+                buckets[ index ] = new Array< MapEntry<K, V>>();
+            for( auto iterator = buckets[ index ]->getIterator(); iterator; iterator++ )
+            {
+                if( iterator._.getKey() == key )
+                {
+                    iterator.set( MapEntry<K, V>( key, value ) );
+                    return;
+                }
+            }
+            buckets[ index ]->add( MapEntry<K, V>( key, value ) );
+        }
+
+        void remove( K key )
+        {
+            int index = hash( key ) % bucketCount;
+            if( !buckets[ index ] )
+                return;
+            int listIndex = 0;
+            for( auto iterator = buckets[ index ]->getIterator(); iterator; iterator++, listIndex++ )
+            {
+                if( iterator._.getKey() == key )
+                {
+                    buckets[ index ]->remove( listIndex );
+                    return;
+                }
+            }
+        }
+
+        V get( K key ) const
+        {
+            int index = hash( key ) % bucketCount;
+            if( !buckets[ index ] )
+                throw "element not found";
+            for( auto iterator = buckets[ index ]->getIterator(); iterator; iterator++ )
+            {
+                if( iterator._.getKey() == key )
+                    return iterator._.getValue();
+            }
+            throw "element not found";
+        }
+
+        V safeGet( K key, V fallback ) const
+        {
+            int index = hash( key ) % bucketCount;
+            if( !buckets[ index ] )
+                return fallback;
+            for( auto iterator = buckets[ index ]->getIterator(); iterator; iterator++ )
+            {
+                if( iterator._.getKey() == key )
+                    return iterator._.getValue();
+            }
+            return fallback;
+        }
+
+        bool has( K key ) const
+        {
+            int index = hash( key ) % bucketCount;
+            if( !buckets[ index ] )
+                return 0;
+            for( auto iterator = buckets[ index ]->getIterator(); iterator; iterator++ )
+            {
+                if( iterator._.getKey() == key )
+                    return 1;
+            }
+            return 0;
+        }
+    };
+}