|
@@ -4,74 +4,38 @@ namespace Invercargill {
|
|
|
|
|
|
public class Dictionary<TKey, TValue> : Associative<TKey, TValue>, KeyValues<TKey, TValue> {
|
|
|
|
|
|
- private HashTable<TKey, TValue> hash_table;
|
|
|
-
|
|
|
- public Dictionary(HashFunc<TKey>? key_hash_func = null, EqualFunc<TKey>? key_equal_func = null) {
|
|
|
- var hash_func = key_hash_func;
|
|
|
- var equal_func = key_equal_func;
|
|
|
-
|
|
|
- var key_type = typeof(TKey);
|
|
|
- if(hash_func == null) {
|
|
|
- if(key_type == typeof(string)) {
|
|
|
- hash_func = GLib.str_hash;
|
|
|
- }
|
|
|
- else if(key_type == typeof(int64) || key_type == typeof(uint64)) {
|
|
|
- hash_func = GLib.int64_hash;
|
|
|
- }
|
|
|
- else if(key_type == typeof(int)) {
|
|
|
- hash_func = GLib.direct_hash;
|
|
|
- }
|
|
|
- else if(key_type == typeof(double)) {
|
|
|
- hash_func = GLib.double_hash;
|
|
|
- }
|
|
|
- else if(key_type.is_a(typeof(Hashable))) {
|
|
|
- hash_func = (k) => ((Hashable)k).hash_code();
|
|
|
- }
|
|
|
- }
|
|
|
- if(equal_func == null) {
|
|
|
- if(key_type == typeof(string)) {
|
|
|
- equal_func = GLib.str_equal;
|
|
|
- }
|
|
|
- else if(key_type == typeof(int64) || key_type == typeof(uint64)) {
|
|
|
- equal_func = GLib.int64_equal;
|
|
|
- }
|
|
|
- else if(key_type == typeof(int)) {
|
|
|
- equal_func = GLib.direct_equal;
|
|
|
- }
|
|
|
- else if(key_type == typeof(double)) {
|
|
|
- equal_func = GLib.double_equal;
|
|
|
- }
|
|
|
- else if(key_type.is_a(typeof(Equatable))) {
|
|
|
- equal_func = (a, b) => ((Equatable<TKey>)a).equals(b);
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
-
|
|
|
- hash_table = new HashTable<TKey, TValue>(hash_func, equal_func);
|
|
|
+ private HashTable<Key<TKey>, TValue> hash_table;
|
|
|
+ private EqualityDelegate<TKey> key_equal_delegate;
|
|
|
+ private HashDelegate<TKey> key_hash_delegate;
|
|
|
+
|
|
|
+ public Dictionary(HashDelegate<TKey>? key_hash_func = null, EqualityDelegate<TKey>? key_equal_func = null) {
|
|
|
+ key_hash_delegate = key_hash_func ?? Operators.hash<TKey>();
|
|
|
+ key_equal_delegate = key_equal_func ?? Operators.equality<TKey>();
|
|
|
+ hash_table = new HashTable<Key<TKey>, TValue>(Key.hash, Key.equal);
|
|
|
}
|
|
|
|
|
|
public override void @set (TKey key, TValue value) {
|
|
|
lock(hash_table) {
|
|
|
- hash_table.set (key, value);
|
|
|
+ hash_table.set (new Key<TKey>(this, key), value);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public override void set_all (Enumerable<KeyValuePair<TKey, TValue>> key_values) {
|
|
|
lock(hash_table) {
|
|
|
- key_values.iterate(kv => hash_table.set(kv.key, kv.value));
|
|
|
+ key_values.iterate(kv => hash_table.set(new Key<TKey>(this, kv.key), kv.value));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public override bool try_get (TKey key, out TValue value) {
|
|
|
lock(hash_table) {
|
|
|
TKey orig_key;
|
|
|
- return hash_table.lookup_extended (key, out orig_key, out value);
|
|
|
+ return hash_table.lookup_extended (new Key<TKey>(this, key), out orig_key, out value);
|
|
|
}
|
|
|
}
|
|
|
|
|
|
public override void clear (TKey key) {
|
|
|
lock(hash_table) {
|
|
|
- hash_table.remove(key);
|
|
|
+ hash_table.remove(new Key<TKey>(this, key));
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -80,14 +44,14 @@ namespace Invercargill {
|
|
|
}
|
|
|
public override bool has (TKey key) {
|
|
|
lock(hash_table) {
|
|
|
- return hash_table.contains (key);
|
|
|
+ return hash_table.contains (new Key<TKey>(this, key));
|
|
|
}
|
|
|
}
|
|
|
|
|
|
private class DictionaryTracker<TKey, TValue> : Tracker<KeyValuePair<TKey, TValue>> {
|
|
|
|
|
|
private Dictionary<TKey, TValue> dictionary;
|
|
|
- private (unowned TKey)[] keys;
|
|
|
+ private (unowned Key<TKey>)[] keys;
|
|
|
private int index;
|
|
|
|
|
|
public DictionaryTracker(Dictionary<TKey, TValue> dict) {
|
|
@@ -100,12 +64,30 @@ namespace Invercargill {
|
|
|
return index < keys.length;
|
|
|
}
|
|
|
public override KeyValuePair<TKey, TValue> get_next() {
|
|
|
- var key = keys[index];
|
|
|
+ var key = keys[index].key;
|
|
|
var item = dictionary.get_or_default(key);
|
|
|
index++;
|
|
|
return new KeyValuePair<TKey, TValue> (key, item);
|
|
|
}
|
|
|
|
|
|
}
|
|
|
+
|
|
|
+ private class Key<TKey> {
|
|
|
+ public Dictionary owner;
|
|
|
+ public TKey key;
|
|
|
+
|
|
|
+ public Key(Dictionary owner, TKey key) {
|
|
|
+ this.owner = owner;
|
|
|
+ this.key = key;
|
|
|
+ }
|
|
|
+
|
|
|
+ public bool equal(Key<TKey> other) {
|
|
|
+ return owner.key_equal_delegate(key, other.key);
|
|
|
+ }
|
|
|
+
|
|
|
+ public uint hash() {
|
|
|
+ return owner.key_hash_delegate(key);
|
|
|
+ }
|
|
|
+ }
|
|
|
}
|
|
|
}
|