Summary: Merging the results directories of targets on buck projects involved creating symbolic links into buck-out. The bulk of files are .attr files: one per procedure. Creating these links can be a bottleneck, and the merge phase can be slower than the analysis phases on projects with many procedures. This diff introduces multilinks to speed up merge. A multilink is a file `multilink.txt` containing a sequence of paths ``` path/to/file1.ext path/to/file2.ext ... ``` A multilink file is a compact way to represent a link for each entry. This diff creates a multilink file for each `attributes/dir` directory, instead of one symbolic link for each file. Reviewed By: jberdine Differential Revision: D4067428 fbshipit-source-id: 911f8a9master
parent
a31658a9b8
commit
47c623ff51
@ -0,0 +1,68 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
open! Utils;
|
||||
|
||||
let module F = Format;
|
||||
|
||||
let module L = Logging;
|
||||
|
||||
let multilink_file_name = "multilink.txt";
|
||||
|
||||
type t = StringHash.t string;
|
||||
|
||||
let add multilinks fname => StringHash.replace multilinks (Filename.basename fname) fname;
|
||||
|
||||
let create () :t => StringHash.create 1;
|
||||
|
||||
/* Cache of multilinks files read from disk */
|
||||
let multilink_files_cache = StringHash.create 1;
|
||||
|
||||
let reset_cache () => StringHash.reset multilink_files_cache;
|
||||
|
||||
let read dir::dir :option t => {
|
||||
let multilink_fname = Filename.concat dir multilink_file_name;
|
||||
switch (Utils.read_file multilink_fname) {
|
||||
| None => None
|
||||
| Some lines =>
|
||||
let links = create ();
|
||||
IList.iter (fun line => StringHash.add links (Filename.basename line) line) lines;
|
||||
StringHash.add multilink_files_cache dir links;
|
||||
Some links
|
||||
}
|
||||
};
|
||||
|
||||
/* Write a multilink file in the given directory */
|
||||
let write multilinks dir::dir => {
|
||||
let fname = Filename.concat dir multilink_file_name;
|
||||
let outc = open_out fname;
|
||||
StringHash.iter (fun _ src => output_string outc (src ^ "\n")) multilinks;
|
||||
close_out outc
|
||||
};
|
||||
|
||||
let lookup dir::dir =>
|
||||
try (Some (StringHash.find multilink_files_cache dir)) {
|
||||
| Not_found => read dir::dir
|
||||
};
|
||||
|
||||
let resolve fname => {
|
||||
let fname_s = DB.filename_to_string fname;
|
||||
if (Sys.file_exists fname_s) {
|
||||
fname
|
||||
} else {
|
||||
let base = Filename.basename fname_s;
|
||||
let dir = Filename.dirname fname_s;
|
||||
switch (lookup dir::dir) {
|
||||
| None => fname
|
||||
| Some links =>
|
||||
try (DB.filename_from_string (StringHash.find links base)) {
|
||||
| Not_found => fname
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
@ -0,0 +1,47 @@
|
||||
/*
|
||||
* Copyright (c) 2015 - present Facebook, Inc.
|
||||
* All rights reserved.
|
||||
*
|
||||
* This source code is licensed under the BSD style license found in the
|
||||
* LICENSE file in the root directory of this source tree. An additional grant
|
||||
* of patent rights can be found in the PATENTS file in the same directory.
|
||||
*/
|
||||
open! Utils;
|
||||
|
||||
let module F = Format;
|
||||
|
||||
let module L = Logging;
|
||||
|
||||
|
||||
/** In-memory representation of multilink files. */
|
||||
type t;
|
||||
|
||||
|
||||
/** Add a link. */
|
||||
let add: t => string => unit;
|
||||
|
||||
|
||||
/** Create a new multilink. */
|
||||
let create: unit => t;
|
||||
|
||||
|
||||
/** Name of the multilink file.
|
||||
A multilink file is recognized by its file name. */
|
||||
let multilink_file_name: string;
|
||||
|
||||
|
||||
/** Read a multilink file from disk. */
|
||||
let read: dir::string => option t;
|
||||
|
||||
|
||||
/** Resolve a filename following multilinks.
|
||||
The cache is updated if a new multilinks file is read. */
|
||||
let resolve: DB.filename => DB.filename;
|
||||
|
||||
|
||||
/** Reset the cache of multilink files */
|
||||
let reset_cache: unit => unit;
|
||||
|
||||
|
||||
/** Write a multilink file in the given directory */
|
||||
let write: t => dir::string => unit;
|
Loading…
Reference in new issue