diff --git a/notify-debouncer-full/src/lib.rs b/notify-debouncer-full/src/lib.rs index 0996fd66..64395b1d 100644 --- a/notify-debouncer-full/src/lib.rs +++ b/notify-debouncer-full/src/lib.rs @@ -244,16 +244,44 @@ impl DebounceDataInner { self.queues = queues_remaining; // order events for different files chronologically, but keep the order of events for the same file - events_expired.sort_by(|event_a, event_b| { - // use the last path because rename events are emitted for the target path - if event_a.paths.last() == event_b.paths.last() { - std::cmp::Ordering::Equal - } else { - event_a.time.cmp(&event_b.time) + // concatenate neighbour events with same last path to one group + let mut concatenated_events_expired = Vec::with_capacity(events_expired.len()); + let mut it = events_expired.into_iter(); + if let Some(event) = it.next() { + concatenated_events_expired.push(vec![event]); + for event in it { + if event + .paths + .last() + .zip( + concatenated_events_expired + .last() + // it is safe to call unwrap here because concatenated_events_expired contains at least one element + .unwrap() + .last() + .and_then(|event| event.paths.last()), + ) + .filter(|(curr, prev)| curr == prev) + .is_some() + { + // Previous last path is equal to current last path, so appending events in one group + // it is safe to call unwrap here because concatenated_events_expired contains at least one element + concatenated_events_expired.last_mut().unwrap().push(event); + } else { + concatenated_events_expired.push(vec![event]); + } } - }); + } - events_expired + // Sort groups lexicographically by time + concatenated_events_expired.sort_by(|vec_a, vec_b| { + vec_a + .iter() + .map(|event_a| event_a.time) + .cmp(vec_b.iter().map(|event_b| event_b.time)) + }); + // Flatten vec of groups of events to vec of events + concatenated_events_expired.into_iter().flatten().collect() } /// Returns all currently stored errors diff --git a/notify-debouncer-full/test_cases/emit_events_in_chronological_order.hjson b/notify-debouncer-full/test_cases/emit_events_in_chronological_order.hjson index ac728487..fa3160f6 100644 --- a/notify-debouncer-full/test_cases/emit_events_in_chronological_order.hjson +++ b/notify-debouncer-full/test_cases/emit_events_in_chronological_order.hjson @@ -34,11 +34,11 @@ events: { long: [ { kind: "modify-data-content", paths: ["/watch/file-a"], time: 1 } + { kind: "modify-metadata-write-time", paths: ["/watch/file-a"], time: 9 } { kind: "modify-data-content", paths: ["/watch/file-b"], time: 3 } - { kind: "modify-data-content", paths: ["/watch/file-c"], time: 4 } { kind: "modify-metadata-write-time", paths: ["/watch/file-b"], time: 7 } + { kind: "modify-data-content", paths: ["/watch/file-c"], time: 4 } { kind: "modify-metadata-write-time", paths: ["/watch/file-c"], time: 8 } - { kind: "modify-metadata-write-time", paths: ["/watch/file-a"], time: 9 } ] } }