(*
Wojciech Muła, $Id: myhash.ml,v 1.3 2006-06-04 08:34:03 wojtek Exp $
*)
let itertop f hash =
let prev = ref None in
let aux key value =
let prev' = !prev in
begin
prev := Some key;
match prev' with
None -> f key value
| Some key' -> if key' <> key then f key value
end;
in
Hashtbl.iter aux hash
let foldtop f hash init =
let prev = ref None in
let aux key value acc =
let prev' = !prev in
begin
prev := Some key;
match prev' with
None -> f key value acc
| Some key' -> if key' <> key then
f key value acc
else
acc
end;
in
Hashtbl.fold aux hash init
let keys hash =
Hashtbl.fold (fun key value list -> key::list) hash []
let values hash =
Hashtbl.fold (fun key value list -> value::list) hash []
let items hash =
Hashtbl.fold (fun key value list -> (key,value)::list) hash []
let from_items2 l =
let h = ref (Hashtbl.create (List.length l)) in
let rec worker = function
| [] -> ()
| (k,v)::xs -> Hashtbl.add !h k v;
worker xs
in
worker l; !h
let from_items keys values =
let h = ref (Hashtbl.create (List.length keys)) in
let rec worker = function
| ([], []) -> ()
| (_ , []) -> failwith "from_items: v shorten then k"
| ([], _ ) -> failwith "from_items: k shorten then v"
| (k::ks, v::vs) -> Hashtbl.add !h k v;
worker (ks, vs)
in
worker (keys,values); !h
let findVariant h x =
try Some (Hashtbl.find h x) with Not_found -> None
let set_default h x d =
try
Hashtbl.find h x
with
Not_found -> Hashtbl.add h x d; d
let remove_all hash key =
let l = Hashtbl.find_all hash key in
let n = List.length l in
for i = 0 to n do
Hashtbl.remove hash key
done;
l
let replace_all hash key value =
let removed = remove_all hash key in
Hashtbl.add hash key value;
removed
let reverse_hash hash =
let i = items hash in
let i' = List.map (fun (k,v) -> (v,k)) i in
from_items2 i'