import vec import map import io import serialize import util fun hash_map(): hash_map { var toRet.construct(): hash_map return toRet } fun hash_map(key: ref T, value: ref U): hash_map { var toRet.construct(): hash_map toRet.set(key, value) return toRet } obj hash_map (Object, Serializable) { var data: vec::vec> var size: int fun construct(): *hash_map { data.construct() data.add(map::map()) size = 0 return this } fun copy_construct(old: *hash_map) { data.copy_construct(&old->data) size = old->size } fun operator=(rhs: ref hash_map) { data = rhs.data size = rhs.size } fun destruct() { data.destruct() } fun serialize(): vec::vec { return serialize::serialize(data) + serialize::serialize(size) } fun unserialize(it: ref vec::vec, pos: int): int { pos = data.unserialize(it, pos) util::unpack(size, pos) = serialize::unserialize(it, pos) return pos } // the old unnecessary template to prevent generation // if not used trick (in this case, changing out U with V) fun operator==(other: ref hash_map): bool { return data == other.data } fun set(key: ref T, value: ref U) { var key_hash = util::hash(key) if (!data[(key_hash%data.size) cast int].contains_key(key)) { size++ if (size > data.size) { var new_data.construct(size*2): vec::vec> for (var i = 0; i < size*2; i++;) new_data.addEnd(map::map()) for_each(fun(key: T, value: U) { new_data[(util::hash(key)%new_data.size) cast int].set(key, value) }) data.swap(new_data) } } data[(key_hash%data.size) cast int].set(key, value) } fun get(key: ref T): ref U { return data[(util::hash(key)%data.size) cast int].get(key) } fun get_ptr_or_null(key: ref T): *U { return data[(util::hash(key)%data.size) cast int].get_ptr_or_null(key) } fun contains_key(key: ref T): bool { return data[(util::hash(key)%data.size) cast int].contains_key(key) } fun contains_value(value: ref U): bool { for (var i = 0; i < data.size; i++;) { if (data[i].contains_value(value)) return true } return false } fun reverse_get(value: ref U): ref T { for (var i = 0; i < data.size; i++;) { if (data[i].contains_value(value)) return data[i].reverse_get(value) } io::println("trying to reverse get a value that is not in the hash_map") } fun remove(key: ref T) { data[(util::hash(key)%data.size) cast int].remove(key) } fun for_each(func: fun(T, U):void) { for (var i = 0; i < data.size; i++;) data[i].for_each(func) } fun operator[](key: ref T): ref U { return get(key) } fun operator[]=(key: ref T, value: ref U) { set(key,value) } fun get_with_default(key: ref T, default_val: ref U): ref U { if (contains_key(key)) return get(key) return default_val } fun clear() { data.clear() size = 0 data.add(map::map()) } }