(* Encapsulate the attribute/value list type used by Debian.read_packages, Debian.parse_control_text, Psql.avl_of_tuple, etc. *) (* type t = (string * string) list let create _ = [] let find = List.assoc let remove = List.remove_assoc let add avl key value = (key, value) :: avl let replace avl key value = (key, value) :: (remove key avl) *) (* Reference based version *) (* type t = (string * string) list ref let create _ = ref [] let find key avl = List.assoc key !avl let remove key avl = avl := List.remove_assoc key !avl let add avl key value = avl := (key, value) :: !avl let replace avl key value = avl := (key, value) :: List.remove_assoc key !avl *) (* Hash table base version *) type t = (string, string) Hashtbl.t let create n = Hashtbl.create n let find key avl = Hashtbl.find avl key let remove key avl = Hashtbl.remove avl key let add avl key value = Hashtbl.add avl key value let unset key avl = Hashtbl.remove avl key let replace avl key value = Hashtbl.replace avl key value let addret avl key value = Hashtbl.add avl key value; avl let replret avl key value = Hashtbl.replace avl key value; avl let iter = Hashtbl.iter let to_list avl = let lst = ref [] in Hashtbl.iter (fun attr value -> lst := (attr, value) :: !lst) avl; !lst let of_list pairs = let avl = create (List.length pairs) in List.iter (fun (a, v) -> add avl a v) pairs; avl let filter pred avl = let nu = create 50 in Hashtbl.iter (fun attr value -> if pred (attr, value) then add nu attr value) avl; nu let merge a b = let c = Hashtbl.create 50 in Hashtbl.iter (fun attr value -> add c attr value) a; Hashtbl.iter (fun attr value -> replace c attr value) b; c (* Derived *) let search attr avls = let rec loop avls = match avls with [] -> raise Not_found | avl :: etc -> try find attr avl with Not_found -> loop etc in loop avls