Fix edge cases

This commit is contained in:
Andras Schmelczer 2025-11-22 20:14:31 +00:00
parent c3c2cafde5
commit a57ed5c4ae
3 changed files with 28 additions and 6 deletions

View file

@ -49,14 +49,17 @@ export class Locks<T> {
fn: () => R | Promise<R>
): Promise<R> {
const keys = Array.isArray(keyOrKeys) ? keyOrKeys : [keyOrKeys];
keys.sort((a, b) => String(a).localeCompare(String(b))); // Ensure consistent order to prevent deadlocks
await Promise.all(keys.map(async (key) => this.waitForLock(key)));
// Deduplicate keys to prevent deadlock from acquiring same lock twice
const uniqueKeys = Array.from(new Set(keys));
uniqueKeys.sort((a, b) => String(a).localeCompare(String(b))); // Ensure consistent order to prevent deadlocks
await Promise.all(uniqueKeys.map(async (key) => this.waitForLock(key)));
try {
return await fn();
} finally {
keys.forEach((key) => {
uniqueKeys.forEach((key) => {
this.unlock(key);
});
}

View file

@ -48,15 +48,29 @@ describe("CoveredValues", () => {
assert.strictEqual(covered.min, 6);
});
it("should handle force setting min value", () => {
it("should auto-advance when setting min value", () => {
const covered = new CoveredValues(5);
covered.add(7);
covered.add(8);
covered.add(9);
assert.strictEqual(covered.min, 5);
// Setting min to 6 should auto-advance through 7, 8, 9
covered.min = 6;
assert.strictEqual(covered.min, 6);
assert.strictEqual(covered.min, 9);
covered.add(10);
assert.strictEqual(covered.min, 10);
});
it("should handle setting min value with no consecutive values", () => {
const covered = new CoveredValues(5);
covered.add(10);
covered.add(15);
assert.strictEqual(covered.min, 5);
// Setting min to 8 should not auto-advance (no consecutive values)
covered.min = 8;
assert.strictEqual(covered.min, 8);
// Add 9 to trigger auto-advance to 10
covered.add(9);
assert.strictEqual(covered.min, 10);
});
});

View file

@ -24,7 +24,8 @@ export class CoveredValues {
public set min(value: number) {
this.minValue = Math.max(value, this.minValue);
this.seenValues = this.seenValues.filter((v) => v > value);
this.seenValues = this.seenValues.filter((v) => v > this.minValue);
this.advanceMinWhilePossible();
}
public add(value: number): void {
@ -45,6 +46,10 @@ export class CoveredValues {
this.seenValues.splice(i, 0, value);
}
this.advanceMinWhilePossible();
}
private advanceMinWhilePossible(): void {
while (
this.seenValues.length > 0 &&
this.seenValues[0] === this.minValue + 1