Skip to content

Commit 2e8eab0

Browse files
authored
Merge pull request #4435 from BuckleScript/compact_encoding
more compact encoding of .bsbuild [internal]
2 parents e945ea0 + d8981c4 commit 2e8eab0

19 files changed

+11622
-10808
lines changed

jscomp/bsb/bsb_db_encode.ml

Lines changed: 34 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ let nl buf =
4040
- not readable
4141
*)
4242

43-
let make_encoding length buf =
43+
let make_encoding length buf : Ext_buffer.t -> int -> unit =
4444
let max_range = length lsl 1 + 1 in
4545
if max_range <= 0xff then begin
4646
Ext_buffer.add_char buf '1';
@@ -62,41 +62,44 @@ let make_encoding length buf =
6262
they are only used to control the order.
6363
Strictly speaking, [tmp_buf1] is not needed
6464
*)
65-
let encode_single (db : Bsb_db.t) (buf : Ext_buffer.t) =
66-
nl buf ; (* module name section *)
65+
let encode_single (db : Bsb_db.map) (buf : Ext_buffer.t) =
66+
(* module name section *)
6767
let len = Map_string.cardinal db in
6868
Ext_buffer.add_string_char buf (string_of_int len) '\n';
69-
let mapping = Hash_string.create 50 in
70-
Map_string.iter db (fun name {dir} ->
71-
Ext_buffer.add_string_char buf name '\n';
72-
if not (Hash_string.mem mapping dir) then
73-
Hash_string.add mapping dir (Hash_string.length mapping)
74-
);
75-
let length = Hash_string.length mapping in
76-
let rev_mapping = Array.make length "" in
77-
Hash_string.iter mapping (fun k i -> Array.unsafe_set rev_mapping i k);
78-
(* directory name section *)
79-
Ext_array.iter rev_mapping (fun s -> Ext_buffer.add_string_char buf s '\t');
80-
nl buf; (* module name info section *)
81-
let len_encoding = make_encoding length buf in
82-
Map_string.iter db (fun _ module_info ->
83-
len_encoding buf
84-
(Hash_string.find_exn mapping module_info.dir lsl 1 + Obj.magic module_info.case ))
85-
86-
let encode (dbs : Bsb_db.ts) buf =
87-
88-
Ext_buffer.add_char_string buf '\n' (string_of_int (Array.length dbs));
89-
Ext_array.iter dbs (fun x -> encode_single x buf)
90-
69+
if len <> 0 then begin
70+
let mapping = Hash_string.create 50 in
71+
Map_string.iter db (fun name {dir} ->
72+
Ext_buffer.add_string_char buf name '\n';
73+
if not (Hash_string.mem mapping dir) then
74+
Hash_string.add mapping dir (Hash_string.length mapping)
75+
);
76+
let length = Hash_string.length mapping in
77+
let rev_mapping = Array.make length "" in
78+
Hash_string.iter mapping (fun k i -> Array.unsafe_set rev_mapping i k);
79+
(* directory name section *)
80+
Ext_array.iter rev_mapping (fun s -> Ext_buffer.add_string_char buf s '\t');
81+
nl buf; (* module name info section *)
82+
let len_encoding = make_encoding length buf in
83+
Map_string.iter db (fun _ module_info ->
84+
len_encoding buf
85+
(Hash_string.find_exn mapping module_info.dir lsl 1 + Obj.magic module_info.case ));
86+
nl buf
87+
end
88+
let encode (dbs : Bsb_db.t) buf =
89+
encode_single dbs.lib buf ;
90+
encode_single dbs.dev buf
91+
9192

92-
(* TODO: shall we avoid writing such file (checking the digest) *)
93-
let write_build_cache ~dir (bs_files : Bsb_db.ts) : string =
93+
(* shall we avoid writing such file (checking the digest)?
94+
It is expensive to start scanning the whole code base,
95+
we should we avoid it in the first place, if we do start scanning,
96+
this operation seems affordable
97+
*)
98+
let write_build_cache ~dir (bs_files : Bsb_db.t) : string =
9499
let oc = open_out_bin (Filename.concat dir bsbuild_cache) in
95100
let buf = Ext_buffer.create 100_000 in
96101
encode bs_files buf ;
97-
let digest = Ext_buffer.digest buf in
98-
let hex_digest = Digest.to_hex digest in
99-
output_string oc digest;
100102
Ext_buffer.output_buffer oc buf;
101103
close_out oc;
102-
hex_digest
104+
let digest = Ext_buffer.digest buf in
105+
Digest.to_hex digest

