feat: v0.2.4 异步Compaction + 槽位压缩 + EXPLAIN + 慢查询日志
This commit is contained in:
@@ -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;
|
||||
|
||||
// 收集有效 slot(offset>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 的行数据。
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user