diff --git a/lib/src/local_working_copy.rs b/lib/src/local_working_copy.rs index d67bcbb05..d45338f20 100644 --- a/lib/src/local_working_copy.rs +++ b/lib/src/local_working_copy.rs @@ -149,13 +149,17 @@ impl FileStatesMap { FileStatesMap { data: Vec::new() } } - // TODO: skip sorting if the data is known to be sorted? - fn from_proto_unsorted(mut data: Vec) -> Self { - data.sort_unstable_by(|entry1, entry2| { - let path1 = RepoPath::from_internal_string(&entry1.path); - let path2 = RepoPath::from_internal_string(&entry2.path); - path1.cmp(path2) - }); + fn from_proto( + mut data: Vec, + is_sorted: bool, + ) -> Self { + if !is_sorted { + data.sort_unstable_by(|entry1, entry2| { + let path1 = RepoPath::from_internal_string(&entry1.path); + let path2 = RepoPath::from_internal_string(&entry2.path); + path1.cmp(path2) + }); + } debug_assert!(is_file_state_entries_proto_unique_and_sorted(&data)); FileStatesMap { data } } @@ -610,7 +614,8 @@ impl TreeState { .collect(); self.tree_id = MergedTreeId::Merge(tree_ids_builder.build()); } - self.file_states = FileStatesMap::from_proto_unsorted(proto.file_states); + self.file_states = + FileStatesMap::from_proto(proto.file_states, proto.is_file_states_sorted); self.sparse_patterns = sparse_patterns_from_proto(proto.sparse_patterns.as_ref()); self.watchman_clock = proto.watchman_clock; Ok(()) @@ -630,6 +635,8 @@ impl TreeState { } proto.file_states = self.file_states.data.clone(); + // `FileStatesMap` is guaranteed to be sorted. + proto.is_file_states_sorted = true; let mut sparse_patterns = crate::protos::working_copy::SparsePatterns::default(); for path in &self.sparse_patterns { sparse_patterns @@ -1899,7 +1906,7 @@ mod tests { new_proto_entry("b/e", 3), new_proto_entry("bc", 5), ]; - let mut file_states = FileStatesMap::from_proto_unsorted(data); + let mut file_states = FileStatesMap::from_proto(data, false); let changed_file_states = vec![ new_owned_entry("aa", 10), // change diff --git a/lib/src/protos/working_copy.proto b/lib/src/protos/working_copy.proto index 536ca32e6..634c25da2 100644 --- a/lib/src/protos/working_copy.proto +++ b/lib/src/protos/working_copy.proto @@ -47,6 +47,7 @@ message TreeState { // single (positive) value repeated bytes tree_ids = 5; repeated FileStateEntry file_states = 2; + bool is_file_states_sorted = 6; SparsePatterns sparse_patterns = 3; WatchmanClock watchman_clock = 4; } diff --git a/lib/src/protos/working_copy.rs b/lib/src/protos/working_copy.rs index 4291e9549..90c1bfe67 100644 --- a/lib/src/protos/working_copy.rs +++ b/lib/src/protos/working_copy.rs @@ -38,6 +38,8 @@ pub struct TreeState { pub tree_ids: ::prost::alloc::vec::Vec<::prost::alloc::vec::Vec>, #[prost(message, repeated, tag = "2")] pub file_states: ::prost::alloc::vec::Vec, + #[prost(bool, tag = "6")] + pub is_file_states_sorted: bool, #[prost(message, optional, tag = "3")] pub sparse_patterns: ::core::option::Option, #[prost(message, optional, tag = "4")]