11type 'a comparator = 'a -> 'a -> int
2- type settings = { branching_factor : int }
2+ type ref_type = Strong | Soft | Weak
3+ type settings = { branching_factor : int ; ref_type : ref_type }
34type 'a stored_node = Leaf of 'a list | Branch of 'a list * string list
45
56type 'a storage = {
@@ -53,7 +54,7 @@ let normalize_cmp cmp left right =
5354 match cmp left right with n when n < 0 -> - 1 | 0 -> 0 | _ -> 1
5455
5556let default_cmp left right = Stdlib. compare left right
56- let default_settings = { branching_factor = 32 }
57+ let default_settings = { branching_factor = 32 ; ref_type = Soft }
5758
5859let validate_settings settings =
5960 if settings.branching_factor < 2 then
@@ -62,7 +63,64 @@ let validate_settings settings =
6263
6364let settings set = set.set_settings
6465
66+ let cache_storage settings storage =
67+ let remember cache address node =
68+ let slot = Weak. create 1 in
69+ Weak. set slot 0 (Some node);
70+ Hashtbl. replace cache address slot
71+ in
72+ match settings.ref_type with
73+ | Strong ->
74+ let cache = Hashtbl. create 128 in
75+ {
76+ store_node =
77+ (fun node ->
78+ let address = storage.store_node node in
79+ Hashtbl. replace cache address node;
80+ address);
81+ restore_node =
82+ (fun address ->
83+ match Hashtbl. find_opt cache address with
84+ | Some node -> Some node
85+ | None ->
86+ (match storage.restore_node address with
87+ | Some node ->
88+ Hashtbl. replace cache address node;
89+ Some node
90+ | None -> None ));
91+ accessed = storage.accessed;
92+ }
93+ | Soft | Weak ->
94+ let cache = Hashtbl. create 128 in
95+ {
96+ store_node =
97+ (fun node ->
98+ let address = storage.store_node node in
99+ remember cache address node;
100+ address);
101+ restore_node =
102+ (fun address ->
103+ match Hashtbl. find_opt cache address with
104+ | Some slot -> (
105+ match Weak. get slot 0 with
106+ | Some node -> Some node
107+ | None -> (
108+ match storage.restore_node address with
109+ | Some node ->
110+ remember cache address node;
111+ Some node
112+ | None -> None ))
113+ | None -> (
114+ match storage.restore_node address with
115+ | Some node ->
116+ remember cache address node;
117+ Some node
118+ | None -> None ));
119+ accessed = storage.accessed;
120+ }
121+
65122let empty_with_cmp ?storage settings cmp =
123+ let storage = Option. map (cache_storage settings) storage in
66124 {
67125 cmp;
68126 set_settings = settings;
@@ -1893,7 +1951,7 @@ let restore ?(cmp = default_cmp) ?(settings = default_settings) storage address
18931951 {
18941952 cmp = normalize_cmp cmp;
18951953 set_settings = settings;
1896- set_storage = Some storage;
1954+ set_storage = Some (cache_storage settings storage) ;
18971955 data = Deferred { address };
18981956 count_cache = None ;
18991957 }
0 commit comments