Skip to content

Commit 8e9f46f

Browse files
author
Lichu Acuña
committed
Implemented module ID global optimization using GlobalInformation.
1 parent 721c53b commit 8e9f46f

File tree

5 files changed

+82
-11
lines changed

5 files changed

+82
-11
lines changed

crates/turbopack-browser/src/chunking_context.rs

+5
Original file line numberDiff line numberDiff line change
@@ -514,4 +514,9 @@ impl ChunkingContext for BrowserChunkingContext {
514514
self.chunk_item_id_from_ident(AsyncLoaderModule::asset_ident_for(module))
515515
})
516516
}
517+
518+
#[turbo_tasks::function]
519+
async fn global_information(self: Vc<Self>) -> Result<Vc<OptionGlobalInformation>> {
520+
Ok(self.await?.global_information)
521+
}
517522
}

crates/turbopack-core/src/changed.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ async fn get_referenced_output_assets(
1717
Ok(parent.references().await?.clone_value().into_iter())
1818
}
1919

20-
async fn get_referenced_modules(
20+
pub async fn get_referenced_modules(
2121
parent: Vc<Box<dyn Module>>,
2222
) -> Result<impl Iterator<Item = Vc<Box<dyn Module>>> + Send> {
2323
Ok(primary_referenced_modules(parent)

crates/turbopack-core/src/chunk/chunking_context.rs

+9-1
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,10 @@ use turbo_tasks::{trace::TraceRawVcs, RcStr, TaskInput, Upcast, Value, ValueToSt
44
use turbo_tasks_fs::FileSystemPath;
55
use turbo_tasks_hash::DeterministicHash;
66

7-
use super::{availability_info::AvailabilityInfo, ChunkableModule, EvaluatableAssets};
7+
use super::{
8+
availability_info::AvailabilityInfo, global_information::OptionGlobalInformation,
9+
ChunkableModule, EvaluatableAssets,
10+
};
811
use crate::{
912
chunk::{ChunkItem, ModuleId},
1013
environment::Environment,
@@ -114,10 +117,15 @@ pub trait ChunkingContext {
114117
availability_info: Value<AvailabilityInfo>,
115118
) -> Result<Vc<EntryChunkGroupResult>>;
116119

120+
fn global_information(self: Vc<Self>) -> Vc<OptionGlobalInformation>;
121+
117122
async fn chunk_item_id_from_ident(
118123
self: Vc<Self>,
119124
ident: Vc<AssetIdent>,
120125
) -> Result<Vc<ModuleId>> {
126+
if let Some(global_information) = &*self.global_information().await? {
127+
return Ok(global_information.get_module_id(ident).await?);
128+
}
121129
Ok(ModuleId::String(ident.to_string().await?.clone_value()).cell())
122130
}
123131

Original file line numberDiff line numberDiff line change
@@ -1,6 +1,67 @@
1+
use std::collections::{HashMap, HashSet};
2+
3+
use anyhow::Result;
4+
use turbo_tasks::{ValueToString, Vc};
5+
use turbo_tasks_hash::hash_xxh3_hash64;
6+
7+
use super::ModuleId;
8+
use crate::{ident::AssetIdent, module::Module};
9+
110
#[turbo_tasks::value]
211
#[derive(Clone, Debug)]
3-
pub struct GlobalInformation {}
12+
pub struct GlobalInformation {
13+
pub module_id_map: HashMap<AssetIdent, ModuleId>,
14+
}
15+
16+
impl GlobalInformation {
17+
pub async fn get_module_id(&self, asset_ident: Vc<AssetIdent>) -> Result<Vc<ModuleId>> {
18+
let ident_str = asset_ident.to_string().await?;
19+
let ident = asset_ident.await?;
20+
let hashed_module_id = self.module_id_map.get(&ident);
21+
if let Some(hashed_module_id) = hashed_module_id {
22+
dbg!("Hashed module ID found", &ident_str, hashed_module_id);
23+
return Ok(hashed_module_id.clone().cell());
24+
}
25+
dbg!("Hashed module ID not found", &ident_str);
26+
return Ok(ModuleId::String(ident_str.clone_value()).cell());
27+
}
28+
}
429

530
#[turbo_tasks::value(transparent)]
631
pub struct OptionGlobalInformation(Option<GlobalInformation>);
32+
33+
// NOTE(LichuAcu): This is a temporary location for this function,
34+
// it could later be moved to a `module_id_optimization.rs` file with
35+
// other module ID optimization logic.
36+
pub async fn process_module(
37+
module: Vc<Box<dyn Module>>,
38+
id_map: &mut HashMap<AssetIdent, ModuleId>,
39+
used_ids: &mut HashSet<u64>,
40+
) -> Result<()> {
41+
let ident = module.ident();
42+
43+
let hash = hash_xxh3_hash64(ident.to_string().await?);
44+
let mut masked_hash = hash & 0xF;
45+
let mut mask = 0xF;
46+
while used_ids.contains(&masked_hash) {
47+
if mask == 0xFFFFFFFFFFFFFFFF {
48+
return Err(anyhow::anyhow!("This is a... 64-bit hash collision?"));
49+
}
50+
mask = (mask << 4) | 0xF;
51+
masked_hash = hash & mask;
52+
}
53+
54+
let hashed_module_id = ModuleId::String(masked_hash.to_string().into());
55+
56+
dbg!(
57+
"process_module",
58+
ident.await?.clone_value(),
59+
&hashed_module_id,
60+
mask
61+
);
62+
63+
id_map.insert(ident.await?.clone_value(), hashed_module_id);
64+
used_ids.insert(masked_hash);
65+
66+
Ok(())
67+
}

crates/turbopack-nodejs/src/chunking_context.rs

+5-8
Original file line numberDiff line numberDiff line change
@@ -136,14 +136,6 @@ impl NodeJsChunkingContext {
136136

137137
#[turbo_tasks::value_impl]
138138
impl NodeJsChunkingContext {
139-
#[turbo_tasks::function]
140-
async fn chunk_item_id_from_ident(
141-
self: Vc<Self>,
142-
ident: Vc<AssetIdent>,
143-
) -> Result<Vc<ModuleId>> {
144-
Ok(ModuleId::String(ident.to_string().await?.clone_value()).cell())
145-
}
146-
147139
#[turbo_tasks::function]
148140
fn new(this: Value<NodeJsChunkingContext>) -> Vc<Self> {
149141
this.into_value().cell()
@@ -393,4 +385,9 @@ impl ChunkingContext for NodeJsChunkingContext {
393385
self.chunk_item_id_from_ident(AsyncLoaderModule::asset_ident_for(module))
394386
})
395387
}
388+
389+
#[turbo_tasks::function]
390+
async fn global_information(self: Vc<Self>) -> Result<Vc<OptionGlobalInformation>> {
391+
Ok(self.await?.global_information)
392+
}
396393
}

0 commit comments

Comments
 (0)