Ver Fonte

add TryGetValue, Insert, EraseSwap, RemoveSwap

svifylabs há 9 anos atrás
pai
commit
b54b5b9ef7
2 ficheiros alterados com 130 adições e 0 exclusões
  1. 52 0
      Source/Urho3D/Container/HashMap.h
  2. 78 0
      Source/Urho3D/Container/Vector.h

+ 52 - 0
Source/Urho3D/Container/HashMap.h

@@ -385,6 +385,42 @@ public:
             InsertNode(*it++);
     }
 
+    /// Insert a key and value and return iterator to the value and if the value was already added.
+    Pair<Iterator, bool> Insert(const T& key, const U& value, bool findExisting = true)
+    {
+        // If no pointers yet, allocate with minimum bucket count
+        if (!ptrs_)
+        {
+            AllocateBuckets(Size(), MIN_BUCKETS);
+            Rehash();
+        }
+
+        unsigned hashKey = Hash(key);
+
+        if (findExisting)
+        {
+            // If exists, just change the value
+            Node* existing = FindNode(key, hashKey);
+            if (existing)
+            {
+                existing->pair_.second_ = value;
+                return  Pair<T, U>(Iterator(existing), true);
+            }
+        }
+
+        Node* newNode = InsertNode(Tail(), key, value);
+        newNode->down_ = Ptrs()[hashKey];
+        Ptrs()[hashKey] = newNode;
+
+        // Rehash if the maximum load factor has been exceeded
+        if (Size() > NumBuckets() * MAX_LOAD_FACTOR)
+        {
+            AllocateBuckets(Size(), NumBuckets() << 1);
+            Rehash();
+        }
+        return  Pair<T, U>(Iterator(newNode), false);
+    }
+
     /// Erase a pair by key. Return true if was found.
     bool Erase(const T& key)
     {
@@ -545,6 +581,22 @@ public:
         return FindNode(key, hashKey) != 0;
     }
 
+    /// Return true if key found.
+    bool TryGetValue(const T& key, U& out)
+    {
+        if (!ptrs_)
+            return false;
+        unsigned hashKey = Hash(key);
+        Node* node = FindNode(key, hashKey);
+        if (node)
+        {
+            out = node->pair_.second_;
+            return true;
+        }
+        else
+            return false;
+    }
+
     /// Return all the keys.
     Vector<T> Keys() const
     {

+ 78 - 0
Source/Urho3D/Container/Vector.h

@@ -300,6 +300,31 @@ public:
         Resize(size_ - length, 0);
     }
 
+    /// Erase a range of elements by swapping elements from the end of the array in order to reduce the amount of
+    /// data copied. The order of existing elements will be changed, if ordering needs to be retained use Erase!
+    void EraseSwap(unsigned pos, unsigned length = 1)
+    {
+        unsigned shiftStartIndex = pos + count;
+        // Return if the range is illegal
+        if (shiftStartIndex > size_ || !length)
+            return;
+
+        unsigned newSize = size_ - length;
+        unsigned trailingCount = size_ - shiftStartIndex;
+        if (trailingCount <= count)
+        {
+            // We're removing more elements from the array than exist past the end of the range being removed, so
+            // perform a normal shift and destroy.
+            MoveRange(pos, shiftStartIndex, trailingCount);
+        }
+        else
+        {
+            // Swap elements from the end of the array into the empty space.
+            CopyElements(Buffer() + pos, Buffer() + newSize, length);
+        }
+        Resize(newSize, 0);
+    }
+
     /// Erase an element by iterator. Return iterator to the next element.
     Iterator Erase(const Iterator& it)
     {
@@ -336,6 +361,20 @@ public:
             return false;
     }
 
+    /// Erase an element if found by swapping with the last element in order to reduce the amount of
+    /// data copied. The order of existing elements will be changed, if ordering needs to be retained use Remove!
+    bool RemoveSwap(const T& value)
+    {
+        Iterator i = Find(value);
+        if (i != End())
+        {
+            EraseSwap(i);
+            return true;
+        }
+        else
+            return false;
+    }
+
     /// Clear the vector.
     void Clear() { Resize(0); }
 
@@ -803,6 +842,31 @@ public:
         return Begin() + pos;
     }
 
+    /// Erase a range of elements by swapping elements from the end of the array in order to reduce the amount of
+    /// data copied. The order of existing elements will be changed, if ordering needs to be retained use Erase!
+    void EraseSwap(unsigned pos, unsigned length = 1)
+    {
+        unsigned shiftStartIndex = pos + count;
+        // Return if the range is illegal
+        if (shiftStartIndex > size_ || !length)
+            return;
+      
+        unsigned newSize = size_ - length;
+        unsigned trailingCount = size_ - shiftStartIndex;
+        if (trailingCount <= count)
+        {
+            // We're removing more elements from the array than exist past the end of the range being removed, so
+            // perform a normal shift and destroy.
+            MoveRange(pos, shiftStartIndex, trailingCount);
+        }
+        else
+        {
+            // Swap elements from the end of the array into the empty space.
+            CopyElements(Buffer() + pos, Buffer() + newSize, length);
+        }
+        Resize(newSize);
+    }
+
     /// Erase an element if found.
     bool Remove(const T& value)
     {
@@ -816,6 +880,20 @@ public:
             return false;
     }
 
+    /// Erase an element if found by swapping with the last element in order to reduce the amount of
+    /// data copied. The order of existing elements will be changed, if ordering needs to be retained use Remove!
+    bool RemoveSwap(const T& value)
+    {
+        Iterator i = Find(value);
+        if (i != End())
+        {
+            EraseSwap(i);
+            return true;
+        }
+        else
+            return false;
+    }
+
     /// Clear the vector.
     void Clear() { Resize(0); }