package kappa-library
Source file hashed_list.ml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117module type Hash = sig type hashed_list type elt type cache val int_of_hashed_list : hashed_list -> int val compare : hashed_list -> hashed_list -> int val init : unit -> cache val hash : cache -> elt list -> cache * hashed_list val cons : cache -> elt -> hashed_list -> cache * hashed_list val empty : hashed_list val print : Format.formatter -> hashed_list -> unit val print_cache : Format.formatter -> cache -> unit end module Make = functor (A : SetMap.OrderedType) -> struct type elt = A.t type elt_id = int type hashed_list = int let int_of_hashed_list (h : hashed_list) : int = h let compare = compare module SetMap = SetMap.Make (A) type cache = { dictionary: elt_id SetMap.Map.t; next_elt_id: elt_id; cons: hashed_list option Mods.DynArray.t option Mods.DynArray.t; next_list_id: hashed_list; } let fst_elt_id = 1 let next_elt_id = succ let fresh_elt_id cache = ( cache.next_elt_id, { cache with next_elt_id = next_elt_id cache.next_elt_id } ) let fst_list_id = 1 let next_list_id = succ let fresh_list_id cache = ( { cache with next_list_id = next_list_id cache.next_list_id }, cache.next_list_id ) let init () = { dictionary = SetMap.Map.empty; next_elt_id = fst_elt_id; cons = Mods.DynArray.create 0 None; next_list_id = fst_list_id; } let empty = 0 let hash_elt cache elt = match SetMap.Map.find_option elt cache.dictionary with | Some i -> cache, i | None -> let id, cache = fresh_elt_id cache in { cache with dictionary = SetMap.Map.add elt id cache.dictionary }, id let cons cache head tail = let cache, hash_head = hash_elt cache head in let subtab = match Mods.DynArray.get cache.cons hash_head with | Some subtab -> subtab | None -> let subtab = Mods.DynArray.create 0 None in let () = Mods.DynArray.set cache.cons hash_head (Some subtab) in subtab in match Mods.DynArray.get subtab tail with | Some hash -> cache, hash | None -> let cache, hash = fresh_list_id cache in let () = Mods.DynArray.set subtab tail (Some hash) in cache, hash let rec hash cache list = match list with | [] -> cache, empty | h :: t -> let cache, t = hash cache t in cons cache h t let print formatter = Format.fprintf formatter "%i" let print_cache formatter cache = let () = Format.fprintf formatter "Cache\n next_fresh_list_id: %i; next_fresh_elt_id: %i\n" cache.next_list_id cache.next_elt_id in let () = SetMap.Map.iter (fun a i -> Format.fprintf formatter "DIC:%a:%i\n" A.print a i) cache.dictionary in Mods.DynArray.iteri (fun a opt -> match opt with | None -> () | Some opt -> Mods.DynArray.iteri (fun b k -> match k with | None -> () | Some k -> Format.fprintf formatter "(%i,%i)->%i \n" a b k) opt) cache.cons end