1
- use std:: ops:: Range ;
2
-
3
1
use crate :: histogram:: lcs:: find_lcs;
4
2
use crate :: histogram:: list_pool:: { ListHandle , ListPool } ;
5
3
use crate :: intern:: Token ;
6
- use crate :: util:: { strip_common_postfix, strip_common_prefix} ;
7
- use crate :: { myers, Sink } ;
4
+ use crate :: myers;
8
5
9
6
mod lcs;
10
7
mod list_pool;
@@ -16,17 +13,15 @@ struct Histogram {
16
13
pool : ListPool ,
17
14
}
18
15
19
- pub fn diff < S : Sink > (
20
- mut before : & [ Token ] ,
21
- mut after : & [ Token ] ,
16
+ pub fn diff (
17
+ before : & [ Token ] ,
18
+ after : & [ Token ] ,
19
+ removed : & mut [ bool ] ,
20
+ added : & mut [ bool ] ,
22
21
num_tokens : u32 ,
23
- mut sink : S ,
24
- ) -> S :: Out {
22
+ ) {
25
23
let mut histogram = Histogram :: new ( num_tokens) ;
26
- let prefix = strip_common_prefix ( & mut before, & mut after) ;
27
- strip_common_postfix ( & mut before, & mut after) ;
28
- histogram. run ( before, prefix, after, prefix, & mut sink) ;
29
- sink. finish ( )
24
+ histogram. run ( before, after, removed, added) ;
30
25
}
31
26
32
27
impl Histogram {
@@ -58,73 +53,49 @@ impl Histogram {
58
53
fn run (
59
54
& mut self ,
60
55
mut before : & [ Token ] ,
61
- mut before_off : u32 ,
62
56
mut after : & [ Token ] ,
63
- mut after_off : u32 ,
64
- sink : & mut impl Sink ,
57
+ mut removed : & mut [ bool ] ,
58
+ mut added : & mut [ bool ] ,
65
59
) {
66
60
loop {
67
61
if before. is_empty ( ) {
68
- if !after. is_empty ( ) {
69
- sink. process_change (
70
- before_off..before_off,
71
- after_off..after_off + after. len ( ) as u32 ,
72
- ) ;
73
- }
62
+ added. fill ( true ) ;
74
63
return ;
75
64
} else if after. is_empty ( ) {
76
- sink. process_change (
77
- before_off..before_off + before. len ( ) as u32 ,
78
- after_off..after_off,
79
- ) ;
65
+ removed. fill ( true ) ;
80
66
return ;
81
67
}
82
68
83
69
self . populate ( before) ;
84
70
match find_lcs ( before, after, self ) {
85
71
// no lcs was found, that means that file1 and file2 two have nothing in common
86
72
Some ( lcs) if lcs. len == 0 => {
87
- sink. process_change (
88
- before_off..before_off + before. len ( ) as u32 ,
89
- after_off..after_off + after. len ( ) as u32 ,
90
- ) ;
73
+ added. fill ( true ) ;
74
+ removed. fill ( true ) ;
91
75
return ;
92
76
}
93
77
Some ( lcs) => {
94
78
self . run (
95
79
& before[ ..lcs. before_start as usize ] ,
96
- before_off,
97
80
& after[ ..lcs. after_start as usize ] ,
98
- after_off ,
99
- sink ,
81
+ & mut removed [ ..lcs . before_start as usize ] ,
82
+ & mut added [ ..lcs . after_start as usize ] ,
100
83
) ;
101
84
102
85
// this is equivalent to (tail) recursion but implement as a loop for efficeny reasons
103
86
let before_end = lcs. before_start + lcs. len ;
104
87
before = & before[ before_end as usize ..] ;
105
- before_off += before_end;
88
+ removed = & mut removed [ before_end as usize .. ] ;
106
89
107
90
let after_end = lcs. after_start + lcs. len ;
108
91
after = & after[ after_end as usize ..] ;
109
- after_off += after_end;
92
+ added = & mut added [ after_end as usize .. ] ;
110
93
}
111
94
None => {
112
95
// we are diffing two extremely large repetitive files
113
96
// this is a worst case for histogram diff with O(N^2) performance
114
- // fallback to myers to maintain linear time complexity
115
- myers:: diff (
116
- before,
117
- after,
118
- 0 , // not used by myers
119
- |mut before : Range < u32 > , mut after : Range < u32 > | {
120
- before. start += before_off;
121
- before. end += before_off;
122
- after. start += after_off;
123
- after. end += after_off;
124
- sink. process_change ( before, after)
125
- } ,
126
- false ,
127
- ) ;
97
+ // fallback to myers to maintain linear time complxity
98
+ myers:: diff ( before, after, removed, added, false ) ;
128
99
return ;
129
100
}
130
101
}
0 commit comments