๐Ÿ”

ํ…์ŠคํŠธ Diff & ๋ณ€๊ฒฝ์  ๋น„๊ต๊ธฐ Text Diff

์ขŒ์šฐ ๋Œ€์กฐ ํ™”๋ฉด์—์„œ ๋ณ€๊ฒฝ์ ์„ ํ™•์ธํ•˜๊ณ , ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ๋กœ ์ž์œ ๋กญ๊ฒŒ ์„ ํƒํ•˜์—ฌ ๋ณต์‚ฌยท์‚ญ์ œยทํŽธ์ง‘ํ•˜์„ธ์š”

์ธ๋ผ์ธ ๊ฐ•์กฐ:
0 ์ถ”๊ฐ€0 ์‚ญ์ œ0 ์ˆ˜์ •0 ๋ธ”๋ก์œ ์‚ฌ๋„ 100%
ORIGINAL์›๋ณธ (Before)0์ค„ ยท 0์ž
โœ๏ธ ํด๋ฆญํ•˜์—ฌ ํŽธ์ง‘ ยท ๋“œ๋ž˜๊ทธํ•˜์—ฌ ์„ ํƒ
๐Ÿ“„ ํŒŒ์ผ์„ ์—ฌ๊ธฐ์— ๋†“์œผ์„ธ์š”
MODIFIED์ˆ˜์ •๋ณธ (After)0์ค„ ยท 0์ž
โœ๏ธ ํด๋ฆญํ•˜์—ฌ ํŽธ์ง‘ ยท ๋“œ๋ž˜๊ทธํ•˜์—ฌ ์„ ํƒ
๐Ÿ“„ ํŒŒ์ผ์„ ์—ฌ๊ธฐ์— ๋†“์œผ์„ธ์š”
โšก

๋น„๊ต๊ธฐ์— ์ ์šฉ๋œ ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜ & ์•„ํ‚คํ…์ฒ˜

๋ฐ€๋ฆฌ์ดˆ ๋‹จ์œ„์˜ ์‹ค์‹œ๊ฐ„ ๋Œ€์กฐ์™€ ๋ฌด์†์‹ค ์ธ๋ผ์ธ ํŽธ์ง‘์„ ๊ตฌํ˜„ํ•˜๋Š” 4๊ฐ€์ง€ ์ปดํ“จํ„ฐ ๊ณผํ•™ ์›๋ฆฌ

๋™์  ๊ณ„ํš๋ฒ• (DP)O(M ร— N)

1. LCS (์ตœ์žฅ ๊ณตํ†ต ๋ถ€๋ถ„ ์ˆ˜์—ด) & Myers Diff

๋‘ ํ…์ŠคํŠธ ์‹œํ€€์Šค ์‚ฌ์ด์—์„œ ์ˆœ์„œ๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ์ผ์น˜ํ•˜๋Š” ๊ฐ€์žฅ ๊ธด ๋ถ€๋ถ„ ์ˆ˜์—ด์„ ์ฐพ๋Š” ํ•ต์‹ฌ ์•Œ๊ณ ๋ฆฌ์ฆ˜์ž…๋‹ˆ๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ํšจ์œจ์ ์ธ Uint32Array 2์ฐจ์› DP ํ…Œ์ด๋ธ”์„ ๊ตฌ์ถ•ํ•˜์—ฌ ์ตœ์†Œ ํŽธ์ง‘ ๊ฑฐ๋ฆฌ(Edit Distance)๋ฅผ ์—ญ์ถ”์ ํ•˜๊ณ , ์ถ”๊ฐ€(Insert)ยท์‚ญ์ œ(Delete)ยท์ผ์น˜(Equal) ๋ธ”๋ก์„ ์™„๋ฒฝํ•˜๊ฒŒ ํŒ๋ณ„ํ•ฉ๋‹ˆ๋‹ค.

DP[i+1][j+1] = eq(A[i], B[j]) ? DP[i][j] + 1 : Math.max(DP[i+1][j], DP[i][j+1])
  • ์ค„ ๋‹จ์œ„ 1์ฐจ ๋น„๊ต ๋ฐ ๋ณ€๊ฒฝ ์ฒญํฌ(Chunk) ๋ถ„ํ• 
  • ๊ณต๋ฐฑยท๋Œ€์†Œ๋ฌธ์žยท๋นˆ์ค„ ์˜ต์…˜๋ณ„ ์ •๊ทœํ™” ์ „์ฒ˜๋ฆฌ ๋ฐ˜์˜
