Skip to content

Commit 7443e11

Browse files
committed
dofs: Match SQLite filename ordering
1 parent 31d6662 commit 7443e11

2 files changed

Lines changed: 33 additions & 1 deletion

File tree

packages/dofs/src/fs/readdir.test.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,30 @@ describe("readdir", () => {
116116
});
117117
});
118118

119+
it("keeps UTF-8 filename pages stable when a pending file commits", async () => {
120+
await withDB(async (db) => {
121+
const bmpName = "\uE000";
122+
const astralName = "\u{10000}";
123+
await writeFile(db, `/${bmpName}`, "committed", {}, () => 0);
124+
openWriteBufferForCreateSync(db, `/${astralName}`, {}, () => 1);
125+
126+
expect(readdir(db, "/", { limit: 1, offset: 0 }).map((entry) => entry.name)).toEqual([
127+
bmpName,
128+
]);
129+
expect(readdir(db, "/", { limit: 1, offset: 1 }).map((entry) => entry.name)).toEqual([
130+
astralName,
131+
]);
132+
133+
releaseWriteBufferSync(db, `/${astralName}`, () => 2);
134+
expect(readdir(db, "/", { limit: 1, offset: 0 }).map((entry) => entry.name)).toEqual([
135+
bmpName,
136+
]);
137+
expect(readdir(db, "/", { limit: 1, offset: 1 }).map((entry) => entry.name)).toEqual([
138+
astralName,
139+
]);
140+
});
141+
});
142+
119143
it("rejects invalid offsets", async () => {
120144
await withDB((db) => {
121145
expect(() => readdir(db, "/", { offset: -1 })).toThrowError(

packages/dofs/src/fs/readdir.ts

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,14 @@ function toResult(db: Database, parentPath: string, row: DirentRow): WorkspaceDi
147147
};
148148
}
149149

150+
const filenameEncoder = new TextEncoder();
151+
150152
function compareByName(a: WorkspaceDirentResult, b: WorkspaceDirentResult): number {
151-
return a.name < b.name ? -1 : a.name > b.name ? 1 : 0;
153+
const left = filenameEncoder.encode(a.name);
154+
const right = filenameEncoder.encode(b.name);
155+
const length = Math.min(left.byteLength, right.byteLength);
156+
for (let index = 0; index < length; index += 1) {
157+
if (left[index] !== right[index]) return left[index] - right[index];
158+
}
159+
return left.byteLength - right.byteLength;
152160
}

0 commit comments

Comments
 (0)