2121 Report : ParallelReporter < Size > + Sync ,
2222 Size : size:: Size + Into < u64 > + Serialize + Send + Sync ,
2323 SizeGetter : GetSize < Size = Size > + Copy + Sync ,
24- Hook : hook:: Hook < Size > + Copy + Sync ,
24+ Hook : hook:: Hook < Size > + DeduplicateHardlinkSizes < Size > + Copy + Sync ,
2525 DataTreeReflection < String , Size > : Into < UnitAndTree > ,
2626{
2727 /// List of files and/or directories.
4242 pub size_getter : SizeGetter ,
4343 /// Hook to run after [`Self::size_getter`].
4444 pub hook : Hook ,
45+ /// Record of detected hardlinks.
46+ pub hardlink_record : Hook :: HardlinkRecord ,
4547 /// Reports measurement progress.
4648 pub reporter : Report ,
4749 /// Minimal size proportion required to appear.
5557 Size : size:: Size + Into < u64 > + Serialize + Send + Sync ,
5658 Report : ParallelReporter < Size > + Sync ,
5759 SizeGetter : GetSize < Size = Size > + Copy + Sync ,
58- Hook : hook:: Hook < Size > + Copy + Sync ,
60+ Hook : hook:: Hook < Size > + DeduplicateHardlinkSizes < Size > + Copy + Sync ,
5961 DataTreeReflection < String , Size > : Into < UnitAndTree > ,
6062{
6163 /// Run the sub program.
7072 max_depth,
7173 size_getter,
7274 hook,
75+ hardlink_record,
7376 reporter,
7477 min_ratio,
7578 no_sort,
9699 return Sub {
97100 files : vec ! [ "." . into( ) ] ,
98101 hook,
102+ hardlink_record,
99103 reporter,
100104 ..self
101105 }
@@ -120,15 +124,17 @@ where
120124 }
121125
122126 let min_ratio: f32 = min_ratio. into ( ) ;
123- let data_tree = {
127+ let ( data_tree, deduplication_record ) = {
124128 let mut data_tree = data_tree;
125129 if min_ratio > 0.0 {
126130 data_tree. par_cull_insignificant_data ( min_ratio) ;
127131 }
128132 if !no_sort {
129133 data_tree. par_sort_by ( |left, right| left. size ( ) . cmp ( & right. size ( ) ) . reverse ( ) ) ;
130134 }
131- data_tree
135+ let deduplication_record =
136+ Hook :: deduplicate_hardlink_sizes ( & mut data_tree, hardlink_record) ;
137+ ( data_tree, deduplication_record)
132138 } ;
133139
134140 GLOBAL_STATUS_BOARD . clear_line ( 0 ) ;
@@ -157,6 +163,64 @@ where
157163 } ;
158164
159165 print ! ( "{visualizer}" ) ; // visualizer already ends with "\n", println! isn't needed here.
166+ Hook :: report_deduplication_results ( deduplication_record) ;
160167 Ok ( ( ) )
161168 }
162169}
170+
171+ /// Subroutines used by [`Sub`] to deduplicate sizes of detected hardlinks and report about it.
172+ pub trait DeduplicateHardlinkSizes < Size : size:: Size > {
173+ /// Record of detected hardlinks.
174+ type HardlinkRecord ;
175+ /// Report created by [`DeduplicateHardlinkSizes::deduplicate_hardlink_sizes`].
176+ type DeduplicationReport ;
177+ /// Deduplicate the sizes of detected hardlinks and return a report object.
178+ fn deduplicate_hardlink_sizes (
179+ data_tree : & mut DataTree < OsStringDisplay , Size > ,
180+ record : Self :: HardlinkRecord ,
181+ ) -> Self :: DeduplicationReport ;
182+ /// Handle the report.
183+ fn report_deduplication_results ( report : Self :: DeduplicationReport ) ;
184+ }
185+
186+ #[ cfg( unix) ]
187+ impl < ' a , Size > DeduplicateHardlinkSizes < Size > for hook:: RecordHardLink < ' a , Size >
188+ where
189+ DataTree < OsStringDisplay , Size > : Send ,
190+ Size : size:: Size + Sync ,
191+ {
192+ type HardlinkRecord = & ' a dashmap:: DashMap < u64 , ( Size , Vec < PathBuf > ) > ;
193+ type DeduplicationReport = ( ) ; // TODO
194+
195+ fn deduplicate_hardlink_sizes (
196+ data_tree : & mut DataTree < OsStringDisplay , Size > ,
197+ record : Self :: HardlinkRecord ,
198+ ) -> Self :: DeduplicationReport {
199+ use std:: path:: { Path , PathBuf } ;
200+ let hardlink_info: Vec < ( Size , Vec < PathBuf > ) > = record
201+ . iter ( )
202+ . map ( |values| ( values. 0 , values. 1 . clone ( ) ) )
203+ . collect ( ) ;
204+ let hardlink_info: Vec < ( Size , Vec < & Path > ) > = hardlink_info
205+ . iter ( )
206+ . map ( |( size, paths) | ( * size, paths. iter ( ) . map ( AsRef :: as_ref) . collect ( ) ) )
207+ . collect ( ) ;
208+ data_tree. par_deduplicate_hardlinks ( & hardlink_info) ;
209+ }
210+ fn report_deduplication_results ( ( ) : Self :: DeduplicationReport ) { } // TODO
211+ }
212+
213+ impl < Size > DeduplicateHardlinkSizes < Size > for hook:: DoNothing
214+ where
215+ DataTree < OsStringDisplay , Size > : Send ,
216+ Size : size:: Size + Sync ,
217+ {
218+ type HardlinkRecord = ( ) ;
219+ type DeduplicationReport = ( ) ;
220+ fn deduplicate_hardlink_sizes (
221+ _: & mut DataTree < OsStringDisplay , Size > ,
222+ _: Self :: HardlinkRecord ,
223+ ) -> Self :: DeduplicationReport {
224+ }
225+ fn report_deduplication_results ( ( ) : Self :: DeduplicationReport ) { }
226+ }
0 commit comments