Browse Source

avl_tree: using avl_tree in map object.

undefined
Guillaume Bittoun Sam Hocevar <sam@hocevar.net> 10 years ago
parent
commit
5829785014
3 changed files with 37 additions and 46 deletions
  1. +2
    -0
      src/lol/base/avl_tree.h
  2. +32
    -37
      src/lol/base/map.h
  3. +3
    -9
      src/lol/base/string.h

+ 2
- 0
src/lol/base/avl_tree.h View File

@@ -43,6 +43,8 @@ public:


for (auto iterator : other) for (auto iterator : other)
this->insert(iterator.key, iterator.value); this->insert(iterator.key, iterator.value);

return *this;
} }


~avl_tree() ~avl_tree()


+ 32
- 37
src/lol/base/map.h View File

@@ -16,6 +16,7 @@
// A very simple map class. // A very simple map class.
// //


#include <lol/base/avl_tree.h>
#include <lol/base/hash.h> #include <lol/base/hash.h>


namespace lol namespace lol
@@ -35,46 +36,54 @@ public:
inline V const& operator[] (E const &key) const inline V const& operator[] (E const &key) const
{ {
/* Look for the hash in our table and return the value. */ /* Look for the hash in our table and return the value. */
ptrdiff_t i = FindIndex(key);
ASSERT(i >= 0, "trying to read a nonexistent key in map");
return m_array[i].m3;
V * value_ptr = nullptr;
ASSERT(m_tree.try_get_value(key, value_ptr), "trying to read a nonexistent key in map");

return *value_ptr;
} }


template <typename E> template <typename E>
inline V & operator[] (E const &key) inline V & operator[] (E const &key)
{ {
/* Look for the hash in our table and return the value if found. */ /* Look for the hash in our table and return the value if found. */
uint32_t hashed = ((hash<K> const &)*this)(key);
ptrdiff_t i = FindIndex(key, hashed);
if (i >= 0)
return m_array[i].m3;

K typed_key(key);
V * value_ptr = nullptr;

if (!m_tree.try_get_value(typed_key, value_ptr))
{
V default_value = V();
m_tree.insert(typed_key, default_value);
}

ASSERT(m_tree.try_get_value(typed_key, value_ptr), "inner tree is messed up in map");


/* If not found, insert a new value. */ /* If not found, insert a new value. */
m_array.Push(hashed, key, V());
return m_array.Last().m3;
return *value_ptr;
} }


template <typename E> template <typename E>
inline void Remove(E const &key) inline void Remove(E const &key)
{ {
ptrdiff_t i = FindIndex(key);
if (i >= 0)
m_array.Remove(i);
K typed_key(key);
m_tree.erase(typed_key);
} }


template <typename E> template <typename E>
inline bool HasKey(E const &key) inline bool HasKey(E const &key)
{ {
return FindIndex(key) >= 0;
K typed_key(key);
return m_tree.exists(typed_key);
} }


template <typename E> template <typename E>
inline bool TryGetValue(E const &key, V& value) inline bool TryGetValue(E const &key, V& value)
{ {
ptrdiff_t i = FindIndex(key);
if (i >= 0)
K typed_key(key);
V * value_ptr;
if (m_tree.try_get_value(typed_key, value_ptr))
{ {
value = m_array[i].m3;
value = *value_ptr;
return true; return true;
} }


@@ -84,40 +93,26 @@ public:
array<K> Keys() const array<K> Keys() const
{ {
array<K> ret; array<K> ret;
for (auto it : m_array)
ret.Push(it.m2);

for (auto iterator : m_tree)
ret.Push(iterator.key);

return ret; return ret;
} }


inline ptrdiff_t Count() const inline ptrdiff_t Count() const
{ {
return m_array.Count();
return m_tree.get_count();
} }


inline void Empty() inline void Empty()
{ {
m_array.Empty();
m_tree.clear();
} }


private: private:
template <typename E>
inline ptrdiff_t FindIndex(E const &key, uint32_t hashed)
{
for (ptrdiff_t i = 0; i < m_array.Count(); ++i)
if (m_array[i].m1 == hashed)
if (m_array[i].m2 == key)
return i;
return -1;
}

template <typename E>
inline ptrdiff_t FindIndex(E const &key)
{
uint32_t hashed = ((hash<K> const &)*this)(key);
return FindIndex(key, hashed);
}


array<uint32_t, K, V> m_array;
avl_tree<K, V> m_tree;
}; };


} /* namespace lol */ } /* namespace lol */


+ 3
- 9
src/lol/base/string.h View File

@@ -276,16 +276,10 @@ public:
return !(*this == sz); return !(*this == sz);
} }


inline bool operator <(String const & that)
inline bool operator <(String const & s) const
{ {
auto it_this = begin(*this);
auto it_that = begin(that);

for ( ; it_this != end(*this) && it_that != end(that) ; ++it_this, ++it_that)
if (*it_this < *it_that)
return true;

return (!(it_this != end(*this)) && (it_that != end(that)));
using namespace std;
return memcmp(C(), s.C(), Count()) < 0;
} }


#ifdef __GNUC__ #ifdef __GNUC__


Loading…
Cancel
Save