import vector import map import io import serialize import util fun hash_map(): hash_map { var toRet.construct(): hash_map return toRet } fun hash_map(key:T, value:U): hash_map { var toRet.construct(): hash_map toRet.set(key, value) return toRet } obj hash_map (Object, Serializable) { var data: vector::vector> var size: int fun construct(): *hash_map { data.construct() data.add(map::map()) size = 0 /*io::print("Constructed hash_map, this: ")*/ /*io::println((this) cast int)*/ /*io::print("size of data:")*/ /*io::println(data.size)*/ return this } fun copy_construct(old: *hash_map) { data.copy_construct(&old->data) size = old->size /*io::print("Copy constructed hash_map, this: ")*/ /*io::println((this) cast int)*/ /*io::print("new size of data:")*/ /*io::println(data.size)*/ /*io::print("old size of data:")*/ /*io::println(old->data.size)*/ } fun operator=(rhs: hash_map) { destruct() copy_construct(&rhs) } fun destruct() { /*io::print("destructed hash_map, this: ")*/ /*io::println((this) cast int)*/ data.destruct() } fun serialize(): vector::vector { return serialize::serialize(data) + serialize::serialize(size) } fun unserialize(it: ref vector::vector, 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: T, value: U) { /*io::print("doing set! this:")*/ /*io::println((this) cast int)*/ /*io::print("size of data:")*/ /*io::println(data.size)*/ var key_hash = (util::hash(key)) cast int if (!data[key_hash%data.size].contains_key(key)) { size++ if (size > data.size) { /*io::print("rehashing to: ")*/ /*io::println(size*2)*/ var new_data = vector::vector>() 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)) cast int%new_data.size].set(key, value) }) data = new_data } } data[key_hash%data.size].set(key, value) } fun get(key: T): ref U { return data[(util::hash(key)) cast int%data.size].get(key) } fun contains_key(key: T): bool { return data[(util::hash(key)) cast int%data.size].contains_key(key) } fun contains_value(value: U): bool { for (var i = 0; i < data.size; i++;) { if (data[i].contains_value(value)) return true } return false } fun reverse_get(value: 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: T) { data[(util::hash(key)) cast int%data.size].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: T): ref U { return get(key) } fun operator[]=(key: T, value: U) { set(key,value) } fun get_with_default(key: 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()) } }