mirror of https://github.com/YosysHQ/yosys.git
docs: move hashing-based container details into internal docs from guidelines
This commit is contained in:
parent
1401906d81
commit
6d53454bf5
|
@ -1,8 +1,58 @@
|
||||||
Hashing and associative data structures in Yosys
|
Hashing and associative data structures in Yosys
|
||||||
------------------------------------------------
|
------------------------------------------------
|
||||||
|
|
||||||
Yosys heavily relies on custom data structures such as dict or pool defined in
|
Container classes based on hashing
|
||||||
kernel/hashlib.h. There are various reasons for this.
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Yosys uses ``dict<K, T>`` and ``pool<T>`` as main container classes.
|
||||||
|
``dict<K, T>`` is essentially a replacement for ``std::unordered_map<K, T>``
|
||||||
|
and ``pool<T>`` is a replacement for ``std::unordered_set<T>``.
|
||||||
|
The main characteristics are:
|
||||||
|
|
||||||
|
* ``dict<K, T>`` and ``pool<T>`` are about 2x faster than the std containers
|
||||||
|
(though this claim hasn't been verified for over 10 years)
|
||||||
|
|
||||||
|
* references to elements in a ``dict<K, T>`` or ``pool<T>`` are invalidated by
|
||||||
|
insert and remove operations (similar to ``std::vector<T>`` on ``push_back()``).
|
||||||
|
|
||||||
|
* some iterators are invalidated by ``erase()``. specifically, iterators
|
||||||
|
that have not passed the erased element yet are invalidated. (``erase()``
|
||||||
|
itself returns valid iterator to the next element.)
|
||||||
|
|
||||||
|
* no iterators are invalidated by ``insert()``. elements are inserted at
|
||||||
|
``begin()``. i.e. only a new iterator that starts at ``begin()`` will see the
|
||||||
|
inserted elements.
|
||||||
|
|
||||||
|
* the method ``.count(key, iterator)`` is like ``.count(key)`` but only
|
||||||
|
considers elements that can be reached via the iterator.
|
||||||
|
|
||||||
|
* iterators can be compared. ``it1 < it2`` means that the position of ``t2``
|
||||||
|
can be reached via ``t1`` but not vice versa.
|
||||||
|
|
||||||
|
* the method ``.sort()`` can be used to sort the elements in the container
|
||||||
|
the container stays sorted until elements are added or removed.
|
||||||
|
|
||||||
|
* ``dict<K, T>`` and ``pool<T>`` will have the same order of iteration across
|
||||||
|
all compilers, standard libraries and architectures.
|
||||||
|
|
||||||
|
In addition to ``dict<K, T>`` and ``pool<T>`` there is also an ``idict<K>`` that
|
||||||
|
creates a bijective map from ``K`` to the integers. For example:
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
idict<string, 42> si;
|
||||||
|
log("%d\n", si("hello")); // will print 42
|
||||||
|
log("%d\n", si("world")); // will print 43
|
||||||
|
log("%d\n", si.at("world")); // will print 43
|
||||||
|
log("%d\n", si.at("dummy")); // will throw exception
|
||||||
|
log("%s\n", si[42].c_str())); // will print hello
|
||||||
|
log("%s\n", si[43].c_str())); // will print world
|
||||||
|
log("%s\n", si[44].c_str())); // will throw exception
|
||||||
|
|
||||||
|
It is not possible to remove elements from an idict.
|
||||||
|
|
||||||
|
Finally ``mfp<K>`` implements a merge-find set data structure (aka. disjoint-set
|
||||||
|
or union-find) over the type ``K`` ("mfp" = merge-find-promote).
|
||||||
|
|
||||||
The hash function
|
The hash function
|
||||||
~~~~~~~~~~~~~~~~~
|
~~~~~~~~~~~~~~~~~
|
||||||
|
|
|
@ -37,57 +37,15 @@ And then executed using the following command:
|
||||||
Yosys Data Structures
|
Yosys Data Structures
|
||||||
---------------------
|
---------------------
|
||||||
|
|
||||||
Here is a short list of data structures that you should make yourself familiar
|
1. Container classes based on hashing
|
||||||
with before you write C++ code for Yosys. The following data structures are all
|
|
||||||
defined when "kernel/yosys.h" is included and USING_YOSYS_NAMESPACE is used.
|
|
||||||
|
|
||||||
1. Yosys Container Classes
|
Yosys heavily relies on custom container data structures such as dict or pool
|
||||||
|
defined in kernel/hashlib.h.
|
||||||
|
dict<K, T> is essentially a replacement for std::unordered_map<K, T>
|
||||||
|
and pool<T> is a replacement for std::unordered_set<T>. Please refer to
|
||||||
|
docs/source/yosys_internals/hashing.rst for more information on those.
|
||||||
|
|
||||||
Yosys uses dict<K, T> and pool<T> as main container classes. dict<K, T> is
|
Otherwise, Yosys makes use of the following:
|
||||||
essentially a replacement for std::unordered_map<K, T> and pool<T> is a
|
|
||||||
replacement for std::unordered_set<T>. The main characteristics are:
|
|
||||||
|
|
||||||
- dict<K, T> and pool<T> are about 2x faster than the std containers
|
|
||||||
|
|
||||||
- references to elements in a dict<K, T> or pool<T> are invalidated by
|
|
||||||
insert and remove operations (similar to std::vector<T> on push_back()).
|
|
||||||
|
|
||||||
- some iterators are invalidated by erase(). specifically, iterators
|
|
||||||
that have not passed the erased element yet are invalidated. (erase()
|
|
||||||
itself returns valid iterator to the next element.)
|
|
||||||
|
|
||||||
- no iterators are invalidated by insert(). elements are inserted at
|
|
||||||
begin(). i.e. only a new iterator that starts at begin() will see the
|
|
||||||
inserted elements.
|
|
||||||
|
|
||||||
- the method .count(key, iterator) is like .count(key) but only
|
|
||||||
considers elements that can be reached via the iterator.
|
|
||||||
|
|
||||||
- iterators can be compared. it1 < it2 means that the position of t2
|
|
||||||
can be reached via t1 but not vice versa.
|
|
||||||
|
|
||||||
- the method .sort() can be used to sort the elements in the container
|
|
||||||
the container stays sorted until elements are added or removed.
|
|
||||||
|
|
||||||
- dict<K, T> and pool<T> will have the same order of iteration across
|
|
||||||
all compilers, standard libraries and architectures.
|
|
||||||
|
|
||||||
In addition to dict<K, T> and pool<T> there is also an idict<K> that
|
|
||||||
creates a bijective map from K to the integers. For example:
|
|
||||||
|
|
||||||
idict<string, 42> si;
|
|
||||||
log("%d\n", si("hello")); // will print 42
|
|
||||||
log("%d\n", si("world")); // will print 43
|
|
||||||
log("%d\n", si.at("world")); // will print 43
|
|
||||||
log("%d\n", si.at("dummy")); // will throw exception
|
|
||||||
log("%s\n", si[42].c_str())); // will print hello
|
|
||||||
log("%s\n", si[43].c_str())); // will print world
|
|
||||||
log("%s\n", si[44].c_str())); // will throw exception
|
|
||||||
|
|
||||||
It is not possible to remove elements from an idict.
|
|
||||||
|
|
||||||
Finally mfp<K> implements a merge-find set data structure (aka. disjoint-set or
|
|
||||||
union-find) over the type K ("mfp" = merge-find-promote).
|
|
||||||
|
|
||||||
2. Standard STL data types
|
2. Standard STL data types
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue