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
- Repository
- rL LLVM
Event Timeline
| include/llvm/ADT/StringMap.h | ||
|---|---|---|
| 248 ↗ | (On Diff #51755) | May be explicit? | 
| 261 ↗ | (On Diff #51755) | I wonder if we really want to keep the tombstones or if it wouldn't be better to reinsert the elements? | 
| 272 ↗ | (On Diff #51755) | The hashes have to be inserted as well I think (after the buckets), I may miss where it happened? | 
| include/llvm/ADT/StringMap.h | ||
|---|---|---|
| 248 ↗ | (On Diff #51755) | I don't think that I can -- I need the copy-initialization support for: CustomNameFuncs = TLI.CustomNameFuncs; in D18513. | 
| 261 ↗ | (On Diff #51755) | I don't have a good feeling for this; it seems like this could mean one of two things: 
 What do you prefer? | 
| 272 ↗ | (On Diff #51755) | Yes; that's what the HashTable[I] = RHSHashTable[I]; does. | 
| include/llvm/ADT/StringMap.h | ||
|---|---|---|
| 261 ↗ | (On Diff #51755) | 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 ↗ | (On Diff #51755) | Obviously... | 
| include/llvm/ADT/StringMap.h | ||
|---|---|---|
| 261 ↗ | (On Diff #51755) | 
 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 ↗ | (On Diff #51755) | 
 That sounds a good argument to me! | 
| include/llvm/ADT/StringMap.h | ||
|---|---|---|
| 248 ↗ | (On Diff #51755) | 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 ↗ | (On Diff #51755) | 
 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 ↗ | (On Diff #51755) | private -> public is a bit rough, could it be protected maybe? | 
| include/llvm/ADT/StringMap.h | ||
|---|---|---|
| 94 ↗ | (On Diff #51755) | 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 ↗ | (On Diff #51755) | OK nevermind then... |