Skip to content

Commit

Permalink
remove entries from versioned content map again
Browse files Browse the repository at this point in the history
  • Loading branch information
sokra committed Sep 11, 2024
1 parent 94c5a41 commit 7a13154
Showing 1 changed file with 32 additions and 11 deletions.
43 changes: 32 additions & 11 deletions crates/next-api/src/versioned_content_map.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};

use anyhow::{bail, Result};
use indexmap::IndexSet;
use next_core::emit_assets;
use serde::{Deserialize, Serialize};
use turbo_tasks::{
Expand Down Expand Up @@ -31,11 +32,12 @@ struct MapEntry {
#[turbo_tasks::value(transparent)]
struct OptionMapEntry(Option<MapEntry>);

type PathToOutputOperation = HashMap<Vc<FileSystemPath>, Vc<OutputAssets>>;
type PathToOutputOperation = HashMap<Vc<FileSystemPath>, IndexSet<Vc<OutputAssets>>>;
type OutputOperationToComputeEntry = HashMap<Vc<OutputAssets>, Vc<OptionMapEntry>>;

#[turbo_tasks::value]
pub struct VersionedContentMap {
// TODO: turn into a bi-directional multimap, OutputAssets -> IndexSet<FileSystemPath>
map_path_to_op: State<PathToOutputOperation>,
map_op_to_compute_entry: State<OutputOperationToComputeEntry>,
}
Expand Down Expand Up @@ -95,22 +97,41 @@ impl VersionedContentMap {
client_output_path: Vc<FileSystemPath>,
) -> Result<Vc<OptionMapEntry>> {
let assets = *assets_operation.await?;
let entries: Vec<_> = assets
.await?
.iter()
let assets_result = assets.await;

let entries = if let Ok(assets_ref) = assets_result {
assets_ref.iter()
.map(|&asset| async move { Ok((asset.ident().path().resolve().await?, asset, assets)) })
.try_join()
.await?;
.await?
} else {
vec![]
};

self.await?.map_path_to_op.update_conditionally(|map| {
let mut changed = false;
for &(k, _, v) in entries.iter() {
if map.insert(k, v) != Some(v) {
changed = true;
}

// get current map's keys, subtract keys that don't exist in operation
let mut stale_assets = map.keys().copied().collect::<HashSet<_>>();

for (k, _, v) in entries.iter() {
let res = map.entry(*k).or_default().insert(*v);
stale_assets.remove(k);
changed = changed || res;
}

// Make more efficient with reverse map
for k in &stale_assets {
let res = map
.get_mut(k)
// guaranteed
.unwrap()
.remove(&assets);
changed = changed || res
}
changed
});

// Make sure all written client assets are up-to-date
let side_effects = emit_assets(assets, node_root, client_relative_path, client_output_path);
let map_entry = Vc::cell(Some(MapEntry {
Expand Down Expand Up @@ -193,7 +214,7 @@ impl VersionedContentMap {
async fn raw_get(&self, path: Vc<FileSystemPath>) -> Result<Vc<OptionMapEntry>> {
let assets = {
let map = self.map_path_to_op.get();
map.get(&path).copied()
map.get(&path).and_then(|m| m.iter().last().copied())
};
let Some(assets) = assets else {
return Ok(Vc::cell(None));
Expand Down

0 comments on commit 7a13154

Please sign in to comment.