jscomp/bsb/bsb_db_encode.mli

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,5 +22,11 @@
2222
* along with this program; if not, write to the Free Software
2323
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
2424

25+
26+
val encode :
27+
Bsb_db.t ->
28+
Ext_buffer.t ->
29+
unit
30+
2531
val write_build_cache :
26-
dir:string -> Bsb_db.ts -> string
32+
dir:string -> Bsb_db.t -> string

jscomp/bsb/bsb_db_util.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323
* along with this program; if not, write to the Free Software
2424
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *)
2525
type module_info = Bsb_db.module_info
26-
type t = Bsb_db.t
26+
type t = Bsb_db.map
2727
(* type case = Bsb_db.case *)
2828

2929

jscomp/bsb/bsb_db_util.mli

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@ val conflict_module_info:
3232
'a
3333

3434

35-
val merge : Bsb_db.t -> Bsb_db.t -> Bsb_db.t
35+
val merge : Bsb_db.map -> Bsb_db.map -> Bsb_db.map
3636

37-
val sanity_check : Bsb_db.t -> unit
37+
val sanity_check : Bsb_db.map -> unit
3838

3939
(**
4040
Currently it is okay to have duplicated module,
@@ -43,7 +43,7 @@ val sanity_check : Bsb_db.t -> unit
4343

4444
val add_basename:
4545
dir:string ->
46-
Bsb_db.t ->
46+
Bsb_db.map ->
4747
?error_on_invalid_suffix:Ext_position.t->
4848
string ->
49-
Bsb_db.t
49+
Bsb_db.map

jscomp/bsb/bsb_file_groups.ml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type build_generator =
3737

3838
type file_group =
3939
{ dir : string ;
40-
sources : Bsb_db.t;
40+
sources : Bsb_db.map;
4141
resources : string list ;
4242
public : public ;
4343
dev_index : bool ;

jscomp/bsb/bsb_file_groups.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ type build_generator =
3737

3838
type file_group =
3939
{ dir : string ;
40-
sources : Bsb_db.t;
40+
sources : Bsb_db.map;
4141
resources : string list ;
4242
public : public ;
4343
dev_index : bool ; (* false means not in dev mode *)

jscomp/bsb/bsb_ninja_gen.ml

Lines changed: 36 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -161,35 +161,40 @@ let output_ninja_and_namespace_map
161161
(fun x -> x.package_install_path));
162162
Bsb_ninja_global_vars.g_ns , g_ns_flg ;
163163
|] oc
164-
in
165-
let bs_groups, bsc_lib_dirs, static_resources =
166-
(* number_of_dev_groups = 1 -- all devs share the same group *)
167-
let bs_groups = Array.init 2 (fun _ -> Map_string.empty) in
168-
let source_dirs = Array.init 2 (fun _ -> []) in
169-
let static_resources =
170-
Ext_list.fold_left bs_file_groups [] (fun (acc_resources : string list) {sources; dir; resources; dev_index}
171-
->
172-
let dir_index = if dev_index then 1 else 0 in
173-
bs_groups.(dir_index) <- Bsb_db_util.merge bs_groups.(dir_index) sources ;
174-
source_dirs.(dir_index) <- dir :: source_dirs.(dir_index);
175-
Ext_list.map_append resources acc_resources (fun x -> dir//x)
176-
) in
177-
let lib = bs_groups.(0) in
178-
Bsb_db_util.sanity_check lib;
179-
let c = bs_groups.(1) in
180-
Bsb_db_util.sanity_check c;
181-
Map_string.iter c
182-
(fun k a ->
183-
if Map_string.mem lib k then
184-
Bsb_db_util.conflict_module_info k a (Map_string.find_exn lib k)
185-
) ;
186-
Bsb_ninja_targets.output_kv
187-
Bsb_ninja_global_vars.g_dev_incls
188-
(Bsb_build_util.include_dirs source_dirs.(1)) oc
189-
;
190-
bs_groups,source_dirs.(0), static_resources
191-
in
192-
164+
in
165+
let bs_groups : Bsb_db.t = {lib = Map_string.empty; dev = Map_string.empty} in
166+
let source_dirs : string list Bsb_db.cat = {lib = []; dev = []} in
167+
let static_resources =
168+
Ext_list.fold_left
169+
bs_file_groups
170+
[] (
171+
fun
172+
(acc_resources : string list)
173+
{sources; dir; resources; dev_index}
174+
->
175+
if dev_index then begin
176+
bs_groups.dev <- Bsb_db_util.merge bs_groups.dev sources ;
177+
source_dirs.dev <- dir :: source_dirs.dev;
178+
end else begin
179+
bs_groups.lib <- Bsb_db_util.merge bs_groups.lib sources ;
180+
source_dirs.lib <- dir :: source_dirs.lib
181+
end;
182+
Ext_list.map_append resources acc_resources (fun x -> dir//x)
183+
) in
184+
let lib = bs_groups.lib in
185+
let dev = bs_groups.dev in
186+
Bsb_db_util.sanity_check lib;
187+
Bsb_db_util.sanity_check dev;
188+
Map_string.iter dev
189+
(fun k a ->
190+
if Map_string.mem lib k then
191+
Bsb_db_util.conflict_module_info k a (Map_string.find_exn lib k)
192+
) ;
193+
if source_dirs.dev <> [] then
194+
Bsb_ninja_targets.output_kv
195+
Bsb_ninja_global_vars.g_dev_incls
196+
(Bsb_build_util.include_dirs source_dirs.dev) oc
197+
;
193198
let digest = Bsb_db_encode.write_build_cache ~dir:cwd_lib_bs bs_groups in
194199
let rules : Bsb_ninja_rule.builtin =
195200
Bsb_ninja_rule.make_custom_rules
@@ -202,9 +207,8 @@ let output_ninja_and_namespace_map
202207
~reason_react_jsx
203208
~bs_suffix
204209
~digest
205-
generators in
206-
207-
emit_bsc_lib_includes bs_dependencies bsc_lib_dirs external_includes namespace oc;
210+
generators in
211+
emit_bsc_lib_includes bs_dependencies source_dirs.lib external_includes namespace oc;
208212
output_static_resources static_resources rules.copy_resources oc ;
209213
(** Generate build statement for each file *)
210214
Ext_list.iter bs_file_groups

jscomp/bsb/bsb_parse_sources.ml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ type cxt = {
6060
*)
6161
let collect_pub_modules
6262
(xs : Ext_json_types.t array)
63-
(cache : Bsb_db.t) : Set_string.t =
63+
(cache : Bsb_db.map) : Set_string.t =
6464
let set = ref Set_string.empty in
6565
for i = 0 to Array.length xs - 1 do
6666
let v = Array.unsafe_get xs i in
@@ -80,7 +80,7 @@ let collect_pub_modules
8080
done ;
8181
!set
8282

83-
let extract_pub (input : Ext_json_types.t Map_string.t) (cur_sources : Bsb_db.t) : Bsb_file_groups.public =
83+
let extract_pub (input : Ext_json_types.t Map_string.t) (cur_sources : Bsb_db.map) : Bsb_file_groups.public =
8484
match Map_string.find_opt input Bsb_build_schemas.public with
8585
| Some ((Str({str = s}) as x)) ->
8686
if s = Bsb_build_schemas.export_all then Export_all else

jscomp/bsb_helper/bsb_db_decode.ml

Lines changed: 41 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -25,47 +25,49 @@
2525
let bsbuild_cache = Literals.bsbuild_cache
2626

2727

28-
type group = {
29-
modules : string array ;
30-
dir_length : int;
31-
dir_info_offset : int ;
32-
module_info_offset : int;
33-
}
28+
type group =
29+
| Dummy
30+
| Group of {
31+
modules : string array ;
32+
dir_length : int;
33+
dir_info_offset : int ;
34+
module_info_offset : int;
35+
}
3436

35-
type t = group array * string (* string is whole content*)
37+
type t = {
38+
lib : group ;
39+
dev : group ;
40+
content : string (* string is whole content*)
41+
}
3642

3743

3844
type cursor = int ref
3945

4046

4147
(*TODO: special case when module_count is zero *)
42-
let rec decode_internal (x : string) (offset : cursor) =
43-
let len = Ext_pervasives.parse_nat_of_string x offset in
44-
incr offset;
45-
let first = decode_single x offset in
46-
if len = 1 then [|first|]
47-
else
48-
let result = Array.make len first in
49-
for i = 1 to len - 1 do
50-
Array.unsafe_set result i (decode_single x offset)
51-
done ;
52-
result
53-
48+
let rec decode (x : string) : t =
49+
let (offset : cursor) = ref 0 in
50+
let lib = decode_single x offset in
51+
let dev = decode_single x offset in
52+
{lib; dev; content = x}
53+
5454
and decode_single (x : string) (offset : cursor) : group =
5555
let module_number = Ext_pervasives.parse_nat_of_string x offset in
5656
incr offset;
57-
let modules = decode_modules x offset module_number in
58-
let dir_info_offset = !offset in
59-
let module_info_offset =
60-
String.index_from x dir_info_offset '\n' + 1 in
61-
let dir_length = Char.code x.[module_info_offset] - 48 (* Char.code '0'*) in
62-
offset :=
63-
module_info_offset +
64-
1 +
65-
dir_length * module_number +
66-
1
57+
if module_number <> 0 then begin
58+
let modules = decode_modules x offset module_number in
59+
let dir_info_offset = !offset in
60+
let module_info_offset =
61+
String.index_from x dir_info_offset '\n' + 1 in
62+
let dir_length = Char.code x.[module_info_offset] - 48 (* Char.code '0'*) in
63+
offset :=
64+
module_info_offset +
65+
1 +
66+
dir_length * module_number +
67+
1
6768
;
68-
{ modules ; dir_info_offset; module_info_offset ; dir_length}
69+
Group { modules ; dir_info_offset; module_info_offset ; dir_length}
70+
end else Dummy
6971
and decode_modules (x : string) (offset : cursor) module_number : string array =
7072
let result = Array.make module_number "" in
7173
let last = ref !offset in
@@ -91,7 +93,7 @@ and decode_modules (x : string) (offset : cursor) module_number : string array =
9193
let read_build_cache ~dir : t =
9294
let all_content =
9395
Ext_io.load_file (Filename.concat dir bsbuild_cache) in
94-
decode_internal all_content (ref (Ext_digest.length + 1)), all_content
96+
decode all_content
9597

9698

9799

@@ -102,11 +104,13 @@ type module_info = {
102104

103105

104106
let find_opt
105-
((sorteds,whole) : t )
106-
(i : int) (key : string)
107+
({content = whole} as db : t )
108+
lib (key : string)
107109
: module_info option =
108-
let group = sorteds.(i) in
109-
let i = Ext_string_array.find_sorted group.modules key in
110+
match if lib then db.lib else db.dev with
111+
| Dummy -> None
112+
| Group ({modules ;} as group) ->
113+
let i = Ext_string_array.find_sorted modules key in
110114
match i with
111115
| None -> None
112116
| Some count ->
@@ -132,10 +136,10 @@ let find_opt
132136
Some {case ; dir_name = String.sub whole dir_name_start (dir_name_finish - dir_name_start)}
133137

134138
let find db dependent_module is_not_lib_dir =
135-
let opt = find_opt db 0 dependent_module in
139+
let opt = find_opt db true dependent_module in
136140
match opt with
137141
| Some _ -> opt
138142
| None ->
139143
if is_not_lib_dir then
140-
find_opt db 1 dependent_module
144+
find_opt db false dependent_module
141145
else None

0 commit comments

Comments
 (0)