Browse Source

Did a small "Revert-but-not-really" on map+avl_tree

Added an unit-test that breaks map+avl_tree
undefined
Benjamin ‘Touky’ Huet Sam Hocevar <sam@hocevar.net> 10 years ago
parent
commit
fc84a65063
2 changed files with 228 additions and 0 deletions
  1. +101
    -0
      src/lol/base/map.h
  2. +127
    -0
      src/t/base/map.cpp

+ 101
- 0
src/lol/base/map.h View File

@@ -22,6 +22,7 @@
namespace lol
{

#if USING_AVL
/* A stupidly linear map for now. */
template<typename K, typename V> class map : protected hash<K>
{
@@ -114,6 +115,106 @@ private:

avl_tree<K, V> m_tree;
};
#else
/* A stupidly linear map for now. */
template<typename K, typename V> class map : protected hash<K>
{
public:
/* If E is different from K, hash<K> must implement operator()(E const&)
* and an equality operator between K and E must exist in order to use
* this method. */

/* I choose to make this inline because passing the key by reference
* is usually suboptimal. */
template <typename E>
inline V const& operator[] (E const &key) const
{
/* 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;
}

template <typename E>
inline V & operator[] (E const &key)
{
/* 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;

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

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

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

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

return false;
}

array<K> Keys() const
{
array<K> ret;
for (auto it : m_array)
ret.Push(it.m2);
return ret;
}

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

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

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;
};
#endif //USING_AVL

} /* namespace lol */


+ 127
- 0
src/t/base/map.cpp View File

@@ -70,6 +70,133 @@ lolunit_declare_fixture(MapTest)
lolunit_assert_equal(42, foo);
lolunit_assert_equal(12, bar);
lolunit_assert_equal(2, baz);

//Big stress test
array<String> bones = { "RootNode",
"Cyberano_Ns:Root_$AssimpFbx$_Translation",
"Cyberano_Ns:Box004_$AssimpFbx$_PreRotation",
"Cyberano_Ns:Root_$AssimpFbx$_PreRotation",
"Cyberano_Ns:Box004",
"Cyberano_Ns:Root_$AssimpFbx$_Rotation",
"Cyberano_Ns:Root",
"Cyberano_Ns:Hips",
"Cyberano_Ns:Spine",
"Cyberano_Ns:RightUpLeg",
"Cyberano_Ns:LeftUpLeg",
"Cyberano_Ns:BeltSheath1",
"Cyberano_Ns:RightCoat",
"Cyberano_Ns:LeftCoat",
"Cyberano_Ns:Spine1",
"Cyberano_Ns:RightLeg",
"Cyberano_Ns:RightUpLegRoll",
"Cyberano_Ns:LeftUpLegRoll",
"Cyberano_Ns:LeftLeg",
"Cyberano_Ns:Sheath",
"Cyberano_Ns:BeltSheath2",
"Cyberano_Ns:BeltSheath3",
"Cyberano_Ns:Spine2",
"Cyberano_Ns:FrontBelt1",
"Cyberano_Ns:BackBelt1",
"Cyberano_Ns:RightFoot",
"Cyberano_Ns:RightLegRoll",
"Cyberano_Ns:LeftLegRoll",
"Cyberano_Ns:LeftFoot",
"Cyberano_Ns:Sword",
"Cyberano_Ns:Neck",
"Cyberano_Ns:RightShoulder",
"Cyberano_Ns:LeftShoulder",
"Cyberano_Ns:Cloth",
"Cyberano_Ns:FrontBelt2",
"Cyberano_Ns:RightToeBase",
"Cyberano_Ns:LeftToeBase",
"Cyberano_Ns:Head",
"Cyberano_Ns:RightArm",
"Cyberano_Ns:RightSpaulder1",
"Cyberano_Ns:RightSpaulder2",
"Cyberano_Ns:LeftArm",
"Cyberano_Ns:LeftSpaulder1",
"Cyberano_Ns:LeftCloth01",
"Cyberano_Ns:MiddleCloth01",
"Cyberano_Ns:RightCloth01",
"Cyberano_Ns:FrontBelt3",
"Cyberano_Ns:RightoeEnd",
"Cyberano_Ns:LeftoeEnd",
"Cyberano_Ns:HeadEnd",
"Cyberano_Ns:Cap",
"Cyberano_Ns:RightForeArm",
"Cyberano_Ns:RightArmRoll",
"Cyberano_Ns:LeftForeArm",
"Cyberano_Ns:LeftArmRoll",
"Cyberano_Ns:LeftCloth02",
"Cyberano_Ns:MiddleCloth02",
"Cyberano_Ns:RightCloth02",
"Cyberano_Ns:Feather01",
"Cyberano_Ns:RightHand",
"Cyberano_Ns:RightForeArmRoll",
"Cyberano_Ns:LeftHand",
"Cyberano_Ns:LeftForeArmRoll",
"Cyberano_Ns:LeftCloth03",
"Cyberano_Ns:MiddleCloth03",
"Cyberano_Ns:RightCloth03",
"Cyberano_Ns:Feather02",
"Cyberano_Ns:RightThumb1",
"Cyberano_Ns:RightIndex1",
"Cyberano_Ns:RightMiddle1",
"Cyberano_Ns:RightRing1",
"Cyberano_Ns:RightCuff",
"Cyberano_Ns:LeftThumb1",
"Cyberano_Ns:LeftIndex1",
"Cyberano_Ns:LeftMiddle1",
"Cyberano_Ns:LeftRing1",
"Cyberano_Ns:LeftCloth04",
"Cyberano_Ns:MiddleCloth04",
"Cyberano_Ns:RightCloth04",
"Cyberano_Ns:Feather03",
"Cyberano_Ns:RightThumb2",
"Cyberano_Ns:RightIndex2",
"Cyberano_Ns:RightMiddle2",
"Cyberano_Ns:RightRing2",
"Cyberano_Ns:LeftThumb2",
"Cyberano_Ns:LeftIndex2",
"Cyberano_Ns:LeftMiddle2",
"Cyberano_Ns:LeftRing2",
"Cyberano_Ns:Feather04",
"Cyberano_Ns:RightThumb3",
"Cyberano_Ns:RightIndex3",
"Cyberano_Ns:RightMiddle3",
"Cyberano_Ns:RightRing3",
"Cyberano_Ns:LeftThumb3",
"Cyberano_Ns:LeftIndex3",
"Cyberano_Ns:LeftMiddle3",
"Cyberano_Ns:LeftRing3",
"Cyberano_Ns:Feather05",
"Cyberano_Ns:RightThumb4",
"Cyberano_Ns:RightIndex4",
"Cyberano_Ns:RightMiddle4",
"Cyberano_Ns:RightRing4",
"Cyberano_Ns:LeftThumb4",
"Cyberano_Ns:LeftIndex4",
"Cyberano_Ns:LeftMiddle4",
"Cyberano_Ns:LeftRing4",
"Cyberano_Ns:Feather06",
"Cyberano_Ns:Feather07",
"Cyberano_Ns:Feather08",
"Cyberano_Ns:Feather09",
"Cyberano_Ns:Feather10",
"Cyberano_Ns:Feather11",
"Cyberano_Ns:Feather12",
"Cyberano_Ns:Feather13",
"Cyberano_Ns:Feather14",
"Cyberano_Ns:Feather15",
"Cyberano_Ns:Feather16",
"Cyberano_Ns:Feather17" };

map<String, int> bones_map;
for (int i = 0; i < bones.Count(); ++i)
bones_map[bones[i]] = i;

for (int i = 0; i < bones.Count(); ++i)
lolunit_assert_equal(bones_map[bones[i]], i);
}
};



Loading…
Cancel
Save