feat: experiment with different implementations of LSEQ

This commit is contained in:
nobody 2025-07-08 16:49:52 -07:00
commit 1e45ef9314
Signed by: GrocerPublishAgent
GPG key ID: D460CD54A9E3AB86
23 changed files with 3578 additions and 0 deletions

72
typescript/src/index.ts Normal file
View file

@ -0,0 +1,72 @@
const ALPHABET =
"-0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz";
function idToNumbers(id: string): number[] {
const nums = id.split("").map((char) => ALPHABET.indexOf(char));
return nums;
}
type Maybe<T> = T | null;
function isNone<T>(value: Maybe<T>): value is null {
return value === null;
}
export class LSEQ {
// true = allocate near min, false = allocate near max
private strategies: boolean[];
private random: () => number;
constructor(random: () => number = Math.random) {
this.random = random;
this.strategies = [random() < 0.5];
}
public alloc(before: Maybe<string>, after: Maybe<string>): string {
// Convert to numeric arrays, using boundary values for null
const p = isNone(before) ? [0] : idToNumbers(before);
const q = isNone(after) ? [63] : idToNumbers(after);
// Walk through digits looking for space
let depth = 0;
const result = [];
// eslint-disable-next-line no-constant-condition
while (true) {
const pVal = depth < p.length ? p[depth] : 0;
const qVal = depth < q.length ? q[depth] : 63;
const interval = qVal - pVal;
// If we have space between values at this depth
if (interval > 1) {
// Pick a value in the available range
const range = interval - 1;
const addVal = 1 + Math.floor(this.random() * range);
let newValue;
if (this.strategies[depth]) {
newValue = pVal + addVal;
} else {
newValue = qVal - addVal;
}
// Take the prefix from p up to depth and append our new value
result.push(newValue);
return result.map((n) => ALPHABET[n]).join("");
}
result.push(pVal);
// If values are the same or adjacent at this depth,
// continue to next depth
depth++;
if (depth > this.strategies.length) {
this.strategies.push(this.random() < 0.5);
}
}
}
}
export function compareLSEQ(a: string, b: string): number {
if (a === b) return 0;
return a < b ? -1 : 1;
}