Skip to content

Commit fc7391a

Browse files
Speed up implementation of tree::overlay (#1294)
By using only a single treebuilder and no intermediate trees a lot of time and io is saved. Workspace rebuilds are much faster with this change. Change: faster-overlay
1 parent c4cfea6 commit fc7391a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+137
-361
lines changed

josh-core/src/cache.rs

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use super::*;
22
use std::collections::HashMap;
33

4-
const CACHE_VERSION: u64 = 16;
4+
const CACHE_VERSION: u64 = 17;
55

66
lazy_static! {
77
static ref DB: std::sync::Mutex<Option<sled::Db>> = std::sync::Mutex::new(None);
@@ -54,6 +54,7 @@ struct Transaction2 {
5454
commit_map: HashMap<git2::Oid, HashMap<git2::Oid, git2::Oid>>,
5555
apply_map: HashMap<git2::Oid, HashMap<git2::Oid, git2::Oid>>,
5656
subtract_map: HashMap<(git2::Oid, git2::Oid), git2::Oid>,
57+
overlay_map: HashMap<(git2::Oid, git2::Oid), git2::Oid>,
5758
unapply_map: HashMap<git2::Oid, HashMap<git2::Oid, git2::Oid>>,
5859
sled_trees: HashMap<git2::Oid, sled::Tree>,
5960
path_tree: sled::Tree,
@@ -139,6 +140,7 @@ impl Transaction {
139140
commit_map: HashMap::new(),
140141
apply_map: HashMap::new(),
141142
subtract_map: HashMap::new(),
143+
overlay_map: HashMap::new(),
142144
unapply_map: HashMap::new(),
143145
sled_trees: HashMap::new(),
144146
path_tree,
@@ -210,6 +212,16 @@ impl Transaction {
210212
return t2.subtract_map.get(&from).cloned();
211213
}
212214

215+
pub fn insert_overlay(&self, from: (git2::Oid, git2::Oid), to: git2::Oid) {
216+
let mut t2 = self.t2.borrow_mut();
217+
t2.overlay_map.insert(from, to);
218+
}
219+
220+
pub fn get_overlay(&self, from: (git2::Oid, git2::Oid)) -> Option<git2::Oid> {
221+
let t2 = self.t2.borrow_mut();
222+
return t2.overlay_map.get(&from).cloned();
223+
}
224+
213225
pub fn insert_unapply(&self, filter: filter::Filter, from: git2::Oid, to: git2::Oid) {
214226
let mut t2 = self.t2.borrow_mut();
215227
t2.unapply_map

josh-core/src/filter/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ fn apply_to_commit2(
652652
let mut filtered_tree = commit.tree_id();
653653

654654
for t in trees {
655-
filtered_tree = tree::overlay(repo, filtered_tree, t)?;
655+
filtered_tree = tree::overlay(transaction, filtered_tree, t)?;
656656
}
657657

658658
repo.find_tree(filtered_tree)?
@@ -856,7 +856,7 @@ pub fn unapply<'a>(
856856
let new_tree = apply(transaction, inverted, tree)?;
857857

858858
return Ok(transaction.repo().find_tree(tree::overlay(
859-
transaction.repo(),
859+
transaction,
860860
new_tree.id(),
861861
stripped,
862862
)?)?);
@@ -911,7 +911,7 @@ fn unapply_workspace<'a>(
911911
let new_tree = apply(transaction, invert(filter)?, tree)?;
912912

913913
let result = transaction.repo().find_tree(tree::overlay(
914-
transaction.repo(),
914+
transaction,
915915
new_tree.id(),
916916
stripped,
917917
)?)?;

josh-core/src/filter/tree.rs

Lines changed: 34 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -340,11 +340,14 @@ pub fn diff_paths(
340340
}
341341

342342
pub fn overlay(
343-
repo: &git2::Repository,
343+
transaction: &cache::Transaction,
344344
input1: git2::Oid,
345345
input2: git2::Oid,
346346
) -> JoshResult<git2::Oid> {
347-
rs_tracing::trace_scoped!("overlay");
347+
if let Some(cached) = transaction.get_overlay((input1, input2)) {
348+
return Ok(cached);
349+
}
350+
let repo = transaction.repo();
348351
if input1 == input2 {
349352
return Ok(input1);
350353
}
@@ -356,29 +359,35 @@ pub fn overlay(
356359
}
357360

358361
if let (Ok(tree1), Ok(tree2)) = (repo.find_tree(input1), repo.find_tree(input2)) {
359-
let mut result_tree = tree1.clone();
362+
rs_tracing::trace_begin!( "overlay",
363+
"overlay_a": format!("{}", input1),
364+
"overlay_b": format!("{}", input2),
365+
"overlay_ab": format!("{} - {}", input1, input2));
366+
let mut builder = repo.treebuilder(Some(&tree1))?;
360367

368+
let mut i = 0;
361369
for entry in tree2.iter() {
362-
if let Some(e) = tree1.get_name(entry.name().ok_or_else(|| josh_error("no name"))?) {
363-
result_tree = replace_child(
364-
repo,
365-
Path::new(entry.name().ok_or_else(|| josh_error("no name"))?),
366-
overlay(repo, e.id(), entry.id())?,
367-
e.filemode(),
368-
&result_tree,
369-
)?;
370+
i += 1;
371+
let (id, mode) = if let Some(e) =
372+
tree1.get_name(entry.name().ok_or_else(|| josh_error("no name"))?)
373+
{
374+
(overlay(transaction, e.id(), entry.id())?, e.filemode())
370375
} else {
371-
result_tree = replace_child(
372-
repo,
373-
Path::new(entry.name().ok_or_else(|| josh_error("no name"))?),
374-
entry.id(),
375-
entry.filemode(),
376-
&result_tree,
377-
)?;
378-
}
376+
(entry.id(), entry.filemode())
377+
};
378+
379+
builder.insert(
380+
Path::new(entry.name().ok_or_else(|| josh_error("no name"))?),
381+
id,
382+
mode,
383+
)?;
379384
}
380385

381-
return Ok(result_tree.id());
386+
let rid = builder.write()?;
387+
rs_tracing::trace_end!( "overlay", "count":i);
388+
389+
transaction.insert_overlay((input1, input2), rid);
390+
return Ok(rid);
382391
}
383392

384393
Ok(input1)
@@ -837,7 +846,7 @@ pub fn invert_paths<'a>(
837846
&format!("{}{}{}", root, if root.is_empty() { "" } else { "/" }, name),
838847
repo.find_tree(entry.id())?,
839848
)?;
840-
result = repo.find_tree(overlay(repo, result.id(), s.id())?)?;
849+
result = repo.find_tree(overlay(transaction, result.id(), s.id())?)?;
841850
}
842851
}
843852

@@ -897,7 +906,7 @@ fn populate(
897906
for entry in content.iter() {
898907
if let Some(e) = paths.get_name(entry.name().ok_or_else(|| josh_error("no name"))?) {
899908
result_tree = overlay(
900-
repo,
909+
transaction,
901910
result_tree,
902911
populate(transaction, e.id(), entry.id())?,
903912
)?;
@@ -918,7 +927,7 @@ pub fn compose_fast(
918927
let repo = transaction.repo();
919928
let mut result = empty_id();
920929
for tree in trees {
921-
result = overlay(repo, tree, result)?;
930+
result = overlay(transaction, tree, result)?;
922931
}
923932

924933
Ok(repo.find_tree(result)?)
@@ -950,8 +959,8 @@ pub fn compose<'a>(
950959
apply(transaction, invert(*f)?, applied)?.id()
951960
};
952961
transaction.insert_unapply(*f, aid, unapplied);
953-
taken = repo.find_tree(overlay(repo, taken.id(), unapplied)?)?;
954-
result = repo.find_tree(overlay(repo, subtracted.id(), result.id())?)?;
962+
taken = repo.find_tree(overlay(transaction, taken.id(), unapplied)?)?;
963+
result = repo.find_tree(overlay(transaction, subtracted.id(), result.id())?)?;
955964
}
956965

957966
Ok(result)

tests/proxy/amend_patchset.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
]
125125
.
126126
|-- josh
127-
| `-- 16
127+
| `-- 17
128128
| `-- sled
129129
| |-- blobs
130130
| |-- conf

tests/proxy/authentication.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@
124124
"real_repo.git" = ["::sub1/"]
125125
.
126126
|-- josh
127-
| `-- 16
127+
| `-- 17
128128
| `-- sled
129129
| |-- blobs
130130
| |-- conf

tests/proxy/caching.t

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@
5151
]
5252
.
5353
|-- josh
54-
| `-- 16
54+
| `-- 17
5555
| `-- sled
5656
| |-- blobs
5757
| |-- conf
@@ -162,7 +162,7 @@
162162
]
163163
.
164164
|-- josh
165-
| `-- 16
165+
| `-- 17
166166
| `-- sled
167167
| |-- blobs
168168
| |-- conf

tests/proxy/clone_absent_head.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@
8585
$ bash ${TESTDIR}/destroy_test_env.sh
8686
.
8787
|-- josh
88-
| `-- 16
88+
| `-- 17
8989
| `-- sled
9090
| |-- blobs
9191
| |-- conf

tests/proxy/clone_all.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@
5353
"real_repo.git" = ["::sub1/"]
5454
.
5555
|-- josh
56-
| `-- 16
56+
| `-- 17
5757
| `-- sled
5858
| |-- blobs
5959
| |-- conf

tests/proxy/clone_blocked.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
$ bash ${TESTDIR}/destroy_test_env.sh
1010
.
1111
|-- josh
12-
| `-- 16
12+
| `-- 17
1313
| `-- sled
1414
| |-- blobs
1515
| |-- conf

tests/proxy/clone_invalid_url.t

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
$ bash ${TESTDIR}/destroy_test_env.sh
3333
.
3434
|-- josh
35-
| `-- 16
35+
| `-- 17
3636
| `-- sled
3737
| |-- blobs
3838
| |-- conf

0 commit comments

Comments
 (0)