##// END OF EJS Templates
dirstate-v2: Replace the 32-bit `mode` field with two bits...
Simon Sapin -
r49009:4d5a1325 default
parent child Browse files
Show More
@@ -380,6 +380,9 Node components are:
380 P2_INFO = 1 << 2
380 P2_INFO = 1 << 2
381 HAS_MODE_AND_SIZE = 1 << 3
381 HAS_MODE_AND_SIZE = 1 << 3
382 HAS_MTIME = 1 << 4
382 HAS_MTIME = 1 << 4
383 MODE_EXEC_PERM = 1 << 5
384 MODE_IS_SYMLINK = 1 << 7
385
383
386
384 Other bits are unset. The meaning of these bits are:
387 Other bits are unset. The meaning of these bits are:
385
388
@@ -414,14 +417,17 Node components are:
414 in order to optimize `hg status`
417 in order to optimize `hg status`
415 by enabling it to skip `readdir` in more cases.
418 by enabling it to skip `readdir` in more cases.
416
419
417 When a node is for a file tracked anywhere,
420 When a node is for a file tracked anywhere:
418 the rest of the node data is three fields:
421 - If `HAS_MODE_AND_SIZE` is set, the file is expected
422 to be a symbolic link or a normal file based on `MODE_IS_SYMLINK`.
423 - If `HAS_MODE_AND_SIZE` is set, the file’s owner is expected
424 to have execute permission or not based on `MODE_EXEC_PERM`.
425 - If `HAS_MODE_AND_SIZE` is unset,
426 the expected type of file and permission are unknown.
427 The rest of the node data is three fields:
419
428
420 * Offset 31:
429 * Offset 31:
421 If `HAS_MODE_AND_SIZE` is unset, four zero bytes.
430 4 unused bytes, set to zero
422 Otherwise, a 32-bit integer for the Unix mode (as in `stat_result.st_mode`)
423 expected for this file to be considered clean.
424 Only the `S_IXUSR` bit (owner has execute permission) is considered.
425
431
426 * Offset 35:
432 * Offset 35:
427 If `HAS_MODE_AND_SIZE` is unset, four zero bytes.
433 If `HAS_MODE_AND_SIZE` is unset, four zero bytes.
@@ -1,5 +1,7
1 # This file is automatically @generated by Cargo.
1 # This file is automatically @generated by Cargo.
2 # It is not intended for manual editing.
2 # It is not intended for manual editing.
3 version = 3
4
3 [[package]]
5 [[package]]
4 name = "adler"
6 name = "adler"
5 version = "0.2.3"
7 version = "0.2.3"
@@ -386,6 +388,7 dependencies = [
386 "im-rc",
388 "im-rc",
387 "itertools",
389 "itertools",
388 "lazy_static",
390 "lazy_static",
391 "libc",
389 "log",
392 "log",
390 "memmap2",
393 "memmap2",
391 "micro-timer",
394 "micro-timer",
@@ -17,6 +17,7 home = "0.5"
17 im-rc = "15.0.*"
17 im-rc = "15.0.*"
18 itertools = "0.9"
18 itertools = "0.9"
19 lazy_static = "1.4.0"
19 lazy_static = "1.4.0"
20 libc = "0.2"
20 rand = "0.7.3"
21 rand = "0.7.3"
21 rand_pcg = "0.2.1"
22 rand_pcg = "0.2.1"
22 rand_distr = "0.2.2"
23 rand_distr = "0.2.2"
@@ -107,13 +107,15 bitflags! {
107 const P2_INFO = 1 << 2;
107 const P2_INFO = 1 << 2;
108 const HAS_MODE_AND_SIZE = 1 << 3;
108 const HAS_MODE_AND_SIZE = 1 << 3;
109 const HAS_MTIME = 1 << 4;
109 const HAS_MTIME = 1 << 4;
110 const MODE_EXEC_PERM = 1 << 5;
111 const MODE_IS_SYMLINK = 1 << 7;
110 }
112 }
111 }
113 }
112
114
113 #[derive(BytesCast, Copy, Clone, Debug)]
115 #[derive(BytesCast, Copy, Clone, Debug)]
114 #[repr(C)]
116 #[repr(C)]
115 struct Entry {
117 struct Entry {
116 mode: U32Be,
118 _padding: U32Be,
117 size: U32Be,
119 size: U32Be,
118 mtime: U32Be,
120 mtime: U32Be,
119 }
121 }
@@ -332,13 +334,27 impl Node {
332 )
334 )
333 }
335 }
334
336
337 fn synthesize_unix_mode(&self) -> u32 {
338 let file_type = if self.flags.contains(Flags::MODE_IS_SYMLINK) {
339 libc::S_IFLNK
340 } else {
341 libc::S_IFREG
342 };
343 let permisions = if self.flags.contains(Flags::MODE_EXEC_PERM) {
344 0o755
345 } else {
346 0o644
347 };
348 file_type | permisions
349 }
350
335 fn assume_entry(&self) -> DirstateEntry {
351 fn assume_entry(&self) -> DirstateEntry {
336 // TODO: convert through raw bits instead?
352 // TODO: convert through raw bits instead?
337 let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED);
353 let wdir_tracked = self.flags.contains(Flags::WDIR_TRACKED);
338 let p1_tracked = self.flags.contains(Flags::P1_TRACKED);
354 let p1_tracked = self.flags.contains(Flags::P1_TRACKED);
339 let p2_info = self.flags.contains(Flags::P2_INFO);
355 let p2_info = self.flags.contains(Flags::P2_INFO);
340 let mode_size = if self.flags.contains(Flags::HAS_MODE_AND_SIZE) {
356 let mode_size = if self.flags.contains(Flags::HAS_MODE_AND_SIZE) {
341 Some((self.data.mode.into(), self.data.size.into()))
357 Some((self.synthesize_unix_mode(), self.data.size.into()))
342 } else {
358 } else {
343 None
359 None
344 };
360 };
@@ -400,13 +416,15 impl Entry {
400 flags.set(Flags::WDIR_TRACKED, wdir_tracked);
416 flags.set(Flags::WDIR_TRACKED, wdir_tracked);
401 flags.set(Flags::P1_TRACKED, p1_tracked);
417 flags.set(Flags::P1_TRACKED, p1_tracked);
402 flags.set(Flags::P2_INFO, p2_info);
418 flags.set(Flags::P2_INFO, p2_info);
403 let (mode, size, mtime);
419 let (size, mtime);
404 if let Some((m, s)) = mode_size_opt {
420 if let Some((m, s)) = mode_size_opt {
405 mode = m;
421 let exec_perm = m & libc::S_IXUSR != 0;
422 let is_symlink = m & libc::S_IFMT == libc::S_IFLNK;
423 flags.set(Flags::MODE_EXEC_PERM, exec_perm);
424 flags.set(Flags::MODE_IS_SYMLINK, is_symlink);
406 size = s;
425 size = s;
407 flags.insert(Flags::HAS_MODE_AND_SIZE)
426 flags.insert(Flags::HAS_MODE_AND_SIZE)
408 } else {
427 } else {
409 mode = 0;
410 size = 0;
428 size = 0;
411 }
429 }
412 if let Some(m) = mtime_opt {
430 if let Some(m) = mtime_opt {
@@ -416,7 +434,7 impl Entry {
416 mtime = 0;
434 mtime = 0;
417 }
435 }
418 let raw_entry = Entry {
436 let raw_entry = Entry {
419 mode: mode.into(),
437 _padding: 0.into(),
420 size: size.into(),
438 size: size.into(),
421 mtime: mtime.into(),
439 mtime: mtime.into(),
422 };
440 };
@@ -600,7 +618,7 impl Writer<'_, '_> {
600 dirstate_map::NodeData::None => (
618 dirstate_map::NodeData::None => (
601 Flags::empty(),
619 Flags::empty(),
602 Entry {
620 Entry {
603 mode: 0.into(),
621 _padding: 0.into(),
604 size: 0.into(),
622 size: 0.into(),
605 mtime: 0.into(),
623 mtime: 0.into(),
606 },
624 },
@@ -23,7 +23,7 python3-bin = ["cpython/python3-sys"]
23 [dependencies]
23 [dependencies]
24 crossbeam-channel = "0.4"
24 crossbeam-channel = "0.4"
25 hg-core = { path = "../hg-core"}
25 hg-core = { path = "../hg-core"}
26 libc = '*'
26 libc = "0.2"
27 log = "0.4.8"
27 log = "0.4.8"
28 env_logger = "0.7.1"
28 env_logger = "0.7.1"
29 stable_deref_trait = "1.2.0"
29 stable_deref_trait = "1.2.0"
General Comments 0
You need to be logged in to leave comments. Login now