mirror of
https://github.com/denoland/deno.git
synced 2025-01-08 07:08:27 -05:00
perf(check): faster source hashing (#18534)
This commit is contained in:
parent
94d8ac598c
commit
f981becf3e
3 changed files with 32 additions and 48 deletions
|
@ -89,10 +89,12 @@ pub fn check(
|
||||||
// to make tsc build info work, we need to consistently hash modules, so that
|
// to make tsc build info work, we need to consistently hash modules, so that
|
||||||
// tsc can better determine if an emit is still valid or not, so we provide
|
// tsc can better determine if an emit is still valid or not, so we provide
|
||||||
// that data here.
|
// that data here.
|
||||||
let hash_data = vec![
|
let hash_data = {
|
||||||
options.ts_config.as_bytes(),
|
let mut hasher = FastInsecureHasher::new();
|
||||||
version::deno().as_bytes().to_owned(),
|
hasher.write(&options.ts_config.as_bytes());
|
||||||
];
|
hasher.write_str(version::deno());
|
||||||
|
hasher.finish()
|
||||||
|
};
|
||||||
|
|
||||||
let response = tsc::exec(tsc::Request {
|
let response = tsc::exec(tsc::Request {
|
||||||
config: options.ts_config,
|
config: options.ts_config,
|
||||||
|
|
|
@ -625,7 +625,7 @@ delete Object.prototype.__proto__;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
createHash(data) {
|
createHash(data) {
|
||||||
return ops.op_create_hash({ data }).hash;
|
return ops.op_create_hash(data);
|
||||||
},
|
},
|
||||||
|
|
||||||
// LanguageServiceHost
|
// LanguageServiceHost
|
||||||
|
|
|
@ -2,6 +2,7 @@
|
||||||
|
|
||||||
use crate::args::TsConfig;
|
use crate::args::TsConfig;
|
||||||
use crate::args::TypeCheckMode;
|
use crate::args::TypeCheckMode;
|
||||||
|
use crate::cache::FastInsecureHasher;
|
||||||
use crate::node;
|
use crate::node;
|
||||||
use crate::node::node_resolve_npm_reference;
|
use crate::node::node_resolve_npm_reference;
|
||||||
use crate::node::NodeResolution;
|
use crate::node::NodeResolution;
|
||||||
|
@ -241,15 +242,16 @@ fn get_lazily_loaded_asset(asset: &str) -> Option<&'static str> {
|
||||||
|
|
||||||
fn get_maybe_hash(
|
fn get_maybe_hash(
|
||||||
maybe_source: Option<&str>,
|
maybe_source: Option<&str>,
|
||||||
hash_data: &[Vec<u8>],
|
hash_data: u64,
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
if let Some(source) = maybe_source {
|
maybe_source.map(|source| get_hash(source, hash_data))
|
||||||
let mut data = vec![source.as_bytes().to_owned()];
|
|
||||||
data.extend_from_slice(hash_data);
|
|
||||||
Some(checksum::gen(&data))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn get_hash(source: &str, hash_data: u64) -> String {
|
||||||
|
let mut hasher = FastInsecureHasher::new();
|
||||||
|
hasher.write_str(source);
|
||||||
|
hasher.write_u64(hash_data);
|
||||||
|
hasher.finish().to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash the URL so it can be sent to `tsc` in a supportable way
|
/// Hash the URL so it can be sent to `tsc` in a supportable way
|
||||||
|
@ -303,7 +305,7 @@ pub struct Request {
|
||||||
/// Indicates to the tsc runtime if debug logging should occur.
|
/// Indicates to the tsc runtime if debug logging should occur.
|
||||||
pub debug: bool,
|
pub debug: bool,
|
||||||
pub graph: Arc<ModuleGraph>,
|
pub graph: Arc<ModuleGraph>,
|
||||||
pub hash_data: Vec<Vec<u8>>,
|
pub hash_data: u64,
|
||||||
pub maybe_npm_resolver: Option<NpmPackageResolver>,
|
pub maybe_npm_resolver: Option<NpmPackageResolver>,
|
||||||
pub maybe_tsbuildinfo: Option<String>,
|
pub maybe_tsbuildinfo: Option<String>,
|
||||||
/// A vector of strings that represent the root/entry point modules for the
|
/// A vector of strings that represent the root/entry point modules for the
|
||||||
|
@ -324,7 +326,7 @@ pub struct Response {
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
struct State {
|
struct State {
|
||||||
hash_data: Vec<Vec<u8>>,
|
hash_data: u64,
|
||||||
graph: Arc<ModuleGraph>,
|
graph: Arc<ModuleGraph>,
|
||||||
maybe_tsbuildinfo: Option<String>,
|
maybe_tsbuildinfo: Option<String>,
|
||||||
maybe_response: Option<RespondArgs>,
|
maybe_response: Option<RespondArgs>,
|
||||||
|
@ -337,7 +339,7 @@ struct State {
|
||||||
impl State {
|
impl State {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
graph: Arc<ModuleGraph>,
|
graph: Arc<ModuleGraph>,
|
||||||
hash_data: Vec<Vec<u8>>,
|
hash_data: u64,
|
||||||
maybe_npm_resolver: Option<NpmPackageResolver>,
|
maybe_npm_resolver: Option<NpmPackageResolver>,
|
||||||
maybe_tsbuildinfo: Option<String>,
|
maybe_tsbuildinfo: Option<String>,
|
||||||
root_map: HashMap<String, ModuleSpecifier>,
|
root_map: HashMap<String, ModuleSpecifier>,
|
||||||
|
@ -364,23 +366,10 @@ fn normalize_specifier(
|
||||||
resolve_url_or_path(specifier, current_dir).map_err(|err| err.into())
|
resolve_url_or_path(specifier, current_dir).map_err(|err| err.into())
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
|
||||||
#[serde(rename_all = "camelCase")]
|
|
||||||
struct CreateHashArgs {
|
|
||||||
/// The string data to be used to generate the hash. This will be mixed with
|
|
||||||
/// other state data in Deno to derive the final hash.
|
|
||||||
data: String,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[op]
|
#[op]
|
||||||
fn op_create_hash(s: &mut OpState, args: Value) -> Result<Value, AnyError> {
|
fn op_create_hash(s: &mut OpState, text: &str) -> String {
|
||||||
let state = s.borrow_mut::<State>();
|
let state = s.borrow_mut::<State>();
|
||||||
let v: CreateHashArgs = serde_json::from_value(args)
|
get_hash(text, state.hash_data)
|
||||||
.context("Invalid request from JavaScript for \"op_create_hash\".")?;
|
|
||||||
let mut data = vec![v.data.as_bytes().to_owned()];
|
|
||||||
data.extend_from_slice(&state.hash_data);
|
|
||||||
let hash = checksum::gen(&data);
|
|
||||||
Ok(json!({ "hash": hash }))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Deserialize)]
|
#[derive(Debug, Deserialize)]
|
||||||
|
@ -455,7 +444,7 @@ fn op_load(state: &mut OpState, args: Value) -> Result<Value, AnyError> {
|
||||||
Some(Cow::Borrowed("declare const __: any;\nexport = __;\n"))
|
Some(Cow::Borrowed("declare const __: any;\nexport = __;\n"))
|
||||||
} else if let Some(name) = v.specifier.strip_prefix("asset:///") {
|
} else if let Some(name) = v.specifier.strip_prefix("asset:///") {
|
||||||
let maybe_source = get_lazily_loaded_asset(name);
|
let maybe_source = get_lazily_loaded_asset(name);
|
||||||
hash = get_maybe_hash(maybe_source, &state.hash_data);
|
hash = get_maybe_hash(maybe_source, state.hash_data);
|
||||||
media_type = MediaType::from_str(&v.specifier);
|
media_type = MediaType::from_str(&v.specifier);
|
||||||
maybe_source.map(Cow::Borrowed)
|
maybe_source.map(Cow::Borrowed)
|
||||||
} else {
|
} else {
|
||||||
|
@ -507,7 +496,7 @@ fn op_load(state: &mut OpState, args: Value) -> Result<Value, AnyError> {
|
||||||
media_type = MediaType::Unknown;
|
media_type = MediaType::Unknown;
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
hash = get_maybe_hash(maybe_source.as_deref(), &state.hash_data);
|
hash = get_maybe_hash(maybe_source.as_deref(), state.hash_data);
|
||||||
maybe_source
|
maybe_source
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -902,12 +891,12 @@ mod tests {
|
||||||
|
|
||||||
async fn setup(
|
async fn setup(
|
||||||
maybe_specifier: Option<ModuleSpecifier>,
|
maybe_specifier: Option<ModuleSpecifier>,
|
||||||
maybe_hash_data: Option<Vec<Vec<u8>>>,
|
maybe_hash_data: Option<u64>,
|
||||||
maybe_tsbuildinfo: Option<String>,
|
maybe_tsbuildinfo: Option<String>,
|
||||||
) -> OpState {
|
) -> OpState {
|
||||||
let specifier = maybe_specifier
|
let specifier = maybe_specifier
|
||||||
.unwrap_or_else(|| ModuleSpecifier::parse("file:///main.ts").unwrap());
|
.unwrap_or_else(|| ModuleSpecifier::parse("file:///main.ts").unwrap());
|
||||||
let hash_data = maybe_hash_data.unwrap_or_else(|| vec![b"".to_vec()]);
|
let hash_data = maybe_hash_data.unwrap_or(0);
|
||||||
let fixtures = test_util::testdata_path().join("tsc2");
|
let fixtures = test_util::testdata_path().join("tsc2");
|
||||||
let mut loader = MockLoader { fixtures };
|
let mut loader = MockLoader { fixtures };
|
||||||
let mut graph = ModuleGraph::default();
|
let mut graph = ModuleGraph::default();
|
||||||
|
@ -933,7 +922,7 @@ mod tests {
|
||||||
async fn test_exec(
|
async fn test_exec(
|
||||||
specifier: &ModuleSpecifier,
|
specifier: &ModuleSpecifier,
|
||||||
) -> Result<Response, AnyError> {
|
) -> Result<Response, AnyError> {
|
||||||
let hash_data = vec![b"something".to_vec()];
|
let hash_data = 123; // something random
|
||||||
let fixtures = test_util::testdata_path().join("tsc2");
|
let fixtures = test_util::testdata_path().join("tsc2");
|
||||||
let mut loader = MockLoader { fixtures };
|
let mut loader = MockLoader { fixtures };
|
||||||
let mut graph = ModuleGraph::default();
|
let mut graph = ModuleGraph::default();
|
||||||
|
@ -999,16 +988,9 @@ mod tests {
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn test_create_hash() {
|
async fn test_create_hash() {
|
||||||
let mut state = setup(None, Some(vec![b"something".to_vec()]), None).await;
|
let mut state = setup(None, Some(123), None).await;
|
||||||
let actual = op_create_hash::call(
|
let actual = op_create_hash::call(&mut state, "some sort of content");
|
||||||
&mut state,
|
assert_eq!(actual, "11905938177474799758");
|
||||||
json!({ "data": "some sort of content" }),
|
|
||||||
)
|
|
||||||
.expect("could not invoke op");
|
|
||||||
assert_eq!(
|
|
||||||
actual,
|
|
||||||
json!({"hash": "ae92df8f104748768838916857a1623b6a3c593110131b0a00f81ad9dac16511"})
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
@ -1050,12 +1032,12 @@ mod tests {
|
||||||
&mut state,
|
&mut state,
|
||||||
json!({ "specifier": "https://deno.land/x/mod.ts"}),
|
json!({ "specifier": "https://deno.land/x/mod.ts"}),
|
||||||
)
|
)
|
||||||
.expect("should have invoked op");
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
actual,
|
actual,
|
||||||
json!({
|
json!({
|
||||||
"data": "console.log(\"hello deno\");\n",
|
"data": "console.log(\"hello deno\");\n",
|
||||||
"version": "149c777056afcc973d5fcbe11421b6d5ddc57b81786765302030d7fc893bf729",
|
"version": "7821807483407828376",
|
||||||
"scriptKind": 3,
|
"scriptKind": 3,
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
|
|
Loading…
Reference in a new issue