I will soon propose a patch that will require that StringMap have a copy constructor (which it does not currently support). This adds one.
Details
Diff Detail
Event Timeline
include/llvm/ADT/StringMap.h | ||
---|---|---|
248 | I don't think that I can -- I need the copy-initialization support for: CustomNameFuncs = TLI.CustomNameFuncs; in D18513. | |
261 | I don't have a good feeling for this; it seems like this could mean one of two things:
What do you prefer? | |
272 | Yes; that's what the HashTable[I] = RHSHashTable[I]; does. |
include/llvm/ADT/StringMap.h | ||
---|---|---|
261 | It seems to me that when looking for an entry in the map, the search stops when it find an empty slot, but continue when there is a tombstone. If I understand your 1), it is just replacing tombstones with empty buckets, but that would break the search for existing entries that are after the tombstones. The 2) is basically what I was thinking of, eventually allocating the same number of buckets, but indeed reinserting each entry (reusing the existing known hash). Not that I have a strong preference, I was rather wondering if you considered this and what is the rational for one or the other (and if there is a reason, I'd rather have it documented in the code for future reference). | |
272 | Obviously... |
include/llvm/ADT/StringMap.h | ||
---|---|---|
261 |
I believe you're correct; scratch that option.
My thought was the following: Most StringMaps don't have many tombstones, because many use cases don't ever (or only rarely) delete things from their string maps. As a result, just copying the structure as-is (any tombstones included) will be faster than re-probing for all keys with little downside.
|
include/llvm/ADT/StringMap.h | ||
---|---|---|
261 |
That sounds a good argument to me! |
include/llvm/ADT/StringMap.h | ||
---|---|---|
248 | The issue is only because the copy assignment operator is defined as: StringMap &operator=(StringMap RHS) { StringMapImpl::swap(RHS); std::swap(Allocator, RHS.Allocator); return *this; } I think we could change it to: StringMap &operator=(const StringMap &RHS) { StringMap Tmp(RHS); StringMapImpl::swap(Tmp); std::swap(Allocator, Tmp.Allocator); return *this; } StringMap &operator=(const StringMap &&RHS) { std::swap(Allocator, std::move(RHS.Allocator)); StringMapImpl::swap(std::move(RHS)); return *this; } Now the only thing that it buys us is a protection against unexpected/unintended copy construction for a StringMap, is it compelling enough? |
include/llvm/ADT/StringMap.h | ||
---|---|---|
248 |
Personally, I don't see a reason to be so careful about copying a StringMap, more careful, that is, than for other similar data structures. We have non-explicit copy constructors on DenseMap, etc. Everyone needs to be just as careful about copying those. As a user of containers, I tend to find such restrictions annoying. Obviously, people have different opinions on this topic ;) |
include/llvm/ADT/StringMap.h | ||
---|---|---|
94 | private -> public is a bit rough, could it be protected maybe? |
include/llvm/ADT/StringMap.h | ||
---|---|---|
94 | Yes, it is (all of the functions in this block are protected). |
Thanks for all the answers. LGTM then.
include/llvm/ADT/StringMap.h | ||
---|---|---|
94 | OK nevermind then... |
private -> public is a bit rough, could it be protected maybe?