diff options
Diffstat (limited to 'gee/treemap.vala')
-rw-r--r-- | gee/treemap.vala | 1268 |
1 files changed, 1206 insertions, 62 deletions
diff --git a/gee/treemap.vala b/gee/treemap.vala index 8b3917e..2d2708a 100644 --- a/gee/treemap.vala +++ b/gee/treemap.vala @@ -1,6 +1,6 @@ /* treemap.vala * - * Copyright (C) 2009 Maciej Piechotka + * Copyright (C) 2009-2011 Maciej Piechotka * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -31,20 +31,24 @@ using GLib; * * @see HashMap */ -public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { +public class Gee.TreeMap<K,V> : Gee.AbstractBidirSortedMap<K,V> { /** * {@inheritDoc} */ public override int size { get { return _size; } } + + public override bool read_only { + get { return false; } + } /** * {@inheritDoc} */ public override Set<K> keys { owned get { - Set<K> keys = _keys; + var keys = _keys; if (_keys == null) { keys = new KeySet<K,V> (this); _keys = keys; @@ -59,7 +63,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { */ public override Collection<V> values { owned get { - Collection<K> values = _values; + var values = _values; if (_values == null) { values = new ValueCollection<K,V> (this); _values = values; @@ -74,7 +78,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { */ public override Set<Map.Entry<K,V>> entries { owned get { - Set<Map.Entry<K,V>> entries = _entries; + var entries = _entries; if (_entries == null) { entries = new EntrySet<K,V> (this); _entries = entries; @@ -87,18 +91,20 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { /** * The keys' comparator function. */ - public CompareFunc key_compare_func { private set; get; } + [CCode (notify = false)] + public CompareDataFunc<K> key_compare_func { private set; get; } /** * The values' equality testing function. */ - public EqualFunc value_equal_func { private set; get; } + [CCode (notify = false)] + public EqualDataFunc<V> value_equal_func { private set; get; } private int _size = 0; - private weak Set<K> _keys; + private weak SortedSet<K> _keys; private weak Collection<V> _values; - private weak Set<Map.Entry<K,V>> _entries; + private weak SortedSet<Map.Entry<K,V>> _entries; /** * Constructs a new, empty tree map sorted according to the specified @@ -110,7 +116,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { * @param key_compare_func an optional key comparator function * @param value_equal_func an optional values equality testing function */ - public TreeMap (CompareFunc? key_compare_func = null, EqualFunc? value_equal_func = null) { + public TreeMap (owned CompareDataFunc<K>? key_compare_func = null, owned EqualDataFunc<V>? value_equal_func = null) { if (key_compare_func == null) { key_compare_func = Functions.get_compare_func_for (typeof (K)); } @@ -121,6 +127,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { this.value_equal_func = value_equal_func; } + ~TreeMap () { + clear (); + } + private void rotate_right (ref Node<K, V> root) { Node<K,V> pivot = (owned) root.left; pivot.color = root.color; @@ -191,8 +201,9 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { return null; } - private void set_to_node (ref Node<K, V>? node, K key, V value, Node<K, V>? prev, Node<K, V>? next) { + private bool set_to_node (ref Node<K, V>? node, K key, V value, out V? old_value, Node<K, V>? prev, Node<K, V>? next) { if (node == null) { + old_value = null; node = new Node<K,V> (key, value, prev, next); if (prev == null) { first = node; @@ -201,25 +212,36 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { last = node; } _size++; + return true; } int cmp = key_compare_func (key, node.key); + bool changed; if (cmp == 0) { - node.value = value; + if (value_equal_func (value, node.value)) { + old_value = null; + changed = false; + } else { + old_value = (owned) node.value; + node.value = value; + changed = true; + } } else if (cmp < 0) { - set_to_node (ref node.left, key, value, node.prev, node); + changed = set_to_node (ref node.left, key, value, out old_value, node.prev, node); } else { - set_to_node (ref node.right, key, value, node, node.next); + changed = set_to_node (ref node.right, key, value, out old_value, node, node.next); } fix_up (ref node); + return changed; } /** * {@inheritDoc} */ public override void set (K key, V value) { - set_to_node (ref root, key, value, null, null); + V old_value; + set_to_node (ref root, key, value, out old_value, null, null); root.color = Node.Color.BLACK; stamp++; } @@ -243,12 +265,8 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { private void fix_removal (ref Node<K,V> node, out K? key = null, out V? value) { Node<K,V> n = (owned) node; - if (&key != null) - key = (owned) n.key; - else - n.key = null; - if (&value != null) - value = (owned) n.value; + key = (owned) n.key; + value = (owned) n.value; if (n.prev != null) { n.prev.next = n.next; } else { @@ -279,12 +297,18 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { fix_up (ref node); } - private bool remove_from_node (ref Node<K, V>? node, K key, out V value, out unowned Node<K, V>? prev = null, out unowned Node<K, V>? next = null) { + private bool remove_from_node (ref Node<K, V>? node, K key, out V? value, out unowned Node<K, V>? prev = null, out unowned Node<K, V>? next = null) { if (node == null) { + value = null; + next = null; + prev = null; return false; } else if (key_compare_func (key, node.key) < 0) { weak Node<K,V> left = node.left; if (left == null) { + value = null; + next = null; + prev = null; return false; } if (node.left != null && is_black (left) && is_black (left.left)) { @@ -300,10 +324,8 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { weak Node<K,V>? r = node.right; if (key_compare_func (key, node.key) == 0 && r == null) { - if (&prev != null) - prev = node.prev; - if (&next != null) - next = node.next; + prev = node.prev; + next = node.next; fix_removal (ref node, null, out value); return true; } @@ -312,10 +334,8 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { } if (key_compare_func (key, node.key) == 0) { value = (owned) node.value; - if (&prev != null) - prev = node.prev; - if (&next != null) - next = node; + prev = node.prev; + next = node; remove_minimal (ref node.right, out node.key, out node.value); fix_up (ref node); return true; @@ -343,12 +363,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { * {@inheritDoc} */ public override bool unset (K key, out V? value = null) { - V node_value; - bool b = remove_from_node (ref root, key, out node_value); - - if (&value != null) { - value = (owned) node_value; - } + bool b = remove_from_node (ref root, key, out value); if (root != null) { root.color = Node.Color.BLACK; @@ -381,9 +396,66 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { /** * {@inheritDoc} */ + public override SortedMap<K,V> head_map (K before) { + return new SubMap<K,V> (this, new Range<K,V>.head (this, before)); + } + + /** + * {@inheritDoc} + */ + public override SortedMap<K,V> tail_map (K after) { + return new SubMap<K,V> (this, new Range<K,V>.tail (this, after)); + } + + /** + * {@inheritDoc} + */ + public override SortedMap<K,V> sub_map (K after, K before) { + return new SubMap<K,V> (this, new Range<K,V> (this, after, before)); + } + + /** + * {@inheritDoc} + */ + public override SortedSet<K> ascending_keys { + owned get { + var keys = _keys; + if (_keys == null) { + keys = new KeySet<K,V> (this); + _keys = keys; + keys.add_weak_pointer (&_keys); + } + return keys; + } + } + /** + * {@inheritDoc} + */ + public override SortedSet<Map.Entry<K,V>> ascending_entries { + owned get { + var entries = _entries; + if (_entries == null) { + entries = new EntrySet<K,V> (this); + _entries = entries; + entries.add_weak_pointer (&_entries); + } + return entries; + } + } + + /** + * {@inheritDoc} + */ public override Gee.MapIterator<K,V> map_iterator () { return new MapIterator<K,V> (this); } + + /** + * {@inheritDoc} + */ + public override Gee.BidirMapIterator<K,V> bidir_map_iterator () { + return new MapIterator<K,V> (this); + } [Compact] private class Node<K, V> { @@ -439,12 +511,54 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { private weak Node<K, V>? last = null; private int stamp = 0; + private inline K min (K a, K b) { + return key_compare_func (a, b) <= 0 ? a : b; + } + + private inline K max (K a, K b) { + return key_compare_func (a, b) > 0 ? a : b; + } + + private inline unowned Node<K,V>? find_node (K key) { + unowned Node<K,V>? cur = root; + while (cur != null) { + int res = key_compare_func (key, cur.key); + if (res == 0) { + return cur; + } else if (res < 0) { + cur = cur.left; + } else { + cur = cur.right; + } + } + return null; + } + + private inline unowned Node<K,V>? find_nearest (K key) { + unowned Node<K,V>? cur = root; + while (cur != null) { + int res = key_compare_func (key, cur.key); + if (res == 0) { + return cur; + } else if (res < 0) { + if (cur.left == null) + return cur; + cur = cur.left; + } else { + if (cur.right == null) + return cur; + cur = cur.right; + } + } + return null; + } + private class Entry<K,V> : Map.Entry<K,V> { private unowned Node<K,V> _node; public static Map.Entry<K,V> entry_for<K,V> (Node<K,V> node) { Map.Entry<K,V> result = node.entry; - if (node.entry == null) { + if (result == null) { result = new Entry<K,V> (node); node.entry = result; result.add_weak_pointer ((void**) (&node.entry)); @@ -462,9 +576,313 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { get { return _node.value; } set { _node.value = value; } } + + public override bool read_only { get { return false; } } } - private class KeySet<K,V> : AbstractSet<K> { + private inline unowned Node<K,V>? find_lower (K key) { + unowned Node<K,V>? node = find_nearest (key); + if (node == null) + return null; + return key_compare_func (key, node.key) <= 0 ? node.prev : node; + } + + private inline unowned Node<K,V>? find_higher (K key) { + unowned Node<K,V>? node = find_nearest (key); + if (node == null) + return null; + return key_compare_func (key, node.key) >= 0 ? node.next : node; + } + + private inline unowned Node<K,V>? find_floor (K key) { + unowned Node<K,V>? node = find_nearest (key); + if (node == null) + return null; + return key_compare_func (key, node.key) < 0 ? node.prev : node; + } + + private inline unowned Node<K,V>? find_ceil (K key) { + unowned Node<K,V>? node = find_nearest (key); + if (node == null) + return null; + return key_compare_func (key, node.key) > 0 ? node.next : node; + } + + private inline K? lift_null_key (Node<K,V>? node) { + return node != null ? node.key : null; + } + + private class Range<K,V> { + public Range (TreeMap<K,V> map, K after, K before) { + this.map = map; + if (map.key_compare_func (after, before) < 0) { + this.after = after; + this.before = before; + type = RangeType.BOUNDED; + } else { + type = RangeType.EMPTY; + } + } + + public Range.head (TreeMap<K,V> map, K before) { + this.map = map; + this.before = before; + type = RangeType.HEAD; + } + + public Range.tail (TreeMap<K,V> map, K after) { + this.map = map; + this.after = after; + type = RangeType.TAIL; + } + + public Range.empty (TreeMap<K,V> map) { + this.map = map; + type = RangeType.EMPTY; + } + + public Range<K,V> cut_head (K after) { + switch (type) { + case RangeType.HEAD: + return new Range<K,V> (map, after, before); + case RangeType.TAIL: + return new Range<K,V>.tail (map, map.max (after, this.after)); + case RangeType.EMPTY: + return this; + case RangeType.BOUNDED: + var _after = map.max (after, this.after); + return new Range<K,V> (map, _after, before); + default: + assert_not_reached (); + } + } + + public Range<K,V> cut_tail (K before) { + switch (type) { + case RangeType.HEAD: + return new Range<K,V>.head (map, map.min (before, this.before)); + case RangeType.TAIL: + return new Range<K,V> (map, after, before); + case RangeType.EMPTY: + return this; + case RangeType.BOUNDED: + var _before = map.min (before, this.before); + return new Range<K,V> (map, after, _before); + default: + assert_not_reached (); + } + } + + public Range<K,V> cut (K after, K before) { + if (type == RangeType.EMPTY) + return this; + var _before = (type == RangeType.HEAD || type == RangeType.BOUNDED) ? + map.min (before, this.before) : before; + var _after = (type == RangeType.TAIL || type == RangeType.BOUNDED) ? + map.max (after, this.after) : after; + return new Range<K,V> (map, _after, _before); + } + + public bool in_range (K key) { + return type == RangeType.EMPTY ? false : compare_range(key) == 0; + } + + public int compare_range (K key) { + switch (type) { + case RangeType.HEAD: + return map.key_compare_func (key, before) < 0 ? 0 : 1; + case RangeType.TAIL: + return map.key_compare_func (key, after) >= 0 ? 0 : -1; + case RangeType.EMPTY: + return 0; // For simplicity - please make sure it does not break anything + case RangeType.BOUNDED: + return map.key_compare_func (key, after) >= 0 ? + (map.key_compare_func (key, before) < 0 ? 0 : 1) : -1; + default: + assert_not_reached (); + } + } + + public bool empty_submap () { + switch (type) { + case RangeType.HEAD: + return map.first == null || !in_range (map.first.key); + case RangeType.TAIL: + return map.last == null || !in_range (map.last.key); + case RangeType.EMPTY: + return true; + case RangeType.BOUNDED: + return first () == null; + default: + assert_not_reached (); + } + } + + public unowned Node<K,V>? first () { + switch (type) { + case RangeType.EMPTY: + return null; + case RangeType.HEAD: + return map.first; + default: + return map.find_floor (after); + } + } + + public unowned Node<K,V>? last () { + switch (type) { + case RangeType.EMPTY: + return null; + case RangeType.TAIL: + return map.last; + default: + return map.find_lower (before); + } + } + + private new TreeMap<K,V> map; + private K after; + private K before; + private RangeType type; + } + + private enum RangeType { + HEAD, + TAIL, + EMPTY, + BOUNDED + } + + private class SubMap<K,V> : AbstractBidirSortedMap<K,V> { + public override int size { get { return keys.size; } } + public bool is_empty { get { return keys.is_empty; } } + + public SubMap (TreeMap<K,V> map, Range<K,V> range) { + this.map = map; + this.range = range; + } + + private weak SortedSet<K>? _keys; + public override Set<K> keys { + owned get { + var keys = _keys; + if (_keys == null) { + keys = new SubKeySet<K,V> (map, range); + _keys = keys; + keys.add_weak_pointer(&_keys); + } + return keys; + } + } + + private weak Collection<K>? _values; + public override Collection<V> values { + owned get { + var values = _values; + if (_values == null) { + values = new SubValueCollection<K,V> (map, range); + _values = values; + values.add_weak_pointer(&_values); + } + return values; + } + } + + private weak SortedSet<Entry<K,V>>? _entries; + public override Set<Entry<K,V>> entries { + owned get { + var entries = _entries; + if (_entries == null) { + entries = new SubEntrySet<K,V> (map, range); + _entries = entries; + entries.add_weak_pointer(&_entries); + } + return entries; + } + } + + public override bool read_only { + get { + return true; + } + } + + public override bool has_key (K key) { + return range.in_range (key) && map.has_key (key); + } + + public override bool has (K key, V value) { + return range.in_range (key) && map.has (key, value); + } + + public override new V? get (K key) { + return range.in_range (key) ? map.get (key) : null; + } + + public override void set (K key, V value) { + if (range.in_range (key)) + map.set (key, value); + } + + public override bool unset (K key, out V? value = null) { + value = null; + return range.in_range (key) && map.unset (key, out value); + } + + public override void clear () { + for (var iterator = map_iterator (); iterator.next ();) + iterator.unset (); + } + + public override Gee.MapIterator<K,V> map_iterator () { + return new SubMapIterator<K,V> (map, range); + } + + public override BidirMapIterator<K,V> bidir_map_iterator () { + return new SubMapIterator<K,V> (map, range); + } + + public override SortedMap<K,V> head_map (K before) { + return new SubMap<K,V> (map, range.cut_tail (before)); + } + + public override SortedMap<K,V> tail_map (K after) { + return new SubMap<K,V> (map, range.cut_head (after)); + } + + public override SortedMap<K,V> sub_map (K after, K before) { + return new SubMap<K,V> (map, range.cut (after, before)); + } + + public override SortedSet<K> ascending_keys { + owned get { + var keys = _keys; + if (_keys == null) { + keys = new SubKeySet<K,V> (map, range); + _keys = keys; + keys.add_weak_pointer(&_keys); + } + return keys; + } + } + + public override SortedSet<K> ascending_entries { + owned get { + var entries = _entries; + if (_entries == null) { + entries = new SubEntrySet<K,V> (map, range); + _entries = entries; + entries.add_weak_pointer(&_entries); + } + return _entries; + } + } + + private TreeMap<K,V> map; + private Range<K,V> range; + } + + private class KeySet<K,V> : AbstractBidirSortedSet<K> { private TreeMap<K,V> _map; public KeySet (TreeMap<K,V> map) { @@ -479,6 +897,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { get { return _map.size; } } + public override bool read_only { + get { return true; } + } + public override bool add (K key) { assert_not_reached (); } @@ -495,17 +917,173 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { return _map.has_key (key); } - public override bool add_all (Collection<K> collection) { + public override K first () { + assert (_map.first != null); + return _map.first.key; + } + + public override K last () { + assert (_map.last != null); + return _map.last.key; + } + + public override BidirIterator<K> bidir_iterator () { + return new KeyIterator<K,V> (_map); + } + + public override SortedSet<K> head_set (K before) { + return new SubKeySet<K,V> (_map, new Range<K,V>.head (_map, before)); + } + + public override SortedSet<K> tail_set (K after) { + return new SubKeySet<K,V> (_map, new Range<K,V>.tail (_map, after)); + } + + public override SortedSet<K> sub_set (K after, K before) { + return new SubKeySet<K,V> (_map, new Range<K,V> (_map, after, before)); + } + + public override Iterator<K>? iterator_at (K item) { + weak Node<K,V>? node = _map.find_node (item); + if (node == null) + return null; + return new KeyIterator<K,V>.pointing (_map, node); + } + + public override K? lower (K item) { + return _map.lift_null_key (_map.find_lower (item)); + } + + public override K? higher (K item) { + return _map.lift_null_key (_map.find_higher (item)); + } + + public override K? floor (K item) { + return _map.lift_null_key (_map.find_floor (item)); + } + + public override K? ceil (K item) { + return _map.lift_null_key (_map.find_ceil (item)); + } + } + + private class SubKeySet<K,V> : AbstractBidirSortedSet<K> { + [CCode (notify = false)] + public TreeMap<K,V> map { private set; get; } + [CCode (notify = false)] + public Range<K,V> range { private set; get; } + + public SubKeySet (TreeMap<K,V> map, Range<K,V> range) { + this.map = map; + this.range = range; + } + + public override Iterator<K> iterator () { + return new SubKeyIterator<K,V> (map, range); + } + + public override int size { + get { + var i = 0; + Gee.Iterator<K> iterator = iterator (); + while (iterator.next ()) + i++; + return i; + } + } + + public override bool read_only { + get { + return true; + } + } + + public bool is_empty { get { return range.empty_submap (); } } + + public override bool add (K key) { assert_not_reached (); } - public override bool remove_all (Collection<K> collection) { + public override void clear () { assert_not_reached (); } - public override bool retain_all (Collection<K> collection) { + public override bool remove (K key) { assert_not_reached (); } + + public override bool contains (K key) { + return range.in_range(key) && map.has_key (key); + } + + public override BidirIterator<K> bidir_iterator () { + return new SubKeyIterator<K,V> (map, range); + } + + public override K first () { + weak Node<K,V>? _first = range.first (); + assert (_first != null); + return _first.key; + } + + public override K last () { + weak Node<K,V>? _last = range.last (); + assert (_last != null); + return _last.key; + } + + public override SortedSet<K> head_set (K before) { + return new SubKeySet<K,V> (map, range.cut_tail (before)); + } + + public override SortedSet<K> tail_set (K after) { + return new SubKeySet<K,V> (map, range.cut_head (after)); + } + + public override SortedSet<K> sub_set (K after, K before) { + return new SubKeySet<K,V> (map, range.cut (after, before)); + } + + public override Iterator<K>? iterator_at (K key) { + if (!range.in_range (key)) + return null; + weak Node<K,V>? n = map.find_node (key); + if (n == null) + return null; + return new SubKeyIterator<K,V>.pointing (map, range, n); + } + + public override K? lower (K key) { + var res = range.compare_range (key); + if (res > 0) + return last (); + var l = map.lift_null_key (map.find_lower (key)); + return l != null && range.in_range (l) ? l : null; + } + + public override K? higher (K key) { + var res = range.compare_range (key); + if (res < 0) + return first (); + var h = map.lift_null_key (map.find_higher (key)); + return h != null && range.in_range (h) ? h : null; + } + + public override K? floor (K key) { + var res = range.compare_range (key); + if (res > 0) + return last (); + var l = map.lift_null_key (map.find_floor (key)); + return l != null && range.in_range (l) ? l : null; + } + + public override K? ceil (K key) { + var res = range.compare_range (key); + if (res < 0) + return first (); + var h = map.lift_null_key (map.find_ceil (key)); + return h != null && range.in_range (h) ? h : null; + } } private class ValueCollection<K,V> : AbstractCollection<V> { @@ -523,6 +1101,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { get { return _map.size; } } + public override bool read_only { + get { return true; } + } + public override bool add (V key) { assert_not_reached (); } @@ -544,21 +1126,65 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { } return false; } + } + + private class SubValueCollection<K,V> : AbstractCollection<V> { + [CCode (notify = false)] + public TreeMap<K,V> map { private set; get; } + [CCode (notify = false)] + public Range<K,V> range { private set; get; } + + public SubValueCollection (TreeMap<K,V> map, Range<K,V> range) { + this.map = map; + this.range = range; + } + + public override Iterator<V> iterator () { + return new SubValueIterator<K,V> (map, range); + } + + public override bool read_only { + get { + return true; + } + } + + public override int size { + get { + var i = 0; + Gee.Iterator<V> iterator = iterator (); + while (iterator.next ()) + i++; + return i; + } + } + + public bool is_empty { get { return range.empty_submap (); } } - public override bool add_all (Collection<V> collection) { + public override bool add (V key) { assert_not_reached (); } - public override bool remove_all (Collection<V> collection) { + public override void clear () { assert_not_reached (); } - public override bool retain_all (Collection<V> collection) { + public override bool remove (V key) { assert_not_reached (); } + + public override bool contains (V key) { + Iterator<V> it = iterator (); + while (it.next ()) { + if (map.value_equal_func (key, it.get ())) { + return true; + } + } + return false; + } } - private class EntrySet<K,V> : AbstractSet<Map.Entry<K, V>> { + private class EntrySet<K,V> : AbstractBidirSortedSet<Map.Entry<K, V>> { private TreeMap<K,V> _map; public EntrySet (TreeMap<K,V> map) { @@ -573,6 +1199,10 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { get { return _map.size; } } + public override bool read_only { + get { return true; } + } + public override bool add (Map.Entry<K, V> entry) { assert_not_reached (); } @@ -589,32 +1219,200 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { return _map.has (entry.key, entry.value); } - public override bool add_all (Collection<Map.Entry<K, V>> entries) { + public override Map.Entry<K, V>/*?*/ first () { + assert (_map.first != null); + return Entry.entry_for<K,V> (_map.first); + } + + public override Map.Entry<K, V>/*?*/ last () { + assert (_map.last != null); + return Entry.entry_for<K,V> (_map.last); + } + + public override BidirIterator<Map.Entry<K, V>> bidir_iterator () { + return new EntryIterator<K,V> (_map); + } + + public override SortedSet<Map.Entry<K, V>> head_set (Map.Entry<K, V> before) { + return new SubEntrySet<K,V> (_map, new Range<K,V>.head (_map, before.key)); + } + + public override SortedSet<Map.Entry<K, V>> tail_set (Map.Entry<K, V> after) { + return new SubEntrySet<K,V> (_map, new Range<K,V>.tail (_map, after.key)); + } + + public override SortedSet<K> sub_set (Map.Entry<K, V> after, Map.Entry<K, V> before) { + return new SubEntrySet<K,V> (_map, new Range<K,V> (_map, after.key, before.key)); + } + + public override Iterator<Map.Entry<K, V>>? iterator_at (Map.Entry<K, V> item) { + weak Node<K,V>? node = _map.find_node (item.key); + if (node == null || !_map.value_equal_func (node.value, item.value)) + return null; + return new EntryIterator<K,V>.pointing (_map, node); + } + + public override Map.Entry<K, V>/*?*/ lower (Map.Entry<K, V> item) { + weak Node<K,V>? l = _map.find_lower (item.key); + return l != null ? Entry.entry_for<K,V> (l) : null; + } + + public override Map.Entry<K, V>/*?*/ higher (Map.Entry<K, V> item) { + weak Node<K,V>? l = _map.find_higher (item.key); + return l != null ? Entry.entry_for<K,V> (l) : null; + } + + public override Map.Entry<K, V>/*?*/ floor (Map.Entry<K, V> item) { + weak Node<K,V>? l = _map.find_floor (item.key); + return l != null ? Entry.entry_for<K,V> (l) : null; + } + + public override Map.Entry<K, V>/*?*/ ceil (Map.Entry<K, V> item) { + weak Node<K,V>? l = _map.find_ceil (item.key); + return l != null ? Entry.entry_for<K,V> (l) : null; + } + } + + private class SubEntrySet<K,V> : AbstractBidirSortedSet<Map.Entry<K,V>> { + [CCode (notify = false)] + public TreeMap<K,V> map { private set; get; } + [CCode (notify = false)] + public Range<K,V> range { private set; get; } + + public SubEntrySet (TreeMap<K,V> map, Range<K,V> range) { + this.map = map; + this.range = range; + } + + public override Iterator<Map.Entry<K,V>> iterator () { + return new SubEntryIterator<K,V> (map, range); + } + + public override int size { + get { + var i = 0; + Gee.Iterator<Map.Entry<K,V>> iterator = iterator (); + while (iterator.next ()) + i++; + return i; + } + } + + public override bool read_only { + get { + return true; + } + } + + public bool is_empty { get { return range.empty_submap (); } } + + public override bool add (Map.Entry<K,V> entry) { assert_not_reached (); } - public override bool remove_all (Collection<Map.Entry<K, V>> entries) { + public override void clear () { assert_not_reached (); } - public override bool retain_all (Collection<Map.Entry<K, V>> entries) { + public override bool remove (Map.Entry<K,V> entry) { assert_not_reached (); } + + public override bool contains (Map.Entry<K,V> entry) { + return range.in_range(entry.key) && map.has (entry.key, entry.value); + } + + public override BidirIterator<K> bidir_iterator () { + return new SubEntryIterator<K,V> (map, range); + } + + public override Map.Entry<K,V> first () { + weak Node<K,V>? _first = range.first (); + assert (_first != null); + return Entry.entry_for<K,V> (_first); + } + + public override Map.Entry<K,V> last () { + weak Node<K,V>? _last = range.last (); + assert (_last != null); + return Entry.entry_for<K,V> (_last); + } + + public override SortedSet<K> head_set (Map.Entry<K,V> before) { + return new SubEntrySet<K,V> (map, range.cut_tail (before.key)); + } + + public override SortedSet<K> tail_set (Map.Entry<K,V> after) { + return new SubEntrySet<K,V> (map, range.cut_head (after.key)); + } + + public override SortedSet<K> sub_set (Map.Entry<K,V> after, Map.Entry<K,V> before) { + return new SubEntrySet<K,V> (map, range.cut (after.key, before.key)); + } + + public override Iterator<Map.Entry<K,V>>? iterator_at (Map.Entry<K,V> entry) { + if (!range.in_range (entry.key)) + return null; + weak Node<K,V>? n = map.find_node (entry.key); + if (n == null || !map.value_equal_func (n.value, entry.value)) + return null; + return new SubEntryIterator<K,V>.pointing (map, range, n); + } + + public override Map.Entry<K,V>/*?*/ lower (Map.Entry<K,V> entry) { + var res = range.compare_range (entry.key); + if (res > 0) + return last (); + weak Node<K,V>? l = map.find_lower (entry.key); + return l != null && range.in_range (l.key) ? Entry.entry_for<K,V> (l) : null; + } + + public override Map.Entry<K,V>/*?*/ higher (Map.Entry<K,V> entry) { + var res = range.compare_range (entry.key); + if (res < 0) + return first (); + weak Node<K,V>? h = map.find_higher (entry.key); + return h != null && range.in_range (h.key) ? Entry.entry_for<K,V> (h) : null; + } + + public override Map.Entry<K,V>/*?*/ floor (Map.Entry<K,V> entry) { + var res = range.compare_range (entry.key); + if (res > 0) + return last (); + weak Node<K,V>? l = map.find_floor (entry.key); + return l != null && range.in_range (l.key) ? Entry.entry_for<K,V> (l) : null; + } + + public override Map.Entry<K,V>/*?*/ ceil (Map.Entry<K,V> entry) { + var res = range.compare_range (entry.key); + if (res < 0) + return first (); + weak Node<K,V>? h = map.find_ceil (entry.key); + return h != null && range.in_range (h.key) ? Entry.entry_for<K,V> (h) : null; + } } - private class NodeIterator<K,V> : Object { + private class NodeIterator<K, V> : Object { protected TreeMap<K,V> _map; // concurrent modification protection protected int stamp; - protected weak Node<K, V>? current; + protected bool started = false; + + internal weak Node<K, V>? current; protected weak Node<K, V>? _next; protected weak Node<K, V>? _prev; public NodeIterator (TreeMap<K,V> map) { _map = map; + this.stamp = _map.stamp; + } + + public NodeIterator.pointing (TreeMap<K,V> map, Node<K,V> current) { + _map = map; stamp = _map.stamp; + this.current = current; } public bool next () { @@ -628,6 +1426,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { } } else if (_next == null && _prev == null) { current = _map.first; + started = true; return current != null; } else { current = _next; @@ -644,7 +1443,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { return (current == null && _next == null && _prev == null && _map.first != null) || (current == null && _next != null) || (current != null && current.next != null); - } + } public bool first () { assert (stamp == _map.stamp); @@ -692,7 +1491,7 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { public void remove () { assert_not_reached (); } - + public void unset () { assert (stamp == _map.stamp); assert (current != null); @@ -706,65 +1505,410 @@ public class Gee.TreeMap<K,V> : Gee.AbstractMap<K,V> { _map.stamp++; assert (stamp == _map.stamp); } + + public virtual bool read_only { + get { + return true; + } + } + + public bool valid { + get { + return current != null; + } + } + + internal unowned Node<K,V>? safe_next_get () { + return (current != null) ? current.next : _next; + } + + internal unowned Node<K,V>? safe_previous_get () { + return (current != null) ? current.prev : _prev; + } } - private class KeyIterator<K,V> : NodeIterator<K,V>, Gee.Iterator<K>, BidirIterator<K> { + private class SubNodeIterator<K,V> : Object { + public SubNodeIterator (TreeMap<K,V> map, Range<K,V> range) { + _map = map; + this.range = range; + } + + public SubNodeIterator.pointing (TreeMap<K,V> map, Range<K,V> range, Node<K,V> node) { + _map = map; + this.range = range; + this.iterator = new NodeIterator<K,V>.pointing (_map, node); + } + + public bool next () { + if (iterator != null) { + weak Node<K,V>? node= iterator.safe_next_get (); + if (node != null && range.in_range (node.key)) { + assert (iterator.next ()); + return true; + } else { + return false; + } + } else { + return first (); + } + } + + public bool has_next () { + if (iterator != null) { + weak Node<K,V>? node = iterator.safe_next_get (); + return node != null && range.in_range (node.key); + } else { + return range.first () != null; + } + } + + public virtual bool first () { + weak Node<K,V>? node = range.first (); + if (node == null) + return false; + iterator = iterator_pointing_at (node); + return true; + } + + public bool previous () { + if (iterator == null) + return false; + weak Node<K,V>? node; + if ((node = iterator.safe_previous_get ()) != null && range.in_range (node.key)) { + assert (iterator.previous ()); + return true; + } else { + return false; + } + } + + public bool has_previous () { + if (iterator == null) + return false; + weak Node<K,V>? node; + return (node = iterator.safe_previous_get ()) != null && range.in_range (node.key); + } + + public virtual bool last () { + weak Node<K,V>? node = range.last (); + if (node == null) + return false; + iterator = iterator_pointing_at (node); + return true; + } + + public void remove () { + assert (valid); + iterator.remove (); + } + + public void unset () { + assert (valid); + iterator.unset (); + } + + public virtual bool read_only { + get { + return true; + } + } + + public bool valid { + get { + return iterator != null && iterator.valid; + } + } + + protected virtual NodeIterator<K,V> iterator_pointing_at (Node<K,V> node) { + return new NodeIterator<K,V>.pointing (_map, node); + } + + protected new TreeMap<K,V> _map; + protected Range<K,V> range; + protected NodeIterator<K,V>? iterator = null; + } + + private class KeyIterator<K,V> : NodeIterator<K, V>, Traversable<K>, Gee.Iterator<K>, BidirIterator<K> { public KeyIterator (TreeMap<K,V> map) { base (map); } + public KeyIterator.pointing (TreeMap<K,V> map, Node<K,V> current) { + base.pointing (map, current); + } + public new K get () { assert (stamp == _map.stamp); assert (current != null); return current.key; } + + public bool foreach (ForallFunc<K> f) { + if (current != null) { + if (!f (current.key)) { + return false; + } + current = current.next; + } else if (_next == null) { + current = _map.first; + started = true; + } else { + current = _next; + if (current != null) { + _next = null; + _prev = null; + } + } + for (; current != null; current = current.next) { + if (!f (current.key)) { + return false; + } + } + return true; + } } - private class ValueIterator<K,V> : NodeIterator<K,V>, Gee.Iterator<V>, Gee.BidirIterator<V> { + private class SubKeyIterator<K,V> : SubNodeIterator<K,V>, Traversable<K>, Gee.Iterator<K>, BidirIterator<K> { + public SubKeyIterator (TreeMap<K,V> map, Range<K,V> range) { + base (map, range); + } + + public SubKeyIterator.pointing (TreeMap<K,V> map, Range<K,V> range, Node<K,V> node) { + base.pointing (map, range, node); + } + + public new K get () { + assert (valid); + return iterator.current.key; + } + + public bool foreach (ForallFunc<K> f) { + if (valid) { + if (!f (iterator.current.key)) { + return false; + } + } + while (iterator.next ()) { + if (!f (iterator.current.key)) { + return false; + } + } + return true; + } + } + + private class ValueIterator<K,V> : NodeIterator<K,V>, Traversable<V>, Gee.Iterator<V>, Gee.BidirIterator<V> { public ValueIterator (TreeMap<K,V> map) { base (map); } + public ValueIterator.pointing (TreeMap<K,V> map, Node<K,V> current) { + base.pointing (map, current); + } + public new V get () { assert (stamp == _map.stamp); - assert (current != null); + assert (valid); return current.value; } + + public bool foreach (ForallFunc<V> f) { + if (current != null) { + if (!f (current.key)) { + return false; + } + current = current.next; + } else if (_next == null) { + current = _map.first; + started = true; + } else { + current = _next; + if (current != null) { + _next = null; + _prev = null; + } + } + for (; current != null; current = current.next) { + if (!f (current.key)) { + return false; + } + } + return true; + } + } + + private class SubValueIterator<K,V> : SubNodeIterator<K,V>, Traversable<V>, Gee.Iterator<V>, BidirIterator<V> { + public SubValueIterator (TreeMap<K,V> map, Range<K,V> range) { + base (map, range); + } + + public SubValueIterator.pointing (TreeMap<K,V> map, Range<K,V> range, Node<K,V> node) { + base.pointing (map, range, node); + } + + public new V get () { + assert (valid); + return iterator.current.value; + } + + public bool foreach (ForallFunc<V> f) { + if (valid) { + if (!f (iterator.current.key)) { + return false; + } + } + while (iterator.next ()) { + if (!f (iterator.current.key)) { + return false; + } + } + return true; + } } - private class EntryIterator<K,V> : NodeIterator<K,V>, Gee.Iterator<Map.Entry<K,V>>, Gee.BidirIterator<Map.Entry<K,V>> { + private class EntryIterator<K,V> : NodeIterator<K,V>, Traversable<Map.Entry<K, V>>, Gee.Iterator<Map.Entry<K,V>>, Gee.BidirIterator<Map.Entry<K,V>> { public EntryIterator (TreeMap<K,V> map) { base (map); } + public EntryIterator.pointing (TreeMap<K,V> map, Node<K,V> node) { + base.pointing (map, node); + } + public new Map.Entry<K,V> get () { assert (stamp == _map.stamp); - assert (current != null); - return Entry<K,V>.entry_for<K,V> (current); + assert (valid); + return Entry.entry_for<K,V> (current); + } + + public new void remove () { + unset (); + } + + public bool foreach (ForallFunc<Map.Entry<K, V>> f) { + if (current != null) { + if (!f (Entry.entry_for<K,V> (current))) { + return false; + } + current = current.next; + } else if (_next == null) { + current = _map.first; + started = true; + } else { + current = _next; + if (current != null) { + _next = null; + _prev = null; + } + } + for (; current != null; current = current.next) { + if (!f (Entry.entry_for<K,V> (current))) { + return false; + } + } + return true; + } + } + + private class SubEntryIterator<K,V> : SubNodeIterator<K,V>, Traversable<Map.Entry<K, V>>, Gee.Iterator<Map.Entry<K,V>>, Gee.BidirIterator<Map.Entry<K,V>> { + public SubEntryIterator (TreeMap<K,V> map, Range<K,V> range) { + base (map, range); + } + + public SubEntryIterator.pointing (TreeMap<K,V> map, Range<K,V> range, Node<K,V> node) { + base.pointing (map, range, node); + } + + public new Map.Entry<K,V> get () { + assert (iterator != null); + return Entry.entry_for<K,V> (iterator.current); + } + + public new void remove () { + unset (); + } + + public bool foreach (ForallFunc<Map.Entry<K, V>> f) { + if (valid) { + if (!f (Entry.entry_for<K,V> (iterator.current))) { + return false; + } + } + while (iterator.next ()) { + if (!f (Entry.entry_for<K,V> (iterator.current))) { + return false; + } + } + return true; } } - private class MapIterator<K,V> : NodeIterator<K,V>, Gee.MapIterator<K,V> { + private class MapIterator<K,V> : NodeIterator<K,V>, Gee.MapIterator<K,V>, BidirMapIterator<K,V> { public MapIterator (TreeMap<K,V> map) { base (map); } public K get_key () { assert (stamp == _map.stamp); - assert (current != null); + assert (valid); return current.key; } public V get_value () { assert (stamp == _map.stamp); - assert (current != null); + assert (valid); return current.value; } public void set_value (V value) { assert (stamp == _map.stamp); - assert (current != null); + assert (valid); current.value = value; } + + public override bool read_only { + get { + return false; + } + } + + public bool mutable { + get { + return true; + } + } + } + + private class SubMapIterator<K,V> : SubNodeIterator<K,V>, Gee.MapIterator<K,V>, BidirMapIterator<K,V> { + public SubMapIterator (TreeMap<K,V> map, Range<K,V> range) { + base (map, range); + } + + public K get_key () { + assert (valid); + return iterator.current.key; + } + + public V get_value () { + assert (valid); + return iterator.current.value; + } + + public void set_value (V value) { + assert (valid); + iterator.current.value = value; + } + + public override bool read_only { + get { + return false; + } + } + + public bool mutable { + get { + return true; + } + } } } |