2๋‹จ๊ณ„ ๊ณ„์ธตํ˜• ์ •๋ฐ€ ๋ถ„์„ํ† ํฌ๋‚˜์ด์ €

2. ๋‹ค๋‹จ๊ณ„ ์ธ๋ผ์ธ ํ† ํฐ ํ•˜์ด๋ผ์ดํŠธ

์ค„ ๋‹จ์œ„ ๋น„๊ต๊ฐ€ ๋๋‚œ ํ›„, ๋ณ€๊ฒฝ๋œ(Modified) ์ค„ ๋‚ด๋ถ€์—์„œ ๋‹ค์‹œ 2์ฐจ LCS๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š” ๊ณ„์ธตํ˜• ์•„ํ‚คํ…์ฒ˜์ž…๋‹ˆ๋‹ค. ์ •๊ทœ์‹์„ ํ†ตํ•ด ํ•œ๊ธ€ ์Œ์ ˆ, ์˜์–ด ๋‹จ์–ด, ๊ณต๋ฐฑ, ํŠน์ˆ˜๊ธฐํ˜ธ๋ฅผ ํ† ํฐํ™”ํ•˜์—ฌ ์ค„ ์ „์ฒด๊ฐ€ ์•„๋‹Œ ์‹ค์ œ ๋ฐ”๋€ ๋‹จ์–ดยท๋ฌธ์ž ๋ถ€๋ถ„๋งŒ ์ •๋ฐ€ํ•˜๊ฒŒ ๊ฐ•์กฐํ•ฉ๋‹ˆ๋‹ค.

Regex: /(\s+|[a-zA-Z0-9_\u3131-\ud79d]+|[^\s\w])/g
  • ๋‹จ์–ด(Word) / ๋ฌธ์ž(Char) / ์ค„ ์ „์ฒด(Line) ๋ชจ๋“œ ์ „ํ™˜
  • <span class="hw-del"> & <span class="hw-ins"> ์ธ๋ผ์ธ ์ƒ‰์ƒ ๋งคํ•‘
๊ฐ€์ƒ ์ •๋ ฌ ๋งคํŠธ๋ฆญ์Šค1:1 ์ˆ˜ํ‰ ๋Œ€์นญ

3. ๊ฐ€์ƒ ์ŠคํŽ˜์ด์„œ(Ghost Spacer) ์ •๋ ฌ

ํ•œ์ชฝ ํŒจ๋„์— ์ค„ ์ถ”๊ฐ€๋‚˜ ์‚ญ์ œ๊ฐ€ ์ƒ๊ธฐ๋ฉด ๋งž์€ํŽธ์— ๋น—์‚ด๋ฌด๋Šฌ ๋นˆ ๊ณต๊ฐ„(.dline-empty)์„ ๋™์ ์œผ๋กœ ์ƒ์„ฑํ•˜์—ฌ ์ขŒ์šฐ ๋Œ€์กฐ ์ค„ ๋ฒˆํ˜ธ์™€ ํ–‰ ๋†’์ด๋ฅผ ํ•ญ์ƒ 1:1 ์ˆ˜ํ‰์œผ๋กœ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ๋นˆ ๊ณต๊ฐ„ ํด๋ฆญ ์‹œ ์ค„์ด ๋ฐ€๋ฆฌ๊ฑฐ๋‚˜ ์ƒˆ ์ค„์ด ์ถ”๊ฐ€๋˜์ง€ ์•Š๊ณ  ํ•ด๋‹น ํ–‰์—์„œ ์ฆ‰์‹œ ์ธ๋ผ์ธ ์ˆ˜์ • ์ƒํƒœ๋กœ ํ™œ์„ฑํ™”๋ฉ๋‹ˆ๋‹ค.

