fix(infra): fix fractional indexing edge cases (#8978)

This commit is contained in:
EYHN 2024-12-02 05:31:07 +00:00
parent cee5d02f71
commit 84210dd197
No known key found for this signature in database
GPG Key ID: 46C9E26A75AB276C
2 changed files with 21 additions and 1 deletions

View File

@ -57,3 +57,19 @@ test('no postfix', () => {
generateFractionalIndexingKeyBetween('a0', 'a01').startsWith('a00V')
).toBe(true);
});
test('edge cases', () => {
for (let i = 0; i < 100; i++) {
let a = generateFractionalIndexingKeyBetween(null, null);
let b = generateFractionalIndexingKeyBetween(null, null);
if (a > b) {
[a, b] = [b, a];
}
const c = generateFractionalIndexingKeyBetween(a, b);
const d = generateFractionalIndexingKeyBetween(c, b);
expect(a < c).toBeTruthy();
expect(c < b).toBeTruthy();
expect(c < d).toBeTruthy();
expect(d < b).toBeTruthy();
}
});

View File

@ -1,5 +1,9 @@
import { generateKeyBetween } from 'fractional-indexing';
function hasSamePrefix(a: string, b: string) {
return a.startsWith(b) || b.startsWith(a);
}
/**
* generate a key between a and b, the result key is always satisfied with a < result < b.
* the key always has a random suffix, so there is no need to worry about collision.
@ -59,7 +63,7 @@ export function generateFractionalIndexingKeyBetween(
return generateKeyBetween(aSubkey, null) + '0' + postfix();
} else if (aSubkey !== null && bSubkey !== null) {
// generate a key between a and b
if (aSubkey === bSubkey && a !== null && b !== null) {
if (hasSamePrefix(aSubkey, bSubkey) && a !== null && b !== null) {
// conflict, if the subkeys are the same, generate a key between fullkeys
return generateKeyBetween(a, b) + '0' + postfix();
} else {