rustdoc: collapse edit distance state into an object

This commit is contained in:
Michael Howell 2023-03-11 20:36:43 -07:00
parent dfd9e5e3fa
commit ce795d9ca8

View file

@ -90,10 +90,11 @@ function printTab(nb) {
* algorithm should not matter to the caller of the methods, which is why it is not noted in the * algorithm should not matter to the caller of the methods, which is why it is not noted in the
* documentation. * documentation.
*/ */
let editDistanceCurrent = []; const editDistanceState = {
let editDistancePrev = []; current: [],
let editDistancePrevPrev = []; prev: [],
function editDistance(a, b, limit) { prevPrev: [],
calculate: function calculate(a, b, limit) {
// Ensure that `b` is the shorter string, minimizing memory use. // Ensure that `b` is the shorter string, minimizing memory use.
if (a.length < b.length) { if (a.length < b.length) {
const aTmp = a; const aTmp = a;
@ -130,14 +131,14 @@ function editDistance(a, b, limit) {
const bLength = b.length; const bLength = b.length;
for (let i = 0; i <= bLength; ++i) { for (let i = 0; i <= bLength; ++i) {
editDistanceCurrent[i] = 0; this.current[i] = 0;
editDistancePrev[i] = i; this.prev[i] = i;
editDistancePrevPrev[i] = Number.MAX_VALUE; this.prevPrev[i] = Number.MAX_VALUE;
} }
// row by row // row by row
for (let i = 1; i <= aLength; ++i) { for (let i = 1; i <= aLength; ++i) {
editDistanceCurrent[0] = i; this.current[0] = i;
const aIdx = i - 1; const aIdx = i - 1;
// column by column // column by column
@ -147,34 +148,39 @@ function editDistance(a, b, limit) {
// There is no cost to substitute a character with itself. // There is no cost to substitute a character with itself.
const substitutionCost = a[aIdx] === b[bIdx] ? 0 : 1; const substitutionCost = a[aIdx] === b[bIdx] ? 0 : 1;
editDistanceCurrent[j] = Math.min( this.current[j] = Math.min(
// deletion // deletion
editDistancePrev[j] + 1, this.prev[j] + 1,
// insertion // insertion
editDistanceCurrent[j - 1] + 1, this.current[j - 1] + 1,
// substitution // substitution
editDistancePrev[j - 1] + substitutionCost this.prev[j - 1] + substitutionCost
); );
if ((i > 1) && (j > 1) && (a[aIdx] === b[bIdx - 1]) && (a[aIdx - 1] === b[bIdx])) { if ((i > 1) && (j > 1) && (a[aIdx] === b[bIdx - 1]) && (a[aIdx - 1] === b[bIdx])) {
// transposition // transposition
editDistanceCurrent[j] = Math.min( this.current[j] = Math.min(
editDistanceCurrent[j], this.current[j],
editDistancePrevPrev[j - 2] + 1 this.prevPrev[j - 2] + 1
); );
} }
} }
// Rotate the buffers, reusing the memory // Rotate the buffers, reusing the memory
const prevPrevTmp = editDistancePrevPrev; const prevPrevTmp = this.prevPrev;
editDistancePrevPrev = editDistancePrev; this.prevPrev = this.prev;
editDistancePrev = editDistanceCurrent; this.prev = this.current;
editDistanceCurrent = prevPrevTmp; this.current = prevPrevTmp;
} }
// `prev` because we already rotated the buffers. // `prev` because we already rotated the buffers.
const distance = editDistancePrev[bLength]; const distance = this.prev[bLength];
return distance <= limit ? distance : (limit + 1); return distance <= limit ? distance : (limit + 1);
},
};
function editDistance(a, b, limit) {
return editDistanceState.calculate(a, b, limit);
} }
function initSearch(rawSearchIndex) { function initSearch(rawSearchIndex) {