[llvm] r211309 - Add StringMap::insert(pair) consistent with the standard associative container concept.
Rafael Espíndola
rafael.espindola at gmail.com
Thu Jun 19 17:37:03 PDT 2014
Looks like this broke the build with gcc 4.7 in some bots and I reverted it.
On 19 June 2014 16:08, David Blaikie <dblaikie at gmail.com> wrote:
> Author: dblaikie
> Date: Thu Jun 19 15:08:56 2014
> New Revision: 211309
>
> URL: http://llvm.org/viewvc/llvm-project?rev=211309&view=rev
> Log:
> Add StringMap::insert(pair) consistent with the standard associative container concept.
>
> Patch by Agustín Bergé.
>
> Modified:
> llvm/trunk/include/llvm/ADT/StringMap.h
> llvm/trunk/lib/Support/StringMap.cpp
> llvm/trunk/unittests/ADT/StringMapTest.cpp
>
> Modified: llvm/trunk/include/llvm/ADT/StringMap.h
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/StringMap.h?rev=211309&r1=211308&r2=211309&view=diff
> ==============================================================================
> --- llvm/trunk/include/llvm/ADT/StringMap.h (original)
> +++ llvm/trunk/include/llvm/ADT/StringMap.h Thu Jun 19 15:08:56 2014
> @@ -64,7 +64,7 @@ protected:
> }
>
> StringMapImpl(unsigned InitSize, unsigned ItemSize);
> - void RehashTable();
> + unsigned RehashTable(unsigned BucketNo = 0);
>
> /// LookupBucketFor - Look up the bucket that the specified string should end
> /// up in. If it already exists as a key in the map, the Item pointer for the
> @@ -323,6 +323,28 @@ public:
> return true;
> }
>
> + /// insert - Inserts the specified key/value pair into the map if the key
> + /// isn't already in the map. The bool component of the returned pair is true
> + /// if and only if the insertion takes place, and the iterator component of
> + /// the pair points to the element with key equivalent to the key of the pair.
> + std::pair<iterator, bool> insert(std::pair<StringRef, ValueTy> KV) {
> + unsigned BucketNo = LookupBucketFor(KV.first);
> + StringMapEntryBase *&Bucket = TheTable[BucketNo];
> + if (Bucket && Bucket != getTombstoneVal())
> + return std::make_pair(iterator(TheTable + BucketNo, false),
> + false); // Already exists in map.
> +
> + if (Bucket == getTombstoneVal())
> + --NumTombstones;
> + Bucket =
> + MapEntryTy::Create(KV.first, Allocator, std::move(KV.second));
> + ++NumItems;
> + assert(NumItems + NumTombstones <= NumBuckets);
> +
> + BucketNo = RehashTable(BucketNo);
> + return std::make_pair(iterator(TheTable + BucketNo, false), true);
> + }
> +
> // clear - Empties out the StringMap
> void clear() {
> if (empty()) return;
> @@ -346,24 +368,7 @@ public:
> /// return.
> template <typename InitTy>
> MapEntryTy &GetOrCreateValue(StringRef Key, InitTy Val) {
> - unsigned BucketNo = LookupBucketFor(Key);
> - StringMapEntryBase *&Bucket = TheTable[BucketNo];
> - if (Bucket && Bucket != getTombstoneVal())
> - return *static_cast<MapEntryTy*>(Bucket);
> -
> - MapEntryTy *NewItem = MapEntryTy::Create(Key, Allocator, std::move(Val));
> -
> - if (Bucket == getTombstoneVal())
> - --NumTombstones;
> - ++NumItems;
> - assert(NumItems + NumTombstones <= NumBuckets);
> -
> - // Fill in the bucket for the hash table. The FullHashValue was already
> - // filled in by LookupBucketFor.
> - Bucket = NewItem;
> -
> - RehashTable();
> - return *NewItem;
> + return *insert(std::make_pair(Key, std::move(Val))).first;
> }
>
> MapEntryTy &GetOrCreateValue(StringRef Key) {
>
> Modified: llvm/trunk/lib/Support/StringMap.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/StringMap.cpp?rev=211309&r1=211308&r2=211309&view=diff
> ==============================================================================
> --- llvm/trunk/lib/Support/StringMap.cpp (original)
> +++ llvm/trunk/lib/Support/StringMap.cpp Thu Jun 19 15:08:56 2014
> @@ -181,7 +181,7 @@ StringMapEntryBase *StringMapImpl::Remov
>
> /// RehashTable - Grow the table, redistributing values into the buckets with
> /// the appropriate mod-of-hashtable-size.
> -void StringMapImpl::RehashTable() {
> +unsigned StringMapImpl::RehashTable(unsigned BucketNo) {
> unsigned NewSize;
> unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1);
>
> @@ -193,9 +193,10 @@ void StringMapImpl::RehashTable() {
> } else if (NumBuckets-(NumItems+NumTombstones) <= NumBuckets/8) {
> NewSize = NumBuckets;
> } else {
> - return;
> + return BucketNo;
> }
>
> + unsigned NewBucketNo = BucketNo;
> // Allocate one extra bucket which will always be non-empty. This allows the
> // iterators to stop at end.
> StringMapEntryBase **NewTableArray =
> @@ -215,6 +216,8 @@ void StringMapImpl::RehashTable() {
> if (!NewTableArray[NewBucket]) {
> NewTableArray[FullHash & (NewSize-1)] = Bucket;
> NewHashArray[FullHash & (NewSize-1)] = FullHash;
> + if (I == BucketNo)
> + NewBucketNo = NewBucket;
> continue;
> }
>
> @@ -227,6 +230,8 @@ void StringMapImpl::RehashTable() {
> // Finally found a slot. Fill it in.
> NewTableArray[NewBucket] = Bucket;
> NewHashArray[NewBucket] = FullHash;
> + if (I == BucketNo)
> + NewBucketNo = NewBucket;
> }
> }
>
> @@ -235,4 +240,5 @@ void StringMapImpl::RehashTable() {
> TheTable = NewTableArray;
> NumBuckets = NewSize;
> NumTombstones = 0;
> + return NewBucketNo;
> }
>
> Modified: llvm/trunk/unittests/ADT/StringMapTest.cpp
> URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/unittests/ADT/StringMapTest.cpp?rev=211309&r1=211308&r2=211309&view=diff
> ==============================================================================
> --- llvm/trunk/unittests/ADT/StringMapTest.cpp (original)
> +++ llvm/trunk/unittests/ADT/StringMapTest.cpp Thu Jun 19 15:08:56 2014
> @@ -10,6 +10,7 @@
> #include "gtest/gtest.h"
> #include "llvm/ADT/StringMap.h"
> #include "llvm/Support/DataTypes.h"
> +#include <tuple>
> using namespace llvm;
>
> namespace {
> @@ -203,6 +204,43 @@ TEST_F(StringMapTest, InsertTest) {
> assertSingleItemMap();
> }
>
> +// Test insert(pair<K, V>) method
> +TEST_F(StringMapTest, InsertPairTest) {
> + bool Inserted;
> + StringMap<uint32_t>::iterator NewIt;
> + std::tie(NewIt, Inserted) =
> + testMap.insert(std::make_pair(testKeyFirst, testValue));
> + EXPECT_EQ(1u, testMap.size());
> + EXPECT_EQ(testValue, testMap[testKeyFirst]);
> + EXPECT_EQ(testKeyFirst, NewIt->first());
> + EXPECT_EQ(testValue, NewIt->second);
> + EXPECT_TRUE(Inserted);
> +
> + StringMap<uint32_t>::iterator ExistingIt;
> + std::tie(ExistingIt, Inserted) =
> + testMap.insert(std::make_pair(testKeyFirst, testValue + 1));
> + EXPECT_EQ(1u, testMap.size());
> + EXPECT_EQ(testValue, testMap[testKeyFirst]);
> + EXPECT_FALSE(Inserted);
> + EXPECT_EQ(NewIt, ExistingIt);
> +}
> +
> +// Test insert(pair<K, V>) method when rehashing occurs
> +TEST_F(StringMapTest, InsertRehashingPairTest) {
> + // Check that the correct iterator is returned when the inserted element is
> + // moved to a different bucket during internal rehashing. This depends on
> + // the particular key, and the implementation of StringMap and HashString.
> + // Changes to those might result in this test not actually checking that.
> + StringMap<uint32_t> t(1);
> + EXPECT_EQ(1u, t.getNumBuckets());
> +
> + StringMap<uint32_t>::iterator It =
> + t.insert(std::make_pair("abcdef", 42)).first;
> + EXPECT_EQ(2u, t.getNumBuckets());
> + EXPECT_EQ("abcdef", It->first());
> + EXPECT_EQ(42u, It->second);
> +}
> +
> // Create a non-default constructable value
> struct StringMapTestStruct {
> StringMapTestStruct(int i) : i(i) {}
>
>
> _______________________________________________
> llvm-commits mailing list
> llvm-commits at cs.uiuc.edu
> http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits
More information about the llvm-commits
mailing list