Skip to content

Commit 27d3fd8

Browse files
author
fossdd
committed
Update pijul
1 parent cb9d225 commit 27d3fd8

File tree

17 files changed

+169
-137
lines changed

17 files changed

+169
-137
lines changed

libpijul/src/alive/output.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ fn output_scc<T: GraphTxnT, B: VertexBuffer, P: ChangeStore>(
212212

213213
let vertex = graph[v].vertex;
214214

215-
let get_contents = |buf: &mut Vec<u8>| {
215+
let get_contents = |buf: &mut [u8]| {
216216
let now = std::time::Instant::now();
217217
let result = changes
218218
.get_contents(

libpijul/src/change/text_changes.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1093,7 +1093,7 @@ pub fn get_change_contents<C: ChangeStore>(
10931093
if Some(e.to) == current {
10941094
continue;
10951095
}
1096-
tmp.clear();
1096+
tmp.resize(e.to.end - e.to.start, 0);
10971097
changes
10981098
.get_contents_ext(e.to, &mut tmp)
10991099
.map_err(TextSerError::C)?;

libpijul/src/changestore/filesystem.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -173,14 +173,14 @@ impl ChangeStore for FileSystem {
173173
&self,
174174
hash: F,
175175
key: Vertex<ChangeId>,
176-
buf: &mut Vec<u8>,
176+
buf: &mut [u8],
177177
) -> Result<usize, Self::Error> {
178178
debug!("get_contents {:?}", key);
179-
buf.resize(key.end.us() - key.start.us(), 0);
180179
if key.end <= key.start || key.is_root() {
181180
debug!("return 0");
182181
return Ok(0);
183182
}
183+
assert_eq!(key.end - key.start, buf.len());
184184
let mut cache = self.load(hash, key.change)?;
185185
let p = cache.get_mut(&key.change).unwrap();
186186
let n = p.read_contents(key.start.into(), buf)?;
@@ -190,10 +190,10 @@ impl ChangeStore for FileSystem {
190190
fn get_contents_ext(
191191
&self,
192192
key: Vertex<Option<Hash>>,
193-
buf: &mut Vec<u8>,
193+
buf: &mut [u8],
194194
) -> Result<usize, Self::Error> {
195195
if let Some(change) = key.change {
196-
buf.resize(key.end.us() - key.start.us(), 0);
196+
assert_eq!(key.end.us() - key.start.us(), buf.len());
197197
if key.end <= key.start {
198198
return Ok(0);
199199
}

libpijul/src/changestore/memory.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -48,36 +48,34 @@ impl ChangeStore for Memory {
4848
&self,
4949
hash: F,
5050
key: Vertex<ChangeId>,
51-
buf: &mut Vec<u8>,
51+
buf: &mut [u8],
5252
) -> Result<usize, Self::Error> {
53-
buf.resize(key.end.us() - key.start.us(), 0);
5453
if key.end <= key.start {
5554
return Ok(0);
5655
}
56+
assert_eq!(buf.len(), key.end - key.start);
5757
let changes = self.changes.read().unwrap();
5858
let p = changes.get(&hash(key.change).unwrap()).unwrap();
5959
let start = key.start.us();
6060
let end = key.end.us();
61-
buf.clear();
62-
buf.extend(&p.contents[start..end]);
61+
buf.clone_from_slice(&p.contents[start..end]);
6362
Ok(end - start)
6463
}
6564
fn get_contents_ext(
6665
&self,
6766
key: Vertex<Option<Hash>>,
68-
buf: &mut Vec<u8>,
67+
buf: &mut [u8],
6968
) -> Result<usize, Self::Error> {
7069
if let Some(change) = key.change {
71-
buf.resize(key.end.us() - key.start.us(), 0);
7270
if key.end <= key.start {
7371
return Ok(0);
7472
}
73+
assert_eq!(key.end.us() - key.start.us(), buf.len());
7574
let changes = self.changes.read().unwrap();
7675
let p = changes.get(&change).unwrap();
7776
let start = key.start.us();
7877
let end = key.end.us();
79-
buf.clear();
80-
buf.extend(&p.contents[start..end]);
78+
buf.clone_from_slice(&p.contents[start..end]);
8179
Ok(end - start)
8280
} else {
8381
Ok(0)

libpijul/src/changestore/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ pub trait ChangeStore {
3131
&self,
3232
hash: F,
3333
key: Vertex<ChangeId>,
34-
buf: &mut Vec<u8>,
34+
buf: &mut [u8],
3535
) -> Result<usize, Self::Error>;
3636
fn get_header(&self, h: &Hash) -> Result<ChangeHeader, Self::Error> {
3737
Ok(self.get_change(h)?.hashed.header)
@@ -40,7 +40,7 @@ pub trait ChangeStore {
4040
fn get_contents_ext(
4141
&self,
4242
key: Vertex<Option<Hash>>,
43-
buf: &mut Vec<u8>,
43+
buf: &mut [u8],
4444
) -> Result<usize, Self::Error>;
4545
fn get_dependencies(&self, hash: &Hash) -> Result<Vec<Hash>, Self::Error> {
4646
Ok(self.get_change(hash)?.hashed.dependencies)
@@ -87,9 +87,8 @@ pub trait ChangeStore {
8787
&self,
8888
hash: F,
8989
vertex: Vertex<ChangeId>,
90-
buf: &'a mut Vec<u8>,
90+
buf: &'a mut [u8],
9191
) -> Result<FileMetadata<'a>, Self::Error> {
92-
buf.clear();
9392
self.get_contents(hash, vertex, buf)?;
9493
Ok(FileMetadata::read(buf))
9594
}

libpijul/src/diff/vertex_buffer.rs

Lines changed: 11 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@ use crate::vertex_buffer;
33
use crate::{HashMap, HashSet};
44

55
pub(super) struct Diff {
6-
pub buf: Vec<u8>,
76
pub inode: Position<Option<ChangeId>>,
87
pub path: String,
98
pub contents_a: Vec<u8>,
@@ -62,7 +61,6 @@ impl Diff {
6261
Diff {
6362
inode,
6463
path,
65-
buf: Vec::with_capacity(graph.len_bytes()),
6664
pos_a: Vec::with_capacity(2 * graph.len_vertices()),
6765
contents_a: Vec::with_capacity(graph.len_bytes()),
6866
missing_eol: HashSet::default(),
@@ -137,20 +135,20 @@ impl vertex_buffer::VertexBuffer for Diff {
137135
fn output_line<E, C>(&mut self, v: crate::pristine::Vertex<ChangeId>, c: C) -> Result<(), E>
138136
where
139137
E: From<std::io::Error>,
140-
C: FnOnce(&mut Vec<u8>) -> Result<(), E>,
138+
C: FnOnce(&mut [u8]) -> Result<(), E>,
141139
{
142140
if v == crate::pristine::Vertex::BOTTOM {
143141
return Ok(());
144142
}
145-
self.buf.clear();
146-
c(&mut self.buf)?;
143+
let len = self.contents_a.len();
144+
self.contents_a.resize(len + (v.end - v.start), 0);
145+
c(&mut self.contents_a[len..])?;
147146
self.pos_a.push(Vertex {
148-
pos: self.contents_a.len(),
147+
pos: len,
149148
vertex: v,
150149
before_conflict: false,
151150
conflict: self.conflict_stack.last().unwrap().counter,
152151
});
153-
self.contents_a.extend(&self.buf);
154152
Ok(())
155153
}
156154

@@ -281,7 +279,12 @@ impl Diff {
281279
},
282280
Err(i) => {
283281
assert!(i > 0);
284-
i - 1
282+
let len = self.pos_a[i-1].vertex.end - self.pos_a[i-1].vertex.start;
283+
if pos < self.pos_a[i-1].pos + len || len == 0 {
284+
i - 1
285+
} else {
286+
i
287+
}
285288
}
286289
}
287290
}

libpijul/src/find_alive.rs

Lines changed: 46 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
use crate::pristine::*;
2-
use crate::HashSet;
2+
use crate::{HashMap, HashSet};
3+
use std::cell::RefCell;
4+
use std::rc::Rc;
5+
6+
type Alive = Rc<RefCell<HashSet<Vertex<ChangeId>>>>;
37

48
pub(crate) fn find_alive_down<T: GraphTxnT>(
59
txn: &T,
610
channel: &T::Graph,
711
vertex0: Vertex<ChangeId>,
8-
) -> Result<HashSet<Vertex<ChangeId>>, BlockError<T::GraphError>> {
9-
let mut stack = vec![(
10-
SerializedEdge::empty(vertex0.start_pos(), ChangeId::ROOT),
11-
0,
12-
)];
12+
cache: &mut HashMap<Vertex<ChangeId>, Alive>,
13+
) -> Result<Alive, BlockError<T::GraphError>> {
14+
let mut stack = vec![SerializedEdge::empty(vertex0.start_pos(), ChangeId::ROOT)];
1315
let mut visited = HashSet::default();
14-
let mut alive = HashSet::default();
15-
while let Some((elt, len)) = stack.pop() {
16+
let alive = Rc::new(RefCell::new(HashSet::new()));
17+
while let Some(elt) = stack.pop() {
1618
if !visited.insert(elt.dest()) {
1719
continue;
1820
}
1921
let vertex = txn.find_block(&channel, elt.dest())?;
22+
if let Some(c) = cache.get(vertex) {
23+
alive.borrow_mut().extend(c.borrow().iter().cloned());
24+
continue;
25+
} else {
26+
cache.insert(*vertex, alive.clone());
27+
}
2028
debug!("elt = {:?}, vertex = {:?}", elt, vertex);
2129
let elt_index = stack.len();
2230
for v in iter_adj_all(txn, &channel, *vertex)? {
@@ -31,18 +39,17 @@ pub(crate) fn find_alive_down<T: GraphTxnT>(
3139
&& !v.flag().contains(EdgeFlags::PSEUDO)
3240
{
3341
if *vertex == vertex0 {
34-
assert!(alive.is_empty());
42+
assert!(alive.borrow().is_empty());
3543
return Ok(alive);
3644
} else {
37-
alive.insert(*vertex);
45+
alive.borrow_mut().insert(*vertex);
3846
stack.truncate(elt_index);
3947
break;
4048
}
41-
} else {
42-
continue;
4349
}
50+
} else {
51+
stack.push(*v)
4452
}
45-
stack.push((*v, len + 1))
4653
}
4754
}
4855
Ok(alive)
@@ -54,8 +61,11 @@ pub fn find_alive_up<T: GraphTxnT>(
5461
files: &mut HashSet<Vertex<ChangeId>>,
5562
vertex0: Vertex<ChangeId>,
5663
change: ChangeId,
57-
) -> Result<HashSet<Vertex<ChangeId>>, BlockError<T::GraphError>> {
58-
let mut alive = HashSet::default();
64+
cache: &mut HashMap<Vertex<ChangeId>, (Alive, Alive)>,
65+
) -> Result<Alive, BlockError<T::GraphError>> {
66+
debug!("find alive up: {:?}", vertex0);
67+
let alive = Rc::new(RefCell::new(HashSet::default()));
68+
let files_ = Rc::new(RefCell::new(HashSet::default()));
5969
let mut stack = vec![SerializedEdge::empty(vertex0.end_pos(), ChangeId::ROOT)];
6070
let mut visited = HashSet::default();
6171

@@ -67,6 +77,18 @@ pub fn find_alive_up<T: GraphTxnT>(
6777
continue;
6878
}
6979
let vertex = *txn.find_block_end(&channel, elt.dest())?;
80+
debug!("vertex = {:?}", vertex);
81+
let is_cached = if let Some((c, f)) = cache.get(&vertex) {
82+
alive.borrow_mut().extend(c.borrow().iter().cloned());
83+
files_.borrow_mut().extend(f.borrow().iter().cloned());
84+
files.extend(f.borrow().iter().cloned());
85+
// We're not continuing here, since the while loop below
86+
// needs to insert stuff into `files` and `files_`.
87+
true
88+
} else {
89+
cache.insert(vertex, (alive.clone(), files_.clone()));
90+
false
91+
};
7092
debug!("find_alive_up: elt = {:?}, vertex = {:?}", elt, vertex);
7193
debug!("stack = {:?}", stack);
7294
let elt_index = stack.len();
@@ -89,25 +111,30 @@ pub fn find_alive_up<T: GraphTxnT>(
89111
is_file |= !e.flag().intersects(EdgeFlags::parent_folder())
90112
}
91113
if is_file && vertex != vertex0 {
92-
alive.insert(vertex);
114+
debug!("is alive + is file {:?}", vertex);
115+
alive.borrow_mut().insert(vertex);
116+
files_.borrow_mut().insert(vertex);
93117
files.insert(vertex);
94118
}
95119
break;
96120
} else if v.flag().is_block() || vertex.is_empty() {
97121
if vertex != vertex0 {
98-
alive.insert(vertex);
122+
debug!("is alive {:?}", vertex);
123+
alive.borrow_mut().insert(vertex);
99124
}
100125
stack.truncate(elt_index);
101126
break;
102127
}
103128
}
104129
if v.flag().is_folder() {
105130
if is_file && vertex != vertex0 {
106-
alive.insert(vertex);
131+
debug!("is alive {:?}", vertex);
132+
alive.borrow_mut().insert(vertex);
133+
files_.borrow_mut().insert(vertex);
107134
files.insert(vertex);
108135
}
109136
break;
110-
} else {
137+
} else if !is_cached {
111138
stack.push(*v)
112139
}
113140
}

libpijul/src/fs.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -637,6 +637,7 @@ impl<'txn, 'changes, T: GraphTxnT, P: ChangeStore + 'changes> Iterator
637637
debug!("dest = {:?}", dest);
638638

639639
let mut buf = std::mem::replace(&mut self.buf, Vec::new());
640+
buf.resize(dest.end - dest.start, 0);
640641
let FileMetadata {
641642
basename,
642643
metadata: perms,
@@ -735,6 +736,7 @@ impl<'txn, 'changes, T: GraphTxnT, P: ChangeStore + 'changes> Iterator
735736
return None;
736737
}
737738
let mut buf = std::mem::replace(&mut self.buf, Vec::new());
739+
buf.resize(dest.end - dest.start, 0);
738740
let FileMetadata {
739741
basename,
740742
metadata: perms,
@@ -884,7 +886,7 @@ pub(crate) fn follow_oldest_path<T: ChannelTxnT, C: ChangeStore>(
884886
.dest();
885887
continue 'outer;
886888
}
887-
name_buf.clear();
889+
name_buf.resize(name_dest.end - name_dest.start, 0);
888890
debug!("getting contents {:?}", name);
889891
changes
890892
.get_contents(
@@ -1013,7 +1015,7 @@ pub fn find_path<T: ChannelTxnT, C: ChangeStore>(
10131015
break;
10141016
}
10151017
if alive {
1016-
name_buf.clear();
1018+
name_buf.resize(name.end - name.start, 0);
10171019
debug!("getting contents {:?}", name);
10181020

10191021
let FileMetadata { basename, .. } = changes

0 commit comments

Comments
 (0)