[PATCH] D18506: Add a copy constructor to StringMap
Hal Finkel via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 30 13:00:24 PDT 2016
This revision was automatically updated to reflect the committed changes.
Closed by commit rL264906: Add a copy constructor to StringMap (authored by hfinkel).
Changed prior to commit:
http://reviews.llvm.org/D18506?vs=51755&id=52108#toc
Repository:
rL LLVM
http://reviews.llvm.org/D18506
Files:
llvm/trunk/include/llvm/ADT/StringMap.h
llvm/trunk/unittests/ADT/StringMapTest.cpp
Index: llvm/trunk/unittests/ADT/StringMapTest.cpp
===================================================================
--- llvm/trunk/unittests/ADT/StringMapTest.cpp
+++ llvm/trunk/unittests/ADT/StringMapTest.cpp
@@ -157,6 +157,33 @@
EXPECT_EQ(5, Map.lookup("funf"));
}
+TEST_F(StringMapTest, CopyCtorTest) {
+ llvm::StringMap<int> Map;
+
+ Map["eins"] = 1;
+ Map["zwei"] = 2;
+ Map["drei"] = 3;
+ Map.erase("drei");
+ Map.erase("eins");
+ Map["veir"] = 4;
+ Map["funf"] = 5;
+
+ EXPECT_EQ(3u, Map.size());
+ EXPECT_EQ(0, Map.lookup("eins"));
+ EXPECT_EQ(2, Map.lookup("zwei"));
+ EXPECT_EQ(0, Map.lookup("drei"));
+ EXPECT_EQ(4, Map.lookup("veir"));
+ EXPECT_EQ(5, Map.lookup("funf"));
+
+ llvm::StringMap<int> Map2(Map);
+ EXPECT_EQ(3u, Map2.size());
+ EXPECT_EQ(0, Map2.lookup("eins"));
+ EXPECT_EQ(2, Map2.lookup("zwei"));
+ EXPECT_EQ(0, Map2.lookup("drei"));
+ EXPECT_EQ(4, Map2.lookup("veir"));
+ EXPECT_EQ(5, Map2.lookup("funf"));
+}
+
// A more complex iteration test.
TEST_F(StringMapTest, IterationTest) {
bool visited[100];
Index: llvm/trunk/include/llvm/ADT/StringMap.h
===================================================================
--- llvm/trunk/include/llvm/ADT/StringMap.h
+++ llvm/trunk/include/llvm/ADT/StringMap.h
@@ -89,7 +89,8 @@
/// table, returning it. If the key is not in the table, this returns null.
StringMapEntryBase *RemoveKey(StringRef Key);
-private:
+ /// Allocate the table with the specified number of buckets and otherwise
+ /// setup the map as empty.
void init(unsigned Size);
public:
@@ -244,7 +245,39 @@
return *this;
}
- // FIXME: Implement copy operations if/when they're needed.
+ StringMap(const StringMap &RHS) :
+ StringMapImpl(static_cast<unsigned>(sizeof(MapEntryTy))),
+ Allocator(RHS.Allocator) {
+ if (RHS.empty())
+ return;
+
+ // Allocate TheTable of the same size as RHS's TheTable, and set the
+ // sentinel appropriately (and NumBuckets).
+ init(RHS.NumBuckets);
+ unsigned *HashTable = (unsigned *)(TheTable + NumBuckets + 1),
+ *RHSHashTable = (unsigned *)(RHS.TheTable + NumBuckets + 1);
+
+ NumItems = RHS.NumItems;
+ NumTombstones = RHS.NumTombstones;
+ for (unsigned I = 0, E = NumBuckets; I != E; ++I) {
+ MapEntryTy *Bucket = ((MapEntryTy**) RHS.TheTable)[I];
+ if (!Bucket || Bucket == getTombstoneVal()) {
+ TheTable[I] = Bucket;
+ continue;
+ }
+
+ TheTable[I] = MapEntryTy::Create(Bucket->getKey(), Allocator,
+ Bucket->getValue());
+ HashTable[I] = RHSHashTable[I];
+ }
+
+ // Note that here we've copied everything from the RHS into this object,
+ // tombstones included. We could, instead, have re-probed for each key to
+ // instantiate this new object without any tombstone buckets. The
+ // assumption here is that items are rarely deleted from most StringMaps,
+ // and so tombstones are rare, so the cost of re-probing for all inputs is
+ // not worthwhile.
+ }
AllocatorTy &getAllocator() { return Allocator; }
const AllocatorTy &getAllocator() const { return Allocator; }
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D18506.52108.patch
Type: text/x-patch
Size: 3169 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20160330/1125ce24/attachment.bin>
More information about the llvm-commits
mailing list