feat: v0.2.4 异步Compaction + 槽位压缩 + EXPLAIN + 慢查询日志
CI / test (18.x) (push) Failing after 5m0s
CI / test (20.x) (push) Failing after 4m58s
CI / test (22.x) (push) Failing after 4m58s
CI / test (24.x) (push) Failing after 4m57s

This commit is contained in:
thzxx
2026-07-27 21:53:13 +08:00
parent da999d607b
commit 82e6baaae9
4 changed files with 104 additions and 2 deletions
+46
View File
@@ -128,6 +128,52 @@ export function freeSlot(buf: ArrayBuffer, slotIndex: number): void {
setSlotEntry(buf, slotIndex, { offset: 0, length: 0 });
}
/**
* 压缩页面槽位:移除已删除 slot,整理碎片空间。
* 将有效数据紧凑排列,释放空洞。
*/
export function compactSlots(buf: ArrayBuffer): number {
const view = new DataView(buf);
const slotCount = view.getUint16(9, false);
if (slotCount === 0) return 0;
// 收集有效 slotoffset>0 的)
const validSlots: { index: number; offset: number; length: number; data: Uint8Array }[] = [];
for (let i = 0; i < slotCount; i++) {
const entry = getSlotEntry(buf, i);
if (entry.offset > 0 && entry.length > 0) {
const data = new Uint8Array(buf, entry.offset, entry.length);
validSlots.push({ index: i, offset: entry.offset, length: entry.length, data: new Uint8Array(data) });
}
}
if (validSlots.length === slotCount) return 0; // 无碎片
// 从页面底部重新紧凑排列
let dataEnd = PAGE_SIZE;
const newSlots: { offset: number; length: number }[] = [];
for (let i = validSlots.length - 1; i >= 0; i--) {
const s = validSlots[i];
dataEnd -= s.length;
new Uint8Array(buf).set(s.data, dataEnd);
newSlots.unshift({ offset: dataEnd, length: s.length });
}
// 重写 slot directory
view.setUint16(9, validSlots.length, false); // slotCount
view.setUint16(7, dataEnd, false); // freeEnd
for (let i = 0; i < validSlots.length; i++) {
setSlotEntry(buf, i, newSlots[i]);
}
// 清除剩余 slot 条目
for (let i = validSlots.length; i < slotCount; i++) {
setSlotEntry(buf, i, { offset: 0, length: 0 });
}
return slotCount - validSlots.length; // 回收的 slot 数量
}
/**
* 读取指定 slot 的行数据。
*/