Mercurial > hg
comparison rust/hg-core/src/matchers.rs @ 50695:1c31b343e514
match: add `filepath:` pattern to match an exact filepath relative to the root
It's useful in certain automated workflows to make sure we recurse in
directories whose name conflicts with files in other revisions.
In addition it makes it possible to avoid building a potentially costly regex,
improving performance when the set of files to match explicitly is large.
The benchmark below are run in the following configuration :
# data-env-vars.name = mozilla-central-2018-08-01-zstd-sparse-revlog
# benchmark.name = files
# benchmark.variants.rev = tip
# benchmark.variants.files = all-list-filepath-sorted
# bin-env-vars.hg.flavor = no-rust
It also includes timings using the re2 engine (through the `google-re2` module)
to show how much can be saved by just using a better regexp engine.
Pattern time (seconds) time using re2
-----------------------------------------------------------
just "." 0.4 0.4
list of "filepath:…" 1.3 1.3
list of "path:…" 25.7 3.9
list of patterns 29.7 10.4
As you can see, Without re2, using "filepath:" instead of "path:" is a huge
win. With re2, it is still about three times faster to not have to build the
regex.
author | Raphaël Gomès <rgomes@octobus.net> |
---|---|
date | Mon, 12 Jun 2023 16:51:08 +0200 |
parents | e98fd81bb151 |
children | e037af7de2ce |
comparison
equal
deleted
inserted
replaced
50686:a41eeb877d07 | 50695:1c31b343e514 |
---|---|
706 } | 706 } |
707 root.push(HgPathBuf::from_bytes(p).as_ref()); | 707 root.push(HgPathBuf::from_bytes(p).as_ref()); |
708 } | 708 } |
709 roots.push(root); | 709 roots.push(root); |
710 } | 710 } |
711 PatternSyntax::Path | PatternSyntax::RelPath => { | 711 PatternSyntax::Path |
712 | PatternSyntax::RelPath | |
713 | PatternSyntax::FilePath => { | |
712 let pat = HgPath::new(if pattern == b"." { | 714 let pat = HgPath::new(if pattern == b"." { |
713 &[] as &[u8] | 715 &[] as &[u8] |
714 } else { | 716 } else { |
715 pattern | 717 pattern |
716 }); | 718 }); |
1221 assert_eq!( | 1223 assert_eq!( |
1222 matcher.visit_children_set(HgPath::new(b"dir/subdir/x")), | 1224 matcher.visit_children_set(HgPath::new(b"dir/subdir/x")), |
1223 VisitChildrenSet::This | 1225 VisitChildrenSet::This |
1224 ); | 1226 ); |
1225 | 1227 |
1228 // VisitchildrensetFilePath | |
1229 let matcher = IncludeMatcher::new(vec![IgnorePattern::new( | |
1230 PatternSyntax::FilePath, | |
1231 b"dir/z", | |
1232 Path::new(""), | |
1233 )]) | |
1234 .unwrap(); | |
1235 | |
1236 let mut set = HashSet::new(); | |
1237 set.insert(HgPathBuf::from_bytes(b"dir")); | |
1238 assert_eq!( | |
1239 matcher.visit_children_set(HgPath::new(b"")), | |
1240 VisitChildrenSet::Set(set) | |
1241 ); | |
1242 assert_eq!( | |
1243 matcher.visit_children_set(HgPath::new(b"folder")), | |
1244 VisitChildrenSet::Empty | |
1245 ); | |
1246 let mut set = HashSet::new(); | |
1247 set.insert(HgPathBuf::from_bytes(b"z")); | |
1248 assert_eq!( | |
1249 matcher.visit_children_set(HgPath::new(b"dir")), | |
1250 VisitChildrenSet::Set(set) | |
1251 ); | |
1252 // OPT: these should probably be set(). | |
1253 assert_eq!( | |
1254 matcher.visit_children_set(HgPath::new(b"dir/subdir")), | |
1255 VisitChildrenSet::Empty | |
1256 ); | |
1257 assert_eq!( | |
1258 matcher.visit_children_set(HgPath::new(b"dir/subdir/x")), | |
1259 VisitChildrenSet::Empty | |
1260 ); | |
1261 | |
1226 // Test multiple patterns | 1262 // Test multiple patterns |
1227 let matcher = IncludeMatcher::new(vec![ | 1263 let matcher = IncludeMatcher::new(vec![ |
1228 IgnorePattern::new(PatternSyntax::RelPath, b"foo", Path::new("")), | 1264 IgnorePattern::new(PatternSyntax::RelPath, b"foo", Path::new("")), |
1229 IgnorePattern::new(PatternSyntax::Glob, b"g*", Path::new("")), | 1265 IgnorePattern::new(PatternSyntax::Glob, b"g*", Path::new("")), |
1230 ]) | 1266 ]) |