Is using the pointer value has hash value really useful?
It is perfect in the sense that these elements are supposed to be
unique, so if you insert an existing item, you get back the already
created item. But since you are using the pointer to the unique item as
hash, you cannot use it to lookup since the new (non-unique) item you
are trying to insert has to be constructed also, and doesn't have the
same pointer value (yet). So you will have to compare all items already
in the collector set before you can decide to return the unique item. Or
am I missing something?
I think what you are missing is the crucial level of indirection.
(Of course, always allow for the possibility that it's me who is
missing something crucial.)
I would have had expected that for anything that is created by
combining
elements would have a hash function based on the hash of the items
combined.
We do. See dwarf_output::debug_info_entry::set_hash:
inline void set_hash ()
{
_m_hash = _m_tag;
subr::hash_combine (_m_hash, *_m_attributes);
subr::hash_combine (_m_hash, *_m_children);
}
The hash value of debug_info_entry itself is that complex hash. That's
how you ever get to a "final" debug_info_entry pointer, an object living
in the collector. Remember, a debug_info_entry is just a three-word
object: tag, children pointer, and attributes pointer. So all that's
getting constructed to do the insertion is the copy of those three
words. That's the hash function for dwarf_output_collector::_m_unique.
The only places where we use that pointer as an integer hash are when
it's being combined as part of a larger object's hash. That is done in
computing the hash of a debug_info_entry::children_type and the hash of
a value::value_reference.
This is why _m_attributes and _m_children are pointers rather than
direct containers in the debug_info_entry. Each of those has its own
hash function and its own hash table in the collector (_m_attr_sets,
_m_broods). The children_type stores its own hash once computed, so
"taking the hash of *_m_children" above is really just extracting
_m_children->_m_hash. Likewise for attributes_types. So that hash
function above is just the two steps of hash_combine arithmetic.
Is that more clear now?
Thanks,
Roland