3 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
4 * Copyright (C) 1997-2000 GLib Team and others
5 * Copyright (C) 2007-2009 Jürg Billeter
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 * Jürg Billeter <j@bitron.ch>
28 * Hash table implementation of the {@link Map} interface.
30 * This implementation is better fit for highly heterogenous key values.
31 * In case of high key hashes redundancy or higher amount of data prefer using
32 * tree implementation like {@link TreeMap}.
36 public class Gee.HashMap<K,V> : Gee.AbstractMap<K,V> {
40 public override int size {
41 get { return _nnodes; }
47 public override bool read_only {
54 public override Set<K> keys {
58 keys = new KeySet<K,V> (this);
60 keys.add_weak_pointer ((void**) (&_keys));
69 public override Collection<V> values {
71 Collection<K> values = _values;
72 if (_values == null) {
73 values = new ValueCollection<K,V> (this);
75 values.add_weak_pointer ((void**) (&_values));
84 public override Set<Map.Entry<K,V>> entries {
86 Set<Map.Entry<K,V>> entries = _entries;
87 if (_entries == null) {
88 entries = new EntrySet<K,V> (this);
90 entries.add_weak_pointer ((void**) (&_entries));
97 * The keys' hash function.
99 [CCode (notify = false)]
100 public HashDataFunc<K> key_hash_func { private set; get; }
103 * The keys' equality testing function.
105 [CCode (notify = false)]
106 public EqualDataFunc<K> key_equal_func { private set; get; }
109 * The values' equality testing function.
111 [CCode (notify = false)]
112 public EqualDataFunc<V> value_equal_func { private set; get; }
114 private int _array_size;
116 private Node<K,V>[] _nodes;
118 private weak Set<K> _keys;
119 private weak Collection<V> _values;
120 private weak Set<Map.Entry<K,V>> _entries;
122 // concurrent modification protection
123 private int _stamp = 0;
125 private const int MIN_SIZE = 11;
126 private const int MAX_SIZE = 13845163;
129 * Constructs a new, empty hash map.
131 * If not provided, the functions parameters are requested to the
132 * {@link Functions} function factory methods.
134 * @param key_hash_func an optional key hash function
135 * @param key_equal_func an optional key equality testing function
136 * @param value_equal_func an optional value equality testing function
138 public HashMap (owned HashDataFunc<K>? key_hash_func = null, owned EqualDataFunc<K>? key_equal_func = null, owned EqualDataFunc<V>? value_equal_func = null) {
139 if (key_hash_func == null) {
140 key_hash_func = Functions.get_hash_func_for (typeof (K));
142 if (key_equal_func == null) {
143 key_equal_func = Functions.get_equal_func_for (typeof (K));
145 if (value_equal_func == null) {
146 value_equal_func = Functions.get_equal_func_for (typeof (V));
148 this.key_hash_func = key_hash_func;
149 this.key_equal_func = key_equal_func;
150 this.value_equal_func = value_equal_func;
152 _array_size = MIN_SIZE;
153 _nodes = new Node<K,V>[_array_size];
156 private Node<K,V>** lookup_node (K key) {
157 uint hash_value = key_hash_func (key);
158 Node<K,V>** node = &_nodes[hash_value % _array_size];
159 while ((*node) != null && (hash_value != (*node)->key_hash || !key_equal_func ((*node)->key, key))) {
160 node = &((*node)->next);
168 public override bool has_key (K key) {
169 Node<K,V>** node = lookup_node (key);
170 return (*node != null);
176 public override bool has (K key, V value) {
177 Node<K,V>** node = lookup_node (key);
178 return (*node != null && value_equal_func ((*node)->value, value));
184 public override V? get (K key) {
185 Node<K,V>* node = (*lookup_node (key));
196 public override void set (K key, V value) {
197 Node<K,V>** node = lookup_node (key);
199 (*node)->value = value;
201 uint hash_value = key_hash_func (key);
202 *node = new Node<K,V> (key, value, hash_value);
212 public override bool unset (K key, out V? value = null) {
213 bool b = unset_helper (key, out value);
223 public override void clear () {
224 for (int i = 0; i < _array_size; i++) {
225 Node<K,V> node = (owned) _nodes[i];
226 while (node != null) {
227 Node next = (owned) node.next;
240 public override Gee.MapIterator<K,V> map_iterator () {
241 return new MapIterator<K,V> (this);
244 private inline bool unset_helper (K key, out V? value = null) {
245 Node<K,V>** node = lookup_node (key);
247 Node<K,V> next = (owned) (*node)->next;
249 value = (owned) (*node)->value;
252 (*node)->value = null;
255 *node = (owned) next;
266 private inline void resize () {
267 if ((_array_size >= 3 * _nnodes && _array_size >= MIN_SIZE) ||
268 (3 * _array_size <= _nnodes && _array_size < MAX_SIZE)) {
269 int new_array_size = (int) SpacedPrimes.closest (_nnodes);
270 new_array_size = new_array_size.clamp (MIN_SIZE, MAX_SIZE);
272 Node<K,V>[] new_nodes = new Node<K,V>[new_array_size];
274 for (int i = 0; i < _array_size; i++) {
276 Node<K,V> next = null;
277 for (node = (owned) _nodes[i]; node != null; node = (owned) next) {
278 next = (owned) node.next;
279 uint hash_val = node.key_hash % new_array_size;
280 node.next = (owned) new_nodes[hash_val];
281 new_nodes[hash_val] = (owned) node;
284 _nodes = (owned) new_nodes;
285 _array_size = new_array_size;
294 private class Node<K,V> {
297 public Node<K,V> next;
298 public uint key_hash;
299 public unowned Map.Entry<K,V>? entry;
301 public Node (owned K k, owned V v, uint hash) {
309 private class Entry<K,V> : Map.Entry<K,V> {
310 private unowned Node<K,V> _node;
312 public static Map.Entry<K,V> entry_for<K,V> (Node<K,V> node) {
313 Map.Entry<K,V> result = node.entry;
314 if (node.entry == null) {
315 result = new Entry<K,V> (node);
317 result.add_weak_pointer ((void**) (&node.entry));
322 public Entry (Node<K,V> node) {
326 public override K key { get { return _node.key; } }
328 public override V value {
329 get { return _node.value; }
330 set { _node.value = value; }
333 public override bool read_only { get { return false; } }
336 private class KeySet<K,V> : AbstractSet<K> {
337 private HashMap<K,V> _map;
339 public KeySet (HashMap map) {
343 public override Iterator<K> iterator () {
344 return new KeyIterator<K,V> (_map);
347 public override int size {
348 get { return _map.size; }
351 public override bool read_only {
355 public override bool add (K key) {
356 assert_not_reached ();
359 public override void clear () {
360 assert_not_reached ();
363 public override bool remove (K key) {
364 assert_not_reached ();
367 public override bool contains (K key) {
368 return _map.has_key (key);
371 public bool add_all (Collection<K> collection) {
372 assert_not_reached ();
375 public bool remove_all (Collection<K> collection) {
376 assert_not_reached ();
379 public bool retain_all (Collection<K> collection) {
380 assert_not_reached ();
385 private class ValueCollection<K,V> : AbstractCollection<V> {
386 private HashMap<K,V> _map;
388 public ValueCollection (HashMap map) {
392 public override Iterator<V> iterator () {
393 return new ValueIterator<K,V> (_map);
396 public override int size {
397 get { return _map.size; }
400 public override bool read_only {
404 public override bool add (V value) {
405 assert_not_reached ();
408 public override void clear () {
409 assert_not_reached ();
412 public override bool remove (V value) {
413 assert_not_reached ();
416 public override bool contains (V value) {
417 Iterator<V> it = iterator ();
419 if (_map.value_equal_func (it.get (), value)) {
426 public bool add_all (Collection<V> collection) {
427 assert_not_reached ();
430 public bool remove_all (Collection<V> collection) {
431 assert_not_reached ();
434 public bool retain_all (Collection<V> collection) {
435 assert_not_reached ();
439 private class EntrySet<K,V> : AbstractSet<Map.Entry<K, V>> {
440 private HashMap<K,V> _map;
442 public EntrySet (HashMap<K,V> map) {
446 public override Iterator<Map.Entry<K, V>> iterator () {
447 return new EntryIterator<K,V> (_map);
450 public override int size {
451 get { return _map.size; }
454 public override bool read_only {
458 public override bool add (Map.Entry<K, V> entry) {
459 assert_not_reached ();
462 public override void clear () {
463 assert_not_reached ();
466 public override bool remove (Map.Entry<K, V> entry) {
467 assert_not_reached ();
470 public override bool contains (Map.Entry<K, V> entry) {
471 return _map.has (entry.key, entry.value);
474 public bool add_all (Collection<Map.Entry<K, V>> entries) {
475 assert_not_reached ();
478 public bool remove_all (Collection<Map.Entry<K, V>> entries) {
479 assert_not_reached ();
482 public bool retain_all (Collection<Map.Entry<K, V>> entries) {
483 assert_not_reached ();
487 private abstract class NodeIterator<K,V> : Object {
488 protected HashMap<K,V> _map;
489 protected int _index = -1;
490 protected weak Node<K,V> _node;
491 protected weak Node<K,V> _next;
493 // concurrent modification protection
494 protected int _stamp;
496 public NodeIterator (HashMap map) {
498 _stamp = _map._stamp;
501 public bool next () {
502 assert (_stamp == _map._stamp);
508 return (_node != null);
511 public bool has_next () {
512 assert (_stamp == _map._stamp);
518 while (_next == null && _index + 1 < _map._array_size) {
520 _next = _map._nodes[_index];
523 return (_next != null);
526 public virtual bool read_only {
534 return _node != null;
539 private class KeyIterator<K,V> : NodeIterator<K,V>, Traversable<K>, Iterator<K> {
540 public KeyIterator (HashMap map) {
544 public new K get () {
545 assert (_stamp == _map._stamp);
546 assert (_node != null);
550 public void remove () {
551 assert_not_reached ();
554 public bool foreach(ForallFunc<K> f) {
564 while(_next != null) {
571 if (_index + 1 < _map._array_size) {
572 _next = _map._nodes[++_index];
580 private class MapIterator<K,V> : NodeIterator<K,V>, Gee.MapIterator<K,V> {
581 public MapIterator (HashMap map) {
585 public new K get_key () {
586 assert (_stamp == _map._stamp);
587 assert (_node != null);
591 public void unset () {
592 assert (_stamp == _map._stamp);
593 assert (_node != null);
595 _map.unset_helper (_node.key);
597 _stamp = _map._stamp;
600 public V get_value () {
601 assert (_stamp == _map._stamp);
602 assert (_node != null);
606 public void set_value (V value) {
607 assert (_stamp == _map._stamp);
608 assert (_node != null);
609 _map.set (_node.key, value);
610 _stamp = _map._stamp;
613 public bool mutable {
619 public override bool read_only {
626 private class ValueIterator<K,V> : NodeIterator<K,V>, Traversable<V>, Iterator<V> {
627 public ValueIterator (HashMap map) {
631 public new V get () {
632 assert (_stamp == _map._stamp);
633 assert (_node != null);
637 public void remove () {
638 assert_not_reached ();
641 public bool foreach(ForallFunc<V> f) {
643 if (!f(_node.value)) {
651 while(_next != null) {
653 if (!f(_node.value)) {
658 if (_index + 1 < _map._array_size) {
659 _next = _map._nodes[++_index];
667 private class EntryIterator<K,V> : NodeIterator<K,V>, Traversable<Map.Entry<K,V>>, Iterator<Map.Entry<K,V>> {
668 public EntryIterator (HashMap map) {
672 public new Map.Entry<K,V> get () {
673 assert (_stamp == _map._stamp);
674 assert (_node != null);
675 return Entry<K,V>.entry_for<K,V> (_node);
678 public void remove () {
679 assert_not_reached ();
682 public bool foreach(ForallFunc<Map.Entry<K,V>> f) {
684 if (!f(Entry<K,V>.entry_for<K,V> (_node))) {
692 while(_next != null) {
694 if (!f(Entry<K,V>.entry_for<K,V> (_node))) {
699 if (_index + 1 < _map._array_size) {
700 _next = _map._nodes[++_index];