12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849(* Any user-defined storage implementation must have at least these three methods *)moduletypeSTORAGE_UNIT=sigtypettypevalue(* (string * config * float) *)(* All storage mechanisms want to be sure that old data is cleared out eventually *)valttl:float(* When implementing this interface, I recommend doing a clean out of stale values in get *)valget:string->(value*float)optionvalremove:string->unitvalupdate:string->value->unitendmoduletypeSTORAGE_KIND=sigtypevaluevalttl:floatendmoduleMakeInMemoryStorage(V:STORAGE_KIND):STORAGE_UNITwithtypevalue=V.value=structtypevalue=V.valuetypestored=(value*float)typet=(string,stored)Hashtbl.tletttl=V.ttlletstore=Hashtbl.create100letis_expired(_value,created_at)=Unix.time()-.created_at>V.ttlletclean()=Hashtbl.filter_map_inplace(fun_keyv->ifis_expiredvthenNoneelseSomev)store(* Due to sealing, only the below methods are publicly accessible *)letgetstate=clean();Hashtbl.find_optstorestateletremovestate=Hashtbl.removestorestateletupdatestatevalue=Hashtbl.replacestorestate(value,Unix.time())end