Skip to content

Commit

Permalink
PDB HashTable: Move TraitsT from class parameter to the methods that …
Browse files Browse the repository at this point in the history
…need it

The traits object is only used by a few methods. Deserializing a hash
table and walking it is possible without the traits object, so it
shouldn't be required to build a dummy object for that use case.

The TraitsT object used to be a function template parameter before
r327647, this restores it to that state.

This makes it clear that the traits object isn't needed at all in 1 of
the current 3 uses of HashTable (and I am going to add another use that
doesn't need it), and that the default PdbHashTraits isn't used outside
of tests.

While here, also re-enable 3 checks in the test that were commented out
(which requires making HashTableInternals templated and giving FooBar
an operator==).

No intended behavior change.

Differential Revision: https://reviews.llvm.org/D64640

llvm-svn: 365974
  • Loading branch information
nico committed Jul 12, 2019
1 parent 882fdf6 commit 51a52b5
Show file tree
Hide file tree
Showing 6 changed files with 102 additions and 96 deletions.
63 changes: 29 additions & 34 deletions llvm/include/llvm/DebugInfo/PDB/Native/HashTable.h
Expand Up @@ -31,21 +31,21 @@ namespace pdb {
Error readSparseBitVector(BinaryStreamReader &Stream, SparseBitVector<> &V);
Error writeSparseBitVector(BinaryStreamWriter &Writer, SparseBitVector<> &Vec);

template <typename ValueT, typename TraitsT> class HashTable;
template <typename ValueT> class HashTable;

template <typename ValueT, typename TraitsT>
template <typename ValueT>
class HashTableIterator
: public iterator_facade_base<HashTableIterator<ValueT, TraitsT>,
: public iterator_facade_base<HashTableIterator<ValueT>,
std::forward_iterator_tag,
std::pair<uint32_t, ValueT>> {
friend HashTable<ValueT, TraitsT>;
friend HashTable<ValueT>;

HashTableIterator(const HashTable<ValueT, TraitsT> &Map, uint32_t Index,
HashTableIterator(const HashTable<ValueT> &Map, uint32_t Index,
bool IsEnd)
: Map(&Map), Index(Index), IsEnd(IsEnd) {}

public:
HashTableIterator(const HashTable<ValueT, TraitsT> &Map) : Map(&Map) {
HashTableIterator(const HashTable<ValueT> &Map) : Map(&Map) {
int I = Map.Present.find_first();
if (I == -1) {
Index = 0;
Expand Down Expand Up @@ -87,22 +87,14 @@ class HashTableIterator
bool isEnd() const { return IsEnd; }
uint32_t index() const { return Index; }

const HashTable<ValueT, TraitsT> *Map;
const HashTable<ValueT> *Map;
uint32_t Index;
bool IsEnd;
};

template <typename T> struct PdbHashTraits {};

template <> struct PdbHashTraits<uint32_t> {
uint32_t hashLookupKey(uint32_t N) const { return N; }
uint32_t storageKeyToLookupKey(uint32_t N) const { return N; }
uint32_t lookupKeyToStorageKey(uint32_t N) { return N; }
};

template <typename ValueT, typename TraitsT = PdbHashTraits<ValueT>>
template <typename ValueT>
class HashTable {
using iterator = HashTableIterator<ValueT, TraitsT>;
using iterator = HashTableIterator<ValueT>;
friend iterator;

struct Header {
Expand All @@ -114,9 +106,7 @@ class HashTable {

public:
HashTable() { Buckets.resize(8); }

explicit HashTable(TraitsT Traits) : HashTable(8, std::move(Traits)) {}
HashTable(uint32_t Capacity, TraitsT Traits) : Traits(Traits) {
explicit HashTable(uint32_t Capacity) {
Buckets.resize(Capacity);
}

Expand Down Expand Up @@ -221,7 +211,8 @@ class HashTable {

/// Find the entry whose key has the specified hash value, using the specified
/// traits defining hash function and equality.
template <typename Key> iterator find_as(const Key &K) const {
template <typename Key, typename TraitsT>
iterator find_as(const Key &K, TraitsT &Traits) const {
uint32_t H = Traits.hashLookupKey(K) % capacity();
uint32_t I = H;
Optional<uint32_t> FirstUnused;
Expand Down Expand Up @@ -252,12 +243,14 @@ class HashTable {

/// Set the entry using a key type that the specified Traits can convert
/// from a real key to an internal key.
template <typename Key> bool set_as(const Key &K, ValueT V) {
return set_as_internal(K, std::move(V), None);
template <typename Key, typename TraitsT>
bool set_as(const Key &K, ValueT V, TraitsT &Traits) {
return set_as_internal(K, std::move(V), Traits, None);
}

template <typename Key> ValueT get(const Key &K) const {
auto Iter = find_as(K);
template <typename Key, typename TraitsT>
ValueT get(const Key &K, TraitsT &Traits) const {
auto Iter = find_as(K, Traits);
assert(Iter != end());
return (*Iter).second;
}
Expand All @@ -266,17 +259,17 @@ class HashTable {
bool isPresent(uint32_t K) const { return Present.test(K); }
bool isDeleted(uint32_t K) const { return Deleted.test(K); }

TraitsT Traits;
BucketList Buckets;
mutable SparseBitVector<> Present;
mutable SparseBitVector<> Deleted;

private:
/// Set the entry using a key type that the specified Traits can convert
/// from a real key to an internal key.
template <typename Key>
bool set_as_internal(const Key &K, ValueT V, Optional<uint32_t> InternalKey) {
auto Entry = find_as(K);
template <typename Key, typename TraitsT>
bool set_as_internal(const Key &K, ValueT V, TraitsT &Traits,
Optional<uint32_t> InternalKey) {
auto Entry = find_as(K, Traits);
if (Entry != end()) {
assert(isPresent(Entry.index()));
assert(Traits.storageKeyToLookupKey(Buckets[Entry.index()].first) == K);
Expand All @@ -293,15 +286,16 @@ class HashTable {
Present.set(Entry.index());
Deleted.reset(Entry.index());

grow();
grow(Traits);

assert((find_as(K)) != end());
assert((find_as(K, Traits)) != end());
return true;
}

static uint32_t maxLoad(uint32_t capacity) { return capacity * 2 / 3 + 1; }

void grow() {
template <typename TraitsT>
void grow(TraitsT &Traits) {
uint32_t S = size();
uint32_t MaxLoad = maxLoad(capacity());
if (S < maxLoad(capacity()))
Expand All @@ -313,10 +307,11 @@ class HashTable {
// Growing requires rebuilding the table and re-hashing every item. Make a
// copy with a larger capacity, insert everything into the copy, then swap
// it in.
HashTable NewMap(NewCapacity, Traits);
HashTable NewMap(NewCapacity);
for (auto I : Present) {
auto LookupKey = Traits.storageKeyToLookupKey(Buckets[I].first);
NewMap.set_as_internal(LookupKey, Buckets[I].second, Buckets[I].first);
NewMap.set_as_internal(LookupKey, Buckets[I].second, Traits,
Buckets[I].first);
}

Buckets.swap(NewMap.Buckets);
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/PDB/Native/NamedStreamMap.h
Expand Up @@ -59,7 +59,7 @@ class NamedStreamMap {
NamedStreamMapTraits HashTraits;
/// Closed hash table from Offset -> StreamNumber, where Offset is the offset
/// of the stream name in NamesBuffer.
HashTable<support::ulittle32_t, NamedStreamMapTraits> OffsetIndexMap;
HashTable<support::ulittle32_t> OffsetIndexMap;

/// Buffer of string data.
std::vector<char> NamesBuffer;
Expand Down
2 changes: 1 addition & 1 deletion llvm/include/llvm/DebugInfo/PDB/Native/PDBFileBuilder.h
Expand Up @@ -97,7 +97,7 @@ class PDBFileBuilder {

PDBStringTableBuilder Strings;
StringTableHashTraits InjectedSourceHashTraits;
HashTable<SrcHeaderBlockEntry, StringTableHashTraits> InjectedSourceTable;
HashTable<SrcHeaderBlockEntry> InjectedSourceTable;

SmallVector<InjectedSourceDescriptor, 2> InjectedSources;

Expand Down
7 changes: 3 additions & 4 deletions llvm/lib/DebugInfo/PDB/Native/NamedStreamMap.cpp
Expand Up @@ -46,8 +46,7 @@ uint32_t NamedStreamMapTraits::lookupKeyToStorageKey(StringRef S) {
return NS->appendStringData(S);
}

NamedStreamMap::NamedStreamMap()
: HashTraits(*this), OffsetIndexMap(1, HashTraits) {}
NamedStreamMap::NamedStreamMap() : HashTraits(*this), OffsetIndexMap(1) {}

Error NamedStreamMap::load(BinaryStreamReader &Stream) {
uint32_t StringBufferSize;
Expand Down Expand Up @@ -99,7 +98,7 @@ uint32_t NamedStreamMap::hashString(uint32_t Offset) const {
}

bool NamedStreamMap::get(StringRef Stream, uint32_t &StreamNo) const {
auto Iter = OffsetIndexMap.find_as(Stream);
auto Iter = OffsetIndexMap.find_as(Stream, HashTraits);
if (Iter == OffsetIndexMap.end())
return false;
StreamNo = (*Iter).second;
Expand All @@ -123,5 +122,5 @@ uint32_t NamedStreamMap::appendStringData(StringRef S) {
}

void NamedStreamMap::set(StringRef Stream, uint32_t StreamNo) {
OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo));
OffsetIndexMap.set_as(Stream, support::ulittle32_t(StreamNo), HashTraits);
}
5 changes: 3 additions & 2 deletions llvm/lib/DebugInfo/PDB/Native/PDBFileBuilder.cpp
Expand Up @@ -34,7 +34,7 @@ using namespace llvm::support;

PDBFileBuilder::PDBFileBuilder(BumpPtrAllocator &Allocator)
: Allocator(Allocator), InjectedSourceHashTraits(Strings),
InjectedSourceTable(2, InjectedSourceHashTraits) {}
InjectedSourceTable(2) {}

PDBFileBuilder::~PDBFileBuilder() {}

Expand Down Expand Up @@ -189,7 +189,8 @@ Error PDBFileBuilder::finalizeMsfLayout() {
static_cast<uint32_t>(PdbRaw_SrcHeaderBlockVer::SrcVerOne);
Entry.CRC = CRC.getCRC();
StringRef VName = getStringTableBuilder().getStringForId(IS.VNameIndex);
InjectedSourceTable.set_as(VName, std::move(Entry));
InjectedSourceTable.set_as(VName, std::move(Entry),
InjectedSourceHashTraits);
}

uint32_t SrcHeaderBlockSize =
Expand Down

0 comments on commit 51a52b5

Please sign in to comment.