@wxn0brp/db-storage-bin 0.110.0-alpha.0 → 0.110.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +6 -0
- package/dist/bin/optimize.js +69 -32
- package/package.json +3 -3
package/README.md
CHANGED
package/dist/bin/optimize.js
CHANGED
|
@@ -1,40 +1,77 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { rename, rm } from "fs/promises";
|
|
2
|
+
import { BinManager } from "./index.js";
|
|
3
|
+
import { ensureCollection } from "./collection.js";
|
|
2
4
|
import { saveHeaderAndPayload } from "./head.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
+
import { INT_SIZE } from "./static.js";
|
|
6
|
+
import { readCollectionEof, readData, writeData } from "./utils.js";
|
|
5
7
|
import { _log } from "../log.js";
|
|
8
|
+
function isRemovedRecord(data) {
|
|
9
|
+
return new Uint8Array(data).every(byte => byte === 0);
|
|
10
|
+
}
|
|
11
|
+
async function appendRawRecord(target, collectionName, recordLengthBuffer, data) {
|
|
12
|
+
const collection = await ensureCollection(target, collectionName, data.length, true);
|
|
13
|
+
const collectionEOF = await readCollectionEof(target.fd, collection.offset);
|
|
14
|
+
const offset = collection.offset + collectionEOF + INT_SIZE;
|
|
15
|
+
await writeData(target.fd, offset, recordLengthBuffer, INT_SIZE);
|
|
16
|
+
await writeData(target.fd, offset + INT_SIZE, data, data.length);
|
|
17
|
+
const newEOF = collectionEOF + INT_SIZE + data.length;
|
|
18
|
+
const collectionLengthBuffer = Buffer.alloc(INT_SIZE);
|
|
19
|
+
collectionLengthBuffer.writeUInt32LE(newEOF, 0);
|
|
20
|
+
await writeData(target.fd, collection.offset, collectionLengthBuffer, INT_SIZE);
|
|
21
|
+
}
|
|
22
|
+
async function copyLiveRecords(source, target, collectionName, sourceOffset, collectionEOF) {
|
|
23
|
+
let readCursor = sourceOffset + INT_SIZE;
|
|
24
|
+
const endOffset = readCursor + collectionEOF;
|
|
25
|
+
while (readCursor < endOffset) {
|
|
26
|
+
const recordLengthBuffer = await readData(source.fd, readCursor, INT_SIZE);
|
|
27
|
+
const recordLength = recordLengthBuffer.readUInt32LE(0);
|
|
28
|
+
readCursor += INT_SIZE;
|
|
29
|
+
const data = await readData(source.fd, readCursor, recordLength);
|
|
30
|
+
readCursor += recordLength;
|
|
31
|
+
if (isRemovedRecord(data))
|
|
32
|
+
continue;
|
|
33
|
+
await appendRawRecord(target, collectionName, recordLengthBuffer, data);
|
|
34
|
+
}
|
|
35
|
+
}
|
|
6
36
|
export async function optimize(cmp) {
|
|
7
37
|
await _log(3, "Starting database optimization");
|
|
8
|
-
const collections = cmp.meta.collections;
|
|
9
|
-
const
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
38
|
+
const collections = [...cmp.meta.collections];
|
|
39
|
+
const tmpPath = `${cmp.path}.tmp`;
|
|
40
|
+
await _log(6, "Removing stale optimization temp file:", tmpPath);
|
|
41
|
+
await rm(tmpPath, { force: true });
|
|
42
|
+
const tmpMgr = new BinManager(tmpPath, cmp.options);
|
|
43
|
+
let tmpOpened = false;
|
|
44
|
+
let originalClosed = false;
|
|
45
|
+
try {
|
|
46
|
+
await tmpMgr.init();
|
|
47
|
+
tmpOpened = true;
|
|
48
|
+
const lengthBuffer = Buffer.alloc(INT_SIZE);
|
|
49
|
+
for (const { name, offset } of collections) {
|
|
50
|
+
await _log(6, "Optimizing collection:", name);
|
|
51
|
+
const collectionEOF = await readCollectionEof(cmp.fd, offset);
|
|
52
|
+
const collectionMeta = await ensureCollection(tmpMgr, name, 0, false);
|
|
53
|
+
lengthBuffer.writeUInt32LE(0, 0);
|
|
54
|
+
await writeData(tmpMgr.fd, collectionMeta.offset, lengthBuffer, INT_SIZE);
|
|
55
|
+
await copyLiveRecords(cmp, tmpMgr, name, offset, collectionEOF);
|
|
56
|
+
}
|
|
57
|
+
await saveHeaderAndPayload(tmpMgr);
|
|
58
|
+
await tmpMgr.close();
|
|
59
|
+
tmpOpened = false;
|
|
60
|
+
await _log(5, "Closing original file for optimization");
|
|
61
|
+
await cmp.close();
|
|
62
|
+
originalClosed = true;
|
|
63
|
+
await _log(5, "Replacing original database with optimized temp file");
|
|
64
|
+
await rename(tmpPath, cmp.path);
|
|
65
|
+
await cmp.init();
|
|
66
|
+
originalClosed = false;
|
|
15
67
|
}
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
let offset = roundUpCapacity(cmp.meta, cmp.meta.payloadLength + HEADER_SIZE) + cmp.meta.blockSize;
|
|
24
|
-
const lengthBuffer = Buffer.alloc(INT_SIZE);
|
|
25
|
-
for (const [collection, data] of allData) {
|
|
26
|
-
await _log(6, "Writing optimized collection:", collection);
|
|
27
|
-
const len = roundUpCapacity(cmp.meta, data.length + INT_SIZE);
|
|
28
|
-
lengthBuffer.writeInt32LE(data.length, 0);
|
|
29
|
-
await writeData(cmp.fd, offset, lengthBuffer, INT_SIZE);
|
|
30
|
-
await writeData(cmp.fd, offset + INT_SIZE, data, len);
|
|
31
|
-
cmp.meta.collections.push({
|
|
32
|
-
name: collection,
|
|
33
|
-
offset,
|
|
34
|
-
capacity: len
|
|
35
|
-
});
|
|
36
|
-
offset += len;
|
|
68
|
+
catch (err) {
|
|
69
|
+
if (tmpOpened)
|
|
70
|
+
await tmpMgr.close();
|
|
71
|
+
await rm(tmpPath, { force: true });
|
|
72
|
+
if (originalClosed)
|
|
73
|
+
await cmp.init();
|
|
74
|
+
throw err;
|
|
37
75
|
}
|
|
38
|
-
await saveHeaderAndPayload(cmp);
|
|
39
76
|
await _log(3, "Database optimization complete");
|
|
40
77
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wxn0brp/db-storage-bin",
|
|
3
|
-
"version": "0.110.0-alpha.
|
|
3
|
+
"version": "0.110.0-alpha.1",
|
|
4
4
|
"main": "dist/index.js",
|
|
5
5
|
"types": "dist/index.d.ts",
|
|
6
6
|
"author": "wxn0brP",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
],
|
|
20
20
|
"devDependencies": {
|
|
21
21
|
"@types/bun": "*",
|
|
22
|
-
"@wxn0brp/db-core": "^0.11.
|
|
22
|
+
"@wxn0brp/db-core": "^0.11.1-alpha.2",
|
|
23
23
|
"tsc-alias": "^1",
|
|
24
24
|
"typescript": "^6"
|
|
25
25
|
},
|
|
@@ -27,7 +27,7 @@
|
|
|
27
27
|
"@msgpack/msgpack": "^3.1.3"
|
|
28
28
|
},
|
|
29
29
|
"peerDependencies": {
|
|
30
|
-
"@wxn0brp/db-core": "^0.11.
|
|
30
|
+
"@wxn0brp/db-core": "^0.11.1-alpha.2"
|
|
31
31
|
},
|
|
32
32
|
"files": [
|
|
33
33
|
"dist"
|