Skip to content

Commit edc5516

Browse files
committed
Completely remove ExitDelimiter vertices
1 parent fef1454 commit edc5516

File tree

2 files changed

+119
-150
lines changed

2 files changed

+119
-150
lines changed

src/diff/dijkstra.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -253,7 +253,6 @@ mod tests {
253253
contiguous: false,
254254
probably_punctuation: false,
255255
},
256-
ExitDelimiter,
257256
]
258257
);
259258
}
@@ -303,7 +302,6 @@ mod tests {
303302
contiguous: false,
304303
probably_punctuation: false
305304
},
306-
ExitDelimiter,
307305
]
308306
);
309307
}
@@ -353,8 +351,6 @@ mod tests {
353351
UnchangedNode {
354352
depth_difference: 0
355353
},
356-
ExitDelimiter,
357-
ExitDelimiter,
358354
],
359355
);
360356
}
@@ -434,7 +430,6 @@ mod tests {
434430
contiguous: true,
435431
probably_punctuation: false
436432
},
437-
ExitDelimiter,
438433
]
439434
);
440435
}
@@ -476,7 +471,6 @@ mod tests {
476471
contiguous: true,
477472
probably_punctuation: false
478473
},
479-
ExitDelimiter,
480474
NovelAtomLHS {
481475
contiguous: true,
482476
probably_punctuation: true

src/diff/graph.rs

Lines changed: 119 additions & 144 deletions
Original file line numberDiff line numberDiff line change
@@ -315,20 +315,13 @@ pub enum Edge {
315315
EnterNovelDelimiterRHS {
316316
contiguous: bool,
317317
},
318-
ExitDelimiter,
319318
}
320319

321320
const NOT_CONTIGUOUS_PENALTY: u64 = 50;
322321

323322
impl Edge {
324323
pub fn cost(self) -> u64 {
325324
match self {
326-
// When we're at the end of a list, there's only one exit
327-
// delimiter possibility, so the cost doesn't matter. We
328-
// choose a non-zero number as it's easier to reason
329-
// about.
330-
ExitDelimiter => 1,
331-
332325
// Matching nodes is always best.
333326
UnchangedNode { depth_difference } => min(40, u64::from(depth_difference) + 1),
334327
// Matching an outer delimiter is good.
@@ -383,7 +376,6 @@ pub type SeenMap<'syn, 'b> = hashbrown::HashMap<
383376
BuildHasherDefault<FxHasher>,
384377
>;
385378

386-
#[inline(never)]
387379
fn allocate_if_new<'syn, 'b>(
388380
v: Vertex<'syn, 'b>,
389381
alloc: &'b Bump,
@@ -417,15 +409,46 @@ fn looks_like_punctuation(content: &str) -> bool {
417409
content == "," || content == ";" || content == "."
418410
}
419411

420-
fn skip_pop_either<'a>(
421-
mut syntax: &'a Syntax<'a>,
422-
mut stack: BitStack,
423-
) -> (SideSyntax<'a>, BitStack) {
424-
while let (None, Some(PopEither)) = (syntax.next_sibling(), stack.peek()) {
425-
syntax = syntax.parent().unwrap();
426-
stack = stack.pop();
412+
#[inline(always)]
413+
fn next_vertex<'a, 'b>(
414+
mut lhs_syntax: SideSyntax<'a>,
415+
mut rhs_syntax: SideSyntax<'a>,
416+
mut lhs_parent_stack: BitStack,
417+
mut rhs_parent_stack: BitStack,
418+
) -> Vertex<'a, 'b> {
419+
loop {
420+
while let (None, Some(PopEither)) = (lhs_syntax.get_side(), lhs_parent_stack.peek()) {
421+
lhs_syntax = next_sibling(lhs_syntax.parent().unwrap());
422+
lhs_parent_stack = lhs_parent_stack.pop();
423+
}
424+
425+
while let (None, Some(PopEither)) = (rhs_syntax.get_side(), rhs_parent_stack.peek()) {
426+
rhs_syntax = next_sibling(rhs_syntax.parent().unwrap());
427+
rhs_parent_stack = rhs_parent_stack.pop();
428+
}
429+
430+
if let (None, None, Some(PopBoth), Some(PopBoth)) = (
431+
lhs_syntax.get_side(),
432+
rhs_syntax.get_side(),
433+
lhs_parent_stack.peek(),
434+
rhs_parent_stack.peek(),
435+
) {
436+
lhs_syntax = next_sibling(lhs_syntax.parent().unwrap());
437+
rhs_syntax = next_sibling(rhs_syntax.parent().unwrap());
438+
lhs_parent_stack = lhs_parent_stack.pop();
439+
rhs_parent_stack = rhs_parent_stack.pop();
440+
} else {
441+
break;
442+
}
443+
}
444+
445+
Vertex {
446+
lhs_syntax,
447+
rhs_syntax,
448+
lhs_parent_stack,
449+
rhs_parent_stack,
450+
..Default::default()
427451
}
428-
(next_sibling(syntax), stack)
429452
}
430453

431454
/// Compute the neighbours of `v`.
@@ -445,49 +468,23 @@ pub fn get_neighbours<'syn, 'b>(
445468
},
446469
);
447470

448-
let v_info = (
449-
v.lhs_syntax.get_side(),
450-
v.rhs_syntax.get_side(),
451-
v.lhs_parent_stack.peek(),
452-
v.rhs_parent_stack.peek(),
453-
);
454-
455-
if let (None, None, Some(PopBoth), Some(PopBoth)) = v_info {
456-
// We have exhausted all the nodes on both lists, so we can
457-
// move up to the parent node.
458-
459-
// Continue from sibling of parent.
460-
add_neighbor(
461-
ExitDelimiter,
462-
Vertex {
463-
lhs_syntax: next_sibling(v.lhs_syntax.parent().unwrap()),
464-
rhs_syntax: next_sibling(v.rhs_syntax.parent().unwrap()),
465-
lhs_parent_stack: v.lhs_parent_stack.pop(),
466-
rhs_parent_stack: v.rhs_parent_stack.pop(),
467-
..Vertex::default()
468-
},
469-
);
470-
}
471+
let v_info = (v.lhs_syntax.get_side(), v.rhs_syntax.get_side());
471472

472-
if let (Some(lhs_syntax), Some(rhs_syntax), _, _) = v_info {
473+
if let (Some(lhs_syntax), Some(rhs_syntax)) = v_info {
473474
if lhs_syntax == rhs_syntax {
474475
let depth_difference = (lhs_syntax.num_ancestors() as i32
475476
- rhs_syntax.num_ancestors() as i32)
476477
.unsigned_abs();
477478

478-
let (next_lhs_syntax, next_lhs_stack) = skip_pop_either(lhs_syntax, v.lhs_parent_stack);
479-
let (next_rhs_syntax, next_rhs_stack) = skip_pop_either(rhs_syntax, v.rhs_parent_stack);
480-
481479
// Both nodes are equal, the happy case.
482480
add_neighbor(
483481
UnchangedNode { depth_difference },
484-
Vertex {
485-
lhs_syntax: next_lhs_syntax,
486-
rhs_syntax: next_rhs_syntax,
487-
lhs_parent_stack: next_lhs_stack,
488-
rhs_parent_stack: next_rhs_stack,
489-
..Vertex::default()
490-
},
482+
next_vertex(
483+
next_sibling(lhs_syntax),
484+
next_sibling(rhs_syntax),
485+
v.lhs_parent_stack,
486+
v.rhs_parent_stack,
487+
),
491488
);
492489
}
493490

@@ -515,13 +512,12 @@ pub fn get_neighbours<'syn, 'b>(
515512

516513
add_neighbor(
517514
EnterUnchangedDelimiter { depth_difference },
518-
Vertex {
519-
lhs_syntax: next_child(lhs_syntax, lhs_children),
520-
rhs_syntax: next_child(rhs_syntax, rhs_children),
521-
lhs_parent_stack: v.lhs_parent_stack.push(PopBoth),
522-
rhs_parent_stack: v.rhs_parent_stack.push(PopBoth),
523-
..Vertex::default()
524-
},
515+
next_vertex(
516+
next_child(lhs_syntax, lhs_children),
517+
next_child(rhs_syntax, rhs_children),
518+
v.lhs_parent_stack.push(PopBoth),
519+
v.rhs_parent_stack.push(PopBoth),
520+
),
525521
);
526522
}
527523
}
@@ -545,101 +541,83 @@ pub fn get_neighbours<'syn, 'b>(
545541
let levenshtein_pct =
546542
(normalized_levenshtein(lhs_content, rhs_content) * 100.0).round() as u8;
547543

548-
let (next_lhs_syntax, next_lhs_stack) =
549-
skip_pop_either(lhs_syntax, v.lhs_parent_stack);
550-
let (next_rhs_syntax, next_rhs_stack) =
551-
skip_pop_either(rhs_syntax, v.rhs_parent_stack);
552-
553544
add_neighbor(
554545
ReplacedComment { levenshtein_pct },
555-
Vertex {
556-
lhs_syntax: next_lhs_syntax,
557-
rhs_syntax: next_rhs_syntax,
558-
lhs_parent_stack: next_lhs_stack,
559-
rhs_parent_stack: next_rhs_stack,
560-
..Vertex::default()
561-
},
546+
next_vertex(
547+
next_sibling(lhs_syntax),
548+
next_sibling(rhs_syntax),
549+
v.lhs_parent_stack,
550+
v.rhs_parent_stack,
551+
),
562552
);
563553
}
564554
}
565555
}
566556

567-
if let (Some(lhs_syntax), _, _, _) = v_info {
568-
let (edge, child) = match lhs_syntax {
569-
Syntax::Atom { content, .. } => (
570-
NovelAtomLHS {
571-
// TODO: should this apply if prev is a parent
572-
// node rather than a sibling?
573-
contiguous: lhs_syntax.prev_is_contiguous(),
574-
probably_punctuation: looks_like_punctuation(content),
575-
},
576-
None,
577-
),
578-
Syntax::List { children, .. } => (
579-
EnterNovelDelimiterLHS {
580-
contiguous: lhs_syntax.prev_is_contiguous(),
581-
},
582-
children.get(0).copied(),
583-
),
584-
};
585-
586-
let (next_syntax, next_stack) = if let Some(child) = child {
587-
(
588-
SideSyntax::from_side(child),
589-
v.lhs_parent_stack.push(PopEither),
590-
)
591-
} else {
592-
skip_pop_either(lhs_syntax, v.lhs_parent_stack)
557+
if let (Some(lhs_syntax), _) = v_info {
558+
match lhs_syntax {
559+
Syntax::Atom { content, .. } => {
560+
add_neighbor(
561+
NovelAtomLHS {
562+
// TODO: should this apply if prev is a parent
563+
// node rather than a sibling?
564+
contiguous: lhs_syntax.prev_is_contiguous(),
565+
probably_punctuation: looks_like_punctuation(content),
566+
},
567+
next_vertex(
568+
next_sibling(lhs_syntax),
569+
v.rhs_syntax,
570+
v.lhs_parent_stack,
571+
v.rhs_parent_stack,
572+
),
573+
);
574+
}
575+
Syntax::List { children, .. } => {
576+
add_neighbor(
577+
EnterNovelDelimiterLHS {
578+
contiguous: lhs_syntax.prev_is_contiguous(),
579+
},
580+
next_vertex(
581+
next_child(lhs_syntax, children),
582+
v.rhs_syntax,
583+
v.lhs_parent_stack.push(PopEither),
584+
v.rhs_parent_stack,
585+
),
586+
);
587+
}
593588
};
594-
595-
add_neighbor(
596-
edge,
597-
Vertex {
598-
lhs_syntax: next_syntax,
599-
rhs_syntax: v.rhs_syntax,
600-
lhs_parent_stack: next_stack,
601-
rhs_parent_stack: v.rhs_parent_stack,
602-
..Vertex::default()
603-
},
604-
);
605589
}
606590

607-
if let (_, Some(rhs_syntax), _, _) = v_info {
608-
let (edge, child) = match rhs_syntax {
609-
Syntax::Atom { content, .. } => (
610-
NovelAtomRHS {
611-
contiguous: rhs_syntax.prev_is_contiguous(),
612-
probably_punctuation: looks_like_punctuation(content),
613-
},
614-
None,
615-
),
616-
Syntax::List { children, .. } => (
617-
EnterNovelDelimiterRHS {
618-
contiguous: rhs_syntax.prev_is_contiguous(),
619-
},
620-
children.get(0).copied(),
621-
),
622-
};
623-
624-
let (next_syntax, next_stack) = if let Some(child) = child {
625-
(
626-
SideSyntax::from_side(child),
627-
v.rhs_parent_stack.push(PopEither),
628-
)
629-
} else {
630-
skip_pop_either(rhs_syntax, v.rhs_parent_stack)
591+
if let (_, Some(rhs_syntax)) = v_info {
592+
match rhs_syntax {
593+
Syntax::Atom { content, .. } => {
594+
add_neighbor(
595+
NovelAtomRHS {
596+
contiguous: rhs_syntax.prev_is_contiguous(),
597+
probably_punctuation: looks_like_punctuation(content),
598+
},
599+
next_vertex(
600+
v.lhs_syntax,
601+
next_sibling(rhs_syntax),
602+
v.lhs_parent_stack,
603+
v.rhs_parent_stack,
604+
),
605+
);
606+
}
607+
Syntax::List { children, .. } => {
608+
add_neighbor(
609+
EnterNovelDelimiterRHS {
610+
contiguous: rhs_syntax.prev_is_contiguous(),
611+
},
612+
next_vertex(
613+
v.lhs_syntax,
614+
next_child(rhs_syntax, children),
615+
v.lhs_parent_stack,
616+
v.rhs_parent_stack.push(PopEither),
617+
),
618+
);
619+
}
631620
};
632-
633-
add_neighbor(
634-
edge,
635-
Vertex {
636-
lhs_syntax: v.lhs_syntax,
637-
rhs_syntax: next_syntax,
638-
lhs_parent_stack: v.lhs_parent_stack,
639-
rhs_parent_stack: next_stack,
640-
..Vertex::default()
641-
},
642-
);
643621
}
644622
}
645623

@@ -651,9 +629,6 @@ pub fn populate_change_map<'a, 'b>(
651629

652630
for (e, v) in route {
653631
match e {
654-
ExitDelimiter => {
655-
// Nothing to do: we have already marked this node when we entered it.
656-
}
657632
UnchangedNode { .. } => {
658633
// No change on this node or its children.
659634
let lhs = v.lhs_syntax.get_side().unwrap();

0 commit comments

Comments
 (0)