Hashtbl cache with LRU expiration
A skeleton of a cache based on Hashtbl with LRU expiration
type data_t = Real of float array | Cplx of Complex.t array type cached_t = Room_t | Room_f | Smoothed | Wrapped | Unwrapped | GRD | Eq_minphase_t | Eq_minphase_f | Deconv1_t | Deconv1_f | Residue1_wrapped | Residue1_unwrapped | Residue1_GRD | Eq_allpass_t | Deconv2_t | Deconv2_f let timestamp_t = float let sweep_interval = 600. let last_sweep = ref 0. let src_serial = ref 0 let sid () = !src_serial let sincr () = incr src_serial let hcache = Hashtbl.create 16 let h_find (cache_id: cached_t) params = Hashtbl.find hcache (cache_id, sid (), params) let h_expire kh = let h_make_expire_list h = (* 1. construct a hashtbl with cache_id as sole elt of the keys, value being a list of timestamps *) let h_list = Hashtbl.create 16 in let build_len_list hlist k v = let cache_id, src_id, params = k in let ts, _ = v in let cid_list = try Hashtbl.find hlist cache_id with Not_found -> ( Hashtbl.add hlist cache_id []; [] ) in Hashtbl.replace hlist cache_id (ts :: cid_list) in Hashtbl.iter (build_len_list h_list) h ; (* 2. iter the h_list about lists lengths, thresholds *) let h_list_over = Hashtbl.create 16 in let thresholds_len_list hlist k v = let thresh = 5 in let ts_list = List.sort Pervasives.compare v in let llen = List.length ts_list in if llen > thresh then ( Hashtbl.add hlist k (BatList.take (llen-thresh) ts_list) ) in Hashtbl.iter (thresholds_len_list h_list_over) h_list ; (* should looks like cache_id as key, a timestamp (list) as value *) h_list_over in let expire k v = let cache_id, src_id, params = k in let ts, data = v in let expire_h = h_make_expire_list kh in let exp_list = try Hashtbl.find expire_h cache_id with Not_found -> [] in try if (List.exists (fun x -> x = ts) exp_list) then (Hashtbl.remove kh k) with Not_found -> () in Hashtbl.iter expire kh let h_add cache_id params (data: data_t) = let ts = Unix.gettimeofday () in if ts > (!last_sweep +. sweep_interval) then (h_expire hcache ; last_sweep := ts) ; Hashtbl.add hcache (cache_id, sid (), params) (ts, data) let () = h_add Room_t (25., 45., 14000., 20000.) (Real [|1.;2.;3.;4.;5.|]) ; let mydata = h_find Room_t (25., 45., 14000., 20000.) in ()