[webkit-dev] New hash template structure API design proposal
Maciej Stachowiak
mjs at apple.com
Sat Jun 25 23:06:57 PDT 2005
I've been planning for a while to make really good, high-performance
generic HashSet and HashMap templates for WebCore, to replace the mix
of QDict, QMap and hand-coded hashtables we have now.
Problems with the current situation are:
* QMap is too slow (algorithmically inefficient by design)
* The WebCore implementation of QDict is too slow, and non-portable
* QDict/QPtrDict is not nearly flexible enough
* Sprinkling the code with hand-coded hashtables sucks
* Even the forthcoming Qt 4.0 QHash will not cut it - it does not
allow making multiple hashtables keyed by the same type but with
different hash and equality functions (important for things like case
insensitive string tables, or having pointer hashes with some other
concept of equality than identity), and it seems likely to be
inefficient for pointer types.
Here's my suggested replacement API. I would use these HashSet and
HashMap templates for all situations in WebCore that require any kind
of set or dictionary data structure, except when other types are
required for classes that are part of the kde khtml API.
I've already started on this and have a HashSet that vaguely
approximates this API.
One important point that is not clear just from the headers is that
these classes have shared value semantics with refcounting and no
copy-on-write.
// The defaultHash and defaultEqual template functions. would be
specialized for all the interesting types.
template<typename _Key, unsigned _Hash(const _Key&) = defaultHash,
bool _Equal(const _Key&, const _Key&) = defaultEqual>
class HashSet {
public:
typedef typename _Key KeyType;
// all the obvious iterator operations, ++, --, *, ->, etc; all
iterators are const since it would
// almost certainly break the hashtable to replace a key in place
class Iterator;
HashSet();
int size() const;
bool isEmpty() const;
Iterator begin() const;
Iterator end() const;
// If an item equal to "key" is already present in the table, it
is left in and not replaced
Iterator insert(const KeyType& key);
// a special version of insert() that finds the object by
hashing and comparing with some other type,
// to avoid the cost of type conversion if the object is already
in the table - useful for making efficient
// unique object factories
template<typename T, unsigned HashT(const T&), bool EqualT(const
KeyType&, const T&), KeyType ConvertT(const T&, unsigned)> Iterator
insert(const T& key);
Iterator find(const KeyType& key) const;
bool contains(const KeyType& key) const;
void remove(const KeyType& key);
void clear();
}
template<typename _Key, typename _Value, unsigned _Hash(const _Key&)
= defaultHash, bool _Equal(const _Key&, const _Key&) = defaultEqual>
class HashMap {
public:
typedef typename _Key KeyType;
typedef typename _Value ValueType;
// ?? should it iterate keys, values, key/value pairs? The last
would be good but then we'd have to define
// a pair type (or bite the bullet and use std::pair)
class Iterator;
HashMap();
int size() const;
bool isEmpty() const;
Iterator begin() const;
Iterator end() const;
// If an item equal to "key" is already present in the table, it
is left in and not replaced
Iterator insert(const KeyType &key, const ValueType &value);
// ?? is the template version of insert ever needed for a map as
opposed to a set?
const ValueType& operator[](const KeyType&) const;
Iterator find(const KeyType&) const;
void remove(const KeyType&);
void clear();
}
More information about the webkit-dev
mailing list