11type 'a comparator = 'a -> 'a -> int
22type ref_type = Strong | Weak
33type settings = { branching_factor : int ; ref_type : ref_type }
4- type 'a stored_node = Leaf of 'a list | Branch of 'a list * string list
4+ type 'a stored_node = Leaf of 'a array | Branch of 'a array * string array
55
66type 'a storage = {
77 store_node : 'a stored_node -> string ;
@@ -167,26 +167,25 @@ let fold_array_prefix f init values len =
167167 done ;
168168 ! acc
169169
170- let prepend_list values init =
171- List. fold_right (fun value acc -> value :: acc) values init
172-
173170let storage_required = function
174171 | Some storage -> storage
175172 | None -> invalid_arg " storage-backed node requires storage"
176173
177174let rec materialize_address_with storage address tail =
178175 match storage.restore_node address with
179- | Some (Leaf values ) -> prepend_list values (tail () )
176+ | Some (Leaf values ) -> prepend_array_prefix values ( Array. length values) (tail () )
180177 | Some (Branch (_ , child_addresses )) ->
181178 materialize_addresses_with storage child_addresses tail
182179 | None -> invalid_arg (" stored node not found: " ^ address)
183180
184181and materialize_addresses_with storage addresses tail =
185- match addresses with
186- | [] -> tail ()
187- | address :: rest ->
188- materialize_address_with storage address (fun () ->
189- materialize_addresses_with storage rest tail)
182+ let rec loop index =
183+ if index > = Array. length addresses then tail ()
184+ else
185+ materialize_address_with storage addresses.(index) (fun () ->
186+ loop (index + 1 ))
187+ in
188+ loop 0
190189
191190let materialize_address storage address =
192191 materialize_address_with storage address (fun () -> [] )
@@ -491,10 +490,8 @@ let find_child_index key_cmp value keys =
491490 if ! best < 0 then length - 1 else ! best
492491
493492let node_of_stored_branch keys child_addresses address =
494- if List . length keys <> List . length child_addresses then
493+ if Array . length keys <> Array . length child_addresses then
495494 invalid_arg " branch keys and addresses arity mismatch" ;
496- let keys = Array. of_list keys in
497- let child_addresses = Array. of_list child_addresses in
498495 let children =
499496 Array. mapi
500497 (fun index child_address ->
@@ -507,7 +504,6 @@ let node_of_stored_branch keys child_addresses address =
507504let node_of_stored_node storage address =
508505 match restore_stored_node storage address with
509506 | Leaf values ->
510- let values = Array. of_list values in
511507 Node. Leaf { values; len = Array. length values; address = Some address }
512508 | Branch (keys , child_addresses ) ->
513509 node_of_stored_branch keys child_addresses address
@@ -723,8 +719,8 @@ let rec add_to_address storage settings order_cmp equality_cmp key_cmp value
723719 add_to_node (Some storage) settings order_cmp equality_cmp key_cmp value
724720 (Node. Leaf
725721 {
726- values = Array. of_list values ;
727- len = List . length values;
722+ values;
723+ len = Array . length values;
728724 address = Some address;
729725 })
730726 | Branch (keys , child_addresses ) ->
@@ -764,8 +760,8 @@ let rec remove_from_address storage settings order_cmp equality_cmp key_cmp
764760 value
765761 (Node. Leaf
766762 {
767- values = Array. of_list values ;
768- len = List . length values;
763+ values;
764+ len = Array . length values;
769765 address = Some address;
770766 })
771767 | Branch (keys , child_addresses ) ->
@@ -1079,18 +1075,15 @@ type search_step = Found | Stop | Continue
10791075let rec search_deferred storage order_cmp equality_cmp value address =
10801076 match storage.restore_node address with
10811077 | Some (Leaf values ) ->
1082- let values = Array. of_list values in
10831078 let cmp = total_cmp order_cmp equality_cmp in
10841079 if array_mem_by_cmp cmp value values then Found
10851080 else
10861081 let length = Array. length values in
10871082 if length > 0 && order_cmp value values.(length - 1 ) < = 0 then Stop
10881083 else Continue
10891084 | Some (Branch (keys , child_addresses )) -> (
1090- if List . length keys <> List . length child_addresses then
1085+ if Array . length keys <> Array . length child_addresses then
10911086 invalid_arg " branch keys and addresses arity mismatch" ;
1092- let keys = Array. of_list keys in
1093- let child_addresses = Array. of_list child_addresses in
10941087 let key_cmp = route_cmp order_cmp equality_cmp in
10951088 let child_address =
10961089 let length = Array. length keys in
@@ -1136,9 +1129,9 @@ let mem value set =
11361129
11371130let rec fold_address storage f init address =
11381131 match storage.restore_node address with
1139- | Some (Leaf values ) -> List . fold_left f init values
1132+ | Some (Leaf values ) -> Array . fold_left f init values
11401133 | Some (Branch (_ , child_addresses )) ->
1141- List . fold_left
1134+ Array . fold_left
11421135 (fun acc child_address -> fold_address storage f acc child_address)
11431136 init child_addresses
11441137 | None -> invalid_arg (" stored node not found: " ^ address)
@@ -1190,20 +1183,6 @@ let child_after_range cmp to_ previous_child_max =
11901183 | Some to_ , Some previous_child_max -> cmp previous_child_max to_ > 0
11911184 | _ -> false
11921185
1193- let slice_values cmp from_ to_ values =
1194- values
1195- |> List. filter (fun value ->
1196- lower_ok cmp from_ value && upper_ok cmp to_ value)
1197-
1198- let reverse_slice_values cmp from_ to_ values =
1199- values |> List. rev
1200- |> List. filter (fun value ->
1201- match (from_, to_) with
1202- | None , None -> true
1203- | Some from_ , None -> cmp value from_ < = 0
1204- | None , Some to_ -> cmp value to_ > = 0
1205- | Some from_ , Some to_ -> cmp value from_ < = 0 && cmp value to_ > = 0 )
1206-
12071186let slice_array_into_len cmp from_ to_ values len acc =
12081187 let rec loop acc index =
12091188 if index > = len then acc
@@ -1238,23 +1217,23 @@ let reverse_slice_array_into_len cmp from_ to_ values len acc =
12381217let rec slice_deferred_into storage cmp from_ to_ address acc =
12391218 match storage.restore_node address with
12401219 | Some (Leaf values ) ->
1241- List. rev_append (slice_values cmp from_ to_ values) acc
1220+ slice_array_into_len cmp from_ to_ values ( Array. length values) acc
12421221 | Some (Branch (keys , child_addresses )) ->
1243- let rec collect previous_key acc keys child_addresses =
1244- match ( keys, child_addresses) with
1245- | [] , [] -> acc
1246- | key :: keys , child_address :: child_addresses ->
1247- if child_after_range cmp to_ previous_key then acc
1248- else if child_before_range cmp from_ key then
1249- collect ( Some key) acc keys child_addresses
1250- else
1251- collect ( Some key)
1252- (slice_deferred_into storage cmp from_ to_ child_address acc)
1253- keys child_addresses
1254- | [] , _ :: _ | _ :: _ , [] ->
1255- invalid_arg " branch keys and addresses arity mismatch "
1222+ if Array. length keys <> Array. length child_addresses then
1223+ invalid_arg " branch keys and addresses arity mismatch " ;
1224+ let rec collect index previous_key acc =
1225+ if index > = Array. length keys then acc
1226+ else
1227+ let key = keys.(index) in
1228+ let child_address = child_addresses.(index) in
1229+ if child_after_range cmp to_ previous_key then acc
1230+ else if child_before_range cmp from_ key then
1231+ collect (index + 1 ) ( Some key) acc
1232+ else
1233+ collect (index + 1 ) ( Some key)
1234+ (slice_deferred_into storage cmp from_ to_ child_address acc)
12561235 in
1257- collect None acc keys child_addresses
1236+ collect 0 None acc
12581237 | None -> invalid_arg (" stored node not found: " ^ address)
12591238
12601239let slice_deferred storage cmp from_ to_ address =
@@ -1263,30 +1242,31 @@ let slice_deferred storage cmp from_ to_ address =
12631242let rec reverse_slice_deferred_into storage cmp from_ to_ address acc =
12641243 match storage.restore_node address with
12651244 | Some (Leaf values ) ->
1266- List. rev_append (reverse_slice_values cmp from_ to_ values) acc
1245+ reverse_slice_array_into_len cmp from_ to_ values (Array. length values)
1246+ acc
12671247 | Some (Branch (keys , child_addresses )) ->
1268- let rec collect previous_key keys child_addresses acc =
1269- match ( keys, child_addresses) with
1270- | [] , [] -> acc
1271- | key :: keys , child_address :: child_addresses ->
1272- let acc = collect ( Some key) keys child_addresses acc in
1273- let child_above_range =
1274- match (from_, previous_key) with
1275- | Some from_ , Some previous_key -> cmp previous_key from_ > 0
1276- | _ -> false
1277- in
1278- let child_below_range =
1279- match to_ with Some to_ -> cmp key to_ < 0 | None -> false
1280- in
1281- if child_above_range then acc
1282- else if child_below_range then acc
1283- else
1284- reverse_slice_deferred_into storage cmp from_ to_ child_address
1285- acc
1286- | [] , _ :: _ | _ :: _ , [] ->
1287- invalid_arg " branch keys and addresses arity mismatch "
1248+ if Array. length keys <> Array. length child_addresses then
1249+ invalid_arg " branch keys and addresses arity mismatch " ;
1250+ let rec collect index previous_key acc =
1251+ if index > = Array. length keys then acc
1252+ else
1253+ let key = keys.(index) in
1254+ let child_address = child_addresses.(index) in
1255+ let acc = collect (index + 1 ) ( Some key) acc in
1256+ let child_above_range =
1257+ match (from_, previous_key) with
1258+ | Some from_ , Some previous_key -> cmp previous_key from_ > 0
1259+ | _ -> false
1260+ in
1261+ let child_below_range =
1262+ match to_ with Some to_ -> cmp key to_ < 0 | None -> false
1263+ in
1264+ if child_above_range then acc
1265+ else if child_below_range then acc
1266+ else
1267+ reverse_slice_deferred_into storage cmp from_ to_ child_address acc
12881268 in
1289- collect None keys child_addresses acc
1269+ collect 0 None acc
12901270 | None -> invalid_arg (" stored node not found: " ^ address)
12911271
12921272let reverse_slice_deferred storage cmp from_ to_ address =
@@ -1443,21 +1423,17 @@ let upper_bound_index_len cmp upper values length =
14431423 ! low - 1
14441424
14451425let cursor_children_of_addresses keys child_addresses =
1446- if List . length keys <> List . length child_addresses then
1426+ if Array . length keys <> Array . length child_addresses then
14471427 invalid_arg " branch keys and addresses arity mismatch" ;
1448- ( Array. of_list keys,
1449- child_addresses
1450- |> List. map (fun address -> Cursor_address address)
1451- |> Array. of_list )
1428+ ( keys,
1429+ Array. map (fun address -> Cursor_address address) child_addresses )
14521430
14531431let cursor_children_of_nodes children =
14541432 Array. map (fun child -> Cursor_node child) children
14551433
14561434let restore_cursor_child storage address =
14571435 match storage.restore_node address with
1458- | Some (Leaf values ) ->
1459- let values = Array. of_list values in
1460- `Leaf (values, Array. length values)
1436+ | Some (Leaf values ) -> `Leaf (values, Array. length values)
14611437 | Some (Branch (keys , child_addresses )) ->
14621438 let keys, children = cursor_children_of_addresses keys child_addresses in
14631439 `Branch (keys, children)
@@ -1815,7 +1791,9 @@ let seek key (seq : 'a seq) =
18151791 in
18161792 { seq with lower; upper }
18171793
1818- let split_branch_refs refs = List. split refs
1794+ let split_branch_refs refs =
1795+ let keys, child_addresses = List. split refs in
1796+ (Array. of_list keys, Array. of_list child_addresses)
18191797
18201798let branch_key refs =
18211799 match last refs with
@@ -1847,9 +1825,7 @@ let rec store_node_tree storage settings = function
18471825 | Node. Ref { address; _ } -> (address, [ address ])
18481826 | Node. Leaf { address = Some address ; _ } -> (address, [ address ])
18491827 | Node. Leaf { values; len; address = None ; _ } ->
1850- let address =
1851- storage.store_node (Leaf (array_prefix_to_list values len))
1852- in
1828+ let address = storage.store_node (Leaf (Array. sub values 0 len)) in
18531829 (address, [ address ])
18541830 | Node. Branch { address = Some address ; _ } -> (address, [ address ])
18551831 | Node. Branch { keys; children; address = None ; _ } ->
@@ -1886,7 +1862,7 @@ let store set =
18861862 let address, _addresses = store_node_tree storage set.set_settings root in
18871863 (address, stored_set address)
18881864 | Empty ->
1889- let address = storage.store_node (Leaf [] ) in
1865+ let address = storage.store_node (Leaf [|| ]) in
18901866 (address, stored_set address)
18911867
18921868let restore ?count ?(cmp = default_cmp) ?(settings = default_settings) storage
0 commit comments