left: { n: d.n, t: 'del' } โ†” right: { n: null, t: 'empty', insertIdx }
  • ์™„๋ฒฝํ•œ ์–‘๋ฐฉํ–ฅ ๋™๊ธฐํ™” ์Šคํฌ๋กค (Sync Scroll) ์œ ์ง€
  • ๋นˆ ๊ณต๊ฐ„ ํด๋ฆญ ์‹œ ์ค„ ๋ฐ€๋ฆผ ์—†์ด ํ•ด๋‹น ์œ„์น˜์—์„œ ์ฆ‰์‹œ ์ธ๋ผ์ธ ์ˆ˜์ • ๋ชจ๋“œ ํ™œ์„ฑํ™”
๋ฐ˜์‘ํ˜• ์ƒํƒœ ๋จธ์‹ ์‹ค์‹œ๊ฐ„ ํŽธ์ง‘

4. ์ƒํƒœ ๋™๊ธฐํ™” & ๋‹ค์ค‘ ์ค„ ์„ ํƒ ๋ชจ๋ธ

๋‹จ์ผ ํ™œ์„ฑ ์ธ๋ผ์ธ ์—๋””ํ„ฐ์™€ ์ „์ฒด ํ…์ŠคํŠธ ๋ชจ๋ธ(linesA, linesB)์„ ์™„๋ฒฝํžˆ ๋ถ„๋ฆฌํ•˜๊ณ , 250ms ๋””๋ฐ”์šด์Šค ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ํƒ€์ดํ•‘ ์ง€์—ฐ ์—†์ด ๋ฐฑ๊ทธ๋ผ์šด๋“œ ์žฌ๊ณ„์‚ฐ์„ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ๋งˆ์šฐ์Šค ๋“œ๋ž˜๊ทธ ์‹œ ์‹œ์ž‘/๋ ์ค„๊ณผ ์—ด์„ ์ถ”์ ํ•˜๋Š” ์„ ํƒ ๋ชจ๋ธ์„ ํ†ตํ•ด ์ผ๊ด„ ๋ณต์‚ฌยท์‚ญ์ œยท์น˜ํ™˜์„ ์ง€์›ํ•ฉ๋‹ˆ๋‹ค.

Selection: { side, startLine, startCol, endLine, endCol }
  • ์‹ค์‹œ๊ฐ„ Diff ์žฌ๊ณ„์‚ฐ ์ค‘์—๋„ ์ปค์„œ ์œ„์น˜(Caret Offset) ๋ฌด์†์‹ค ์œ ์ง€
  • ๋ฏธ๋‹ˆ ํ”Œ๋กœํŒ… ์•ก์…˜ ๋ฐ”(๋ณต์‚ฌยท์ž˜๋ผ๋‚ด๊ธฐยท์‚ญ์ œ) ๋ฐ ๋‹จ์ถ•ํ‚ค ํ†ตํ•ฉ
Diff ์ฒ˜๋ฆฌ ํŒŒ์ดํ”„๋ผ์ธ (Execution Pipeline)
1
์ •๊ทœํ™” & ์ „์ฒ˜๋ฆฌ๊ณต๋ฐฑยท์ •๊ทœ์‹ยท๋Œ€์†Œ๋ฌธ์ž
โžœ
2
1์ฐจ LCS ์ค„ ๋Œ€์กฐ๋™์  ๊ณ„ํš๋ฒ• ์ตœ์†Œ ํŽธ์ง‘ ๊ฑฐ๋ฆฌ
โžœ
3
์ŠคํŽ˜์ด์„œ ์ˆ˜ํ‰ ์ •๋ ฌ์ขŒ์šฐ ๋Œ€์นญ ํ–‰ ๋งคํŠธ๋ฆญ์Šค
โžœ
4
2์ฐจ ์ธ๋ผ์ธ ํ† ํฐํ™”๋‹จ์–ดยท๋ฌธ์ž ๋‹จ์œ„ ํ•˜์ด๋ผ์ดํŠธ
โžœ
5
๋ฐ˜์‘ํ˜• ์ธ๋ผ์ธ ๋ Œ๋”์‹ค์‹œ๊ฐ„ ํŽธ์ง‘ & ๋“œ๋ž˜๊ทธ ์„ ํƒ
๐Ÿ’ฌ

์˜๊ฒฌ ๋ฐ ์งˆ๋ฌธ

0
0 / 1500