1 use crate::histogram
::{Histogram, MAX_CHAIN_LEN}
;
2 use crate::intern
::Token
;
4 pub(super) fn find_lcs(
7 histogram
: &mut Histogram
,
10 LcsSearch { lcs: Lcs::default(), min_occurances: MAX_CHAIN_LEN + 1, found_cs: false }
;
11 search
.run(before
, after
, histogram
);
19 #[derive(Default, Debug)]
21 pub before_start
: u32,
26 pub struct LcsSearch
{
33 fn run(&mut self, before
: &[Token
], after
: &[Token
], histogram
: &mut Histogram
) {
35 while let Some(&token
) = after
.get(pos
as usize) {
36 if histogram
.num_token_occurances(token
) != 0 {
38 if histogram
.num_token_occurances(token
) <= self.min_occurances
{
39 pos
= self.update_lcs(pos
, token
, histogram
, before
, after
);
50 fn success(&mut self) -> bool
{
51 !self.found_cs
|| self.min_occurances
<= MAX_CHAIN_LEN
58 histogram
: &Histogram
,
62 let mut next_token_idx2
= after_pos
+ 1;
63 let mut occurances_iter
= histogram
.token_occurances(token
).iter().copied();
64 let mut token_idx1
= occurances_iter
.next().unwrap();
66 'occurances_iter
: loop {
67 let mut occurances
= histogram
.num_token_occurances(token
);
68 let mut start1
= token_idx1
;
69 let mut start2
= after_pos
;
71 if start1
== 0 || start2
== 0 {
74 let token1
= before
.get(start1
as usize - 1);
75 let token2
= after
.get(start2
as usize - 1);
76 if matches
!((token1
, token2
), (Some(token1
), Some(token2
)) if token1
== token2
) {
79 let new_occurances
= histogram
.num_token_occurances(before
[start1
as usize]);
80 occurances
= occurances
.min(new_occurances
);
86 let mut end1
= token_idx1
+ 1;
87 let mut end2
= after_pos
+ 1;
90 let token1
= before
.get(end1
as usize);
91 let token2
= after
.get(end2
as usize);
92 if matches
!((token1
, token2
), (Some(token1
), Some(token2
)) if token1
== token2
) {
93 let new_occurances
= histogram
.num_token_occurances(before
[end1
as usize]);
94 occurances
= occurances
.min(new_occurances
);
102 if next_token_idx2
< end2
{
103 next_token_idx2
= end2
;
106 let len
= end2
- start2
;
107 debug_assert_eq
!(len
, end1
- start1
);
108 if self.lcs
.len
< len
|| self.min_occurances
> occurances
{
109 self.min_occurances
= occurances
;
110 self.lcs
= Lcs { before_start: start1, after_start: start2, len }
;
114 if let Some(next_token_idx
) = occurances_iter
.next() {
115 if next_token_idx
> end2
{
116 token_idx1
= next_token_idx
;
120 break 'occurances_iter
;