@based/db 0.0.68 → 0.0.70
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 -1
- package/dist/lib/darwin_aarch64/include/selva/fields.h +0 -9
- package/dist/lib/darwin_aarch64/include/selva_error.h +4 -1
- package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v24.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/fields.h +0 -9
- package/dist/lib/linux_aarch64/include/selva_error.h +4 -1
- package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v24.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/fields.h +0 -9
- package/dist/lib/linux_x86_64/include/selva_error.h +4 -1
- package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v24.node +0 -0
- package/dist/lib/linux_x86_64/libselva.so +0 -0
- package/dist/src/client/modify/alias.js +4 -0
- package/dist/src/client/modify/binary.d.ts +1 -1
- package/dist/src/client/modify/binary.js +22 -7
- package/dist/src/client/modify/create.js +91 -39
- package/dist/src/client/modify/fixed.d.ts +3 -3
- package/dist/src/client/modify/fixed.js +80 -20
- package/dist/src/client/modify/json.js +7 -0
- package/dist/src/client/modify/modify.js +3 -3
- package/dist/src/client/modify/references/edge.js +3 -3
- package/dist/src/client/modify/string.d.ts +1 -1
- package/dist/src/client/modify/string.js +17 -7
- package/dist/src/client/modify/text.d.ts +1 -1
- package/dist/src/client/modify/text.js +27 -15
- package/dist/src/client/modify/types.d.ts +2 -1
- package/dist/src/client/modify/types.js +6 -0
- package/dist/src/client/modify/update.js +5 -1
- package/dist/src/client/query/display.js +1 -1
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +3 -0
- package/dist/src/client/query/filter/createReferenceFilter.js +3 -0
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +21 -19
- package/dist/src/client/query/read/read.js +9 -10
- package/dist/src/native.d.ts +1 -0
- package/dist/src/native.js +3 -0
- package/dist/src/server/IoWorker.d.ts +16 -0
- package/dist/src/server/IoWorker.js +32 -3
- package/dist/src/server/QueryWorker.js +2 -2
- package/dist/src/server/blocks.d.ts +3 -1
- package/dist/src/server/blocks.js +31 -7
- package/dist/src/server/index.d.ts +1 -1
- package/dist/src/server/index.js +8 -11
- package/dist/src/server/migrate/index.js +25 -11
- package/dist/src/server/migrate/worker.js +70 -62
- package/dist/src/server/save.d.ts +7 -1
- package/dist/src/server/save.js +107 -50
- package/dist/src/server/schema.d.ts +1 -1
- package/dist/src/server/schema.js +6 -2
- package/dist/src/server/start.js +11 -5
- package/dist/src/server/tree.d.ts +11 -0
- package/dist/src/server/tree.js +0 -1
- package/dist/src/server/workers/DbWorker.d.ts +3 -2
- package/dist/src/server/workers/DbWorker.js +2 -1
- package/dist/src/server/workers/io_worker.js +22 -17
- package/dist/src/server/workers/io_worker_types.d.ts +9 -1
- package/dist/src/server/workers/worker.js +11 -3
- package/dist/src/types.d.ts +1 -0
- package/dist/src/types.js +1 -0
- package/dist/src/utils.js +1 -1
- package/package.json +5 -3
- package/dist/lib/darwin_aarch64/libjemalloc_selva.so.2 +0 -0
- package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
- package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
package/dist/src/server/save.js
CHANGED
|
@@ -3,7 +3,7 @@ import { isMainThread } from 'node:worker_threads';
|
|
|
3
3
|
import { writeFile } from 'node:fs/promises';
|
|
4
4
|
import { join } from 'node:path';
|
|
5
5
|
import { VerifTree, destructureTreeKey, } from './tree.js';
|
|
6
|
-
import { saveBlock, foreachBlock, foreachDirtyBlock, } from './blocks.js';
|
|
6
|
+
import { saveBlock, foreachBlock, foreachDirtyBlock, saveBlocks, } from './blocks.js';
|
|
7
7
|
import { writeFileSync } from 'node:fs';
|
|
8
8
|
import { bufToHex } from '@saulx/utils';
|
|
9
9
|
import { COMMON_SDB_FILE, WRITELOG_FILE } from '../types.js';
|
|
@@ -14,22 +14,56 @@ function hasPartialTypes(db) {
|
|
|
14
14
|
}
|
|
15
15
|
return res;
|
|
16
16
|
}
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
17
|
+
function inhibitSave(db, { skipDirtyCheck, forceFullDump, skipMigrationCheck }) {
|
|
18
|
+
// RFE isMainThread needed??
|
|
19
|
+
if (!(isMainThread && (skipDirtyCheck || db.dirtyRanges.size || forceFullDump))) {
|
|
20
|
+
return true;
|
|
20
21
|
}
|
|
21
22
|
if (forceFullDump && hasPartialTypes(db)) {
|
|
22
23
|
db.emit('error', 'forceFullDump is not allowed with partial types');
|
|
23
|
-
return;
|
|
24
|
+
return true;
|
|
24
25
|
}
|
|
25
26
|
if (db.migrating && !skipMigrationCheck) {
|
|
26
27
|
db.emit('info', 'Block save db is migrating');
|
|
27
|
-
return;
|
|
28
|
+
return true;
|
|
28
29
|
}
|
|
29
30
|
if (db.saveInProgress) {
|
|
30
31
|
db.emit('info', 'Already have a save in progress cancel save');
|
|
31
|
-
return;
|
|
32
|
+
return true;
|
|
33
|
+
}
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
function makeWritelog(db, ts) {
|
|
37
|
+
const types = {};
|
|
38
|
+
const rangeDumps = {};
|
|
39
|
+
for (const key in db.schemaTypesParsed) {
|
|
40
|
+
const { id, lastId, blockCapacity } = db.schemaTypesParsed[key];
|
|
41
|
+
types[id] = { lastId, blockCapacity };
|
|
42
|
+
rangeDumps[id] = [];
|
|
32
43
|
}
|
|
44
|
+
db.verifTree.foreachBlock((block) => {
|
|
45
|
+
const [typeId, start] = destructureTreeKey(block.key);
|
|
46
|
+
const def = db.schemaTypesParsedById[typeId];
|
|
47
|
+
const end = start + def.blockCapacity - 1;
|
|
48
|
+
const data = {
|
|
49
|
+
file: db.verifTree.getBlockFile(block),
|
|
50
|
+
hash: bufToHex(block.hash),
|
|
51
|
+
start,
|
|
52
|
+
end,
|
|
53
|
+
};
|
|
54
|
+
rangeDumps[typeId].push(data);
|
|
55
|
+
});
|
|
56
|
+
return {
|
|
57
|
+
ts,
|
|
58
|
+
types,
|
|
59
|
+
commonDump: COMMON_SDB_FILE,
|
|
60
|
+
rangeDumps,
|
|
61
|
+
hash: bufToHex(db.verifTree.hash), // TODO `hash('hex')`
|
|
62
|
+
};
|
|
63
|
+
}
|
|
64
|
+
export function saveSync(db, opts = {}) {
|
|
65
|
+
if (inhibitSave(db, opts))
|
|
66
|
+
return;
|
|
33
67
|
let ts = Date.now();
|
|
34
68
|
db.saveInProgress = true;
|
|
35
69
|
try {
|
|
@@ -39,7 +73,7 @@ export function save(db, sync = false, forceFullDump = false, skipMigrationCheck
|
|
|
39
73
|
db.emit('error', `Save common failed: ${err}`);
|
|
40
74
|
// Return ?
|
|
41
75
|
}
|
|
42
|
-
if (forceFullDump) {
|
|
76
|
+
if (opts.forceFullDump) {
|
|
43
77
|
// reset the state just in case
|
|
44
78
|
db.verifTree = new VerifTree(db.schemaTypesParsed);
|
|
45
79
|
// We use db.verifTree.types instead of db.schemaTypesParsed because it's
|
|
@@ -53,58 +87,81 @@ export function save(db, sync = false, forceFullDump = false, skipMigrationCheck
|
|
|
53
87
|
foreachDirtyBlock(db, (_mtKey, typeId, start, end) => saveBlock(db, typeId, start, end));
|
|
54
88
|
}
|
|
55
89
|
db.dirtyRanges.clear();
|
|
56
|
-
const
|
|
57
|
-
const rangeDumps = {};
|
|
58
|
-
for (const key in db.schemaTypesParsed) {
|
|
59
|
-
const { id, lastId, blockCapacity } = db.schemaTypesParsed[key];
|
|
60
|
-
types[id] = { lastId, blockCapacity };
|
|
61
|
-
rangeDumps[id] = [];
|
|
62
|
-
}
|
|
63
|
-
db.verifTree.foreachBlock((block) => {
|
|
64
|
-
const [typeId, start] = destructureTreeKey(block.key);
|
|
65
|
-
const def = db.schemaTypesParsedById[typeId];
|
|
66
|
-
const end = start + def.blockCapacity - 1;
|
|
67
|
-
const data = {
|
|
68
|
-
file: db.verifTree.getBlockFile(block),
|
|
69
|
-
hash: bufToHex(block.hash),
|
|
70
|
-
start,
|
|
71
|
-
end,
|
|
72
|
-
};
|
|
73
|
-
rangeDumps[typeId].push(data);
|
|
74
|
-
});
|
|
75
|
-
const data = {
|
|
76
|
-
ts,
|
|
77
|
-
types,
|
|
78
|
-
commonDump: COMMON_SDB_FILE,
|
|
79
|
-
rangeDumps,
|
|
80
|
-
hash: bufToHex(db.verifTree.hash), // TODO `hash('hex')`
|
|
81
|
-
};
|
|
82
|
-
const filePath = join(db.fileSystemPath, WRITELOG_FILE);
|
|
90
|
+
const data = makeWritelog(db, ts);
|
|
83
91
|
const content = JSON.stringify(data);
|
|
84
|
-
db.emit('info', `Save
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
92
|
+
db.emit('info', `Save took ${Date.now() - ts}ms`);
|
|
93
|
+
db.saveInProgress = false;
|
|
94
|
+
return writeFileSync(join(db.fileSystemPath, WRITELOG_FILE), content);
|
|
95
|
+
}
|
|
96
|
+
catch (err) {
|
|
97
|
+
db.emit('error', `Save failed ${err.message}`);
|
|
98
|
+
db.saveInProgress = false;
|
|
99
|
+
throw err;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
export async function save(db, opts = {}) {
|
|
103
|
+
if (inhibitSave(db, opts))
|
|
104
|
+
return;
|
|
105
|
+
let ts = Date.now();
|
|
106
|
+
db.saveInProgress = true;
|
|
107
|
+
try {
|
|
108
|
+
let err;
|
|
109
|
+
err = native.saveCommon(join(db.fileSystemPath, COMMON_SDB_FILE), db.dbCtxExternal);
|
|
110
|
+
if (err) {
|
|
111
|
+
db.emit('error', `Save common failed: ${err}`);
|
|
112
|
+
// Return ?
|
|
113
|
+
}
|
|
114
|
+
const blocks = [];
|
|
115
|
+
if (opts.forceFullDump) {
|
|
116
|
+
// reset the state just in case
|
|
117
|
+
db.verifTree = new VerifTree(db.schemaTypesParsed);
|
|
118
|
+
// We use db.verifTree.types instead of db.schemaTypesParsed because it's
|
|
119
|
+
// ordered.
|
|
120
|
+
for (const { typeId } of db.verifTree.types()) {
|
|
121
|
+
const def = db.schemaTypesParsedById[typeId];
|
|
122
|
+
foreachBlock(db, def, (start, end, _hash) => {
|
|
123
|
+
const typeId = def.id;
|
|
124
|
+
const file = VerifTree.blockSdbFile(typeId, start, end);
|
|
125
|
+
const filepath = join(db.fileSystemPath, file);
|
|
126
|
+
blocks.push({
|
|
127
|
+
filepath,
|
|
128
|
+
typeId,
|
|
129
|
+
start,
|
|
130
|
+
});
|
|
131
|
+
});
|
|
132
|
+
}
|
|
88
133
|
}
|
|
89
134
|
else {
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
db.emit('error', `Save: writing writeLog failed ${err.message}`);
|
|
98
|
-
db.saveInProgress = false;
|
|
99
|
-
reject(err);
|
|
135
|
+
foreachDirtyBlock(db, (_mtKey, typeId, start, end) => {
|
|
136
|
+
const file = VerifTree.blockSdbFile(typeId, start, end);
|
|
137
|
+
const filepath = join(db.fileSystemPath, file);
|
|
138
|
+
blocks.push({
|
|
139
|
+
filepath,
|
|
140
|
+
typeId,
|
|
141
|
+
start
|
|
100
142
|
});
|
|
101
143
|
});
|
|
102
144
|
}
|
|
145
|
+
db.dirtyRanges.clear();
|
|
146
|
+
await saveBlocks(db, blocks);
|
|
147
|
+
try {
|
|
148
|
+
// Note that we assume here that verifTree didn't change before we call
|
|
149
|
+
// makeWritelog(). This is true as long as db.saveInProgress protects
|
|
150
|
+
// the verifTree from changes.
|
|
151
|
+
const data = makeWritelog(db, ts);
|
|
152
|
+
await writeFile(join(db.fileSystemPath, WRITELOG_FILE), JSON.stringify(data));
|
|
153
|
+
}
|
|
154
|
+
catch (err) {
|
|
155
|
+
db.emit('error', `Save: writing writeLog failed ${err.message}`);
|
|
156
|
+
}
|
|
157
|
+
db.emit('info', `Save took ${Date.now() - ts}ms`);
|
|
103
158
|
}
|
|
104
159
|
catch (err) {
|
|
105
160
|
db.emit('error', `Save failed ${err.message}`);
|
|
106
|
-
db.saveInProgress = false;
|
|
107
161
|
throw err;
|
|
108
162
|
}
|
|
163
|
+
finally {
|
|
164
|
+
db.saveInProgress = false;
|
|
165
|
+
}
|
|
109
166
|
}
|
|
110
167
|
//# sourceMappingURL=save.js.map
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
+
import { StrictSchema } from '@based/schema';
|
|
1
2
|
import { DbServer } from './index.js';
|
|
2
3
|
import { DbSchema } from '../schema.js';
|
|
3
|
-
import { StrictSchema } from '@based/schema';
|
|
4
4
|
export declare const setSchemaOnServer: (server: DbServer, schema: DbSchema) => void;
|
|
5
5
|
export declare const writeSchemaFile: (server: DbServer, schema: DbSchema) => Promise<void>;
|
|
6
6
|
export declare const setNativeSchema: (server: DbServer, schema: DbSchema) => void;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { schemaToSelvaBuffer, updateTypeDefs } from '@based/schema/def';
|
|
2
|
+
import { deepCopy, writeUint64 } from '@saulx/utils';
|
|
3
|
+
import { getPropType, serialize } from '@based/schema';
|
|
2
4
|
import { join } from 'node:path';
|
|
3
5
|
import { writeFile } from 'node:fs/promises';
|
|
4
6
|
import native from '../native.js';
|
|
5
7
|
import { makeTreeKey } from './tree.js';
|
|
6
|
-
import { deepCopy, writeUint64 } from '@saulx/utils';
|
|
7
8
|
import { SCHEMA_FILE } from '../types.js';
|
|
9
|
+
import { saveSync } from './save.js';
|
|
8
10
|
import { hash } from '@saulx/hash';
|
|
9
|
-
import { getPropType, serialize } from '@based/schema';
|
|
10
11
|
export const setSchemaOnServer = (server, schema) => {
|
|
11
12
|
const { schemaTypesParsed, schemaTypesParsedById } = updateTypeDefs(schema);
|
|
12
13
|
server.schema = schema;
|
|
@@ -55,6 +56,9 @@ export const setNativeSchema = (server, schema) => {
|
|
|
55
56
|
//server.verifTree = new VerifTree(.schemaTypesParsed)
|
|
56
57
|
}
|
|
57
58
|
server.verifTree.updateTypes(server.schemaTypesParsed);
|
|
59
|
+
if (server.fileSystemPath) {
|
|
60
|
+
saveSync(server, { skipDirtyCheck: true });
|
|
61
|
+
}
|
|
58
62
|
};
|
|
59
63
|
export const strictSchemaToDbSchema = (schema) => {
|
|
60
64
|
// @ts-ignore
|
package/dist/src/server/start.js
CHANGED
|
@@ -7,11 +7,11 @@ import { join } from 'node:path';
|
|
|
7
7
|
import { VerifTree, makeTreeKey } from './tree.js';
|
|
8
8
|
import { foreachBlock } from './blocks.js';
|
|
9
9
|
import exitHook from 'exit-hook';
|
|
10
|
-
import { save } from './save.js';
|
|
10
|
+
import { save, saveSync } from './save.js';
|
|
11
11
|
import { deSerialize } from '@based/schema';
|
|
12
12
|
import { BLOCK_CAPACITY_DEFAULT } from '@based/schema/def';
|
|
13
13
|
import { bufToHex, equals, hexToBuf, wait } from '@saulx/utils';
|
|
14
|
-
import { SCHEMA_FILE, WRITELOG_FILE } from '../types.js';
|
|
14
|
+
import { SCHEMA_FILE, WRITELOG_FILE, SCHEMA_FILE_DEPRECATED } from '../types.js';
|
|
15
15
|
import { setSchemaOnServer } from './schema.js';
|
|
16
16
|
function startWorkers(db, opts) {
|
|
17
17
|
const queryThreads = opts?.queryThreads ?? availableParallelism();
|
|
@@ -42,11 +42,17 @@ export async function start(db, opts) {
|
|
|
42
42
|
console.error(e.message);
|
|
43
43
|
throw e;
|
|
44
44
|
}
|
|
45
|
-
const schema = await readFile(join(path, SCHEMA_FILE));
|
|
45
|
+
const schema = await readFile(join(path, SCHEMA_FILE)).catch(noop);
|
|
46
46
|
if (schema) {
|
|
47
47
|
const s = deSerialize(schema);
|
|
48
48
|
setSchemaOnServer(db, s);
|
|
49
49
|
}
|
|
50
|
+
else {
|
|
51
|
+
const schemaJson = await readFile(join(path, SCHEMA_FILE_DEPRECATED));
|
|
52
|
+
if (schemaJson) {
|
|
53
|
+
setSchemaOnServer(db, JSON.parse(schemaJson.toString()));
|
|
54
|
+
}
|
|
55
|
+
}
|
|
50
56
|
// Load all range dumps
|
|
51
57
|
for (const typeId in writelog.rangeDumps) {
|
|
52
58
|
const dumps = writelog.rangeDumps[typeId];
|
|
@@ -111,7 +117,7 @@ export async function start(db, opts) {
|
|
|
111
117
|
// in Node.js.
|
|
112
118
|
signals.forEach((sig) => process.on(sig, blockSig));
|
|
113
119
|
db.emit('info', `Exiting with signal: ${signal}`);
|
|
114
|
-
|
|
120
|
+
saveSync(db);
|
|
115
121
|
db.emit('info', 'Successfully saved.');
|
|
116
122
|
signals.forEach((sig) => process.off(sig, blockSig));
|
|
117
123
|
});
|
|
@@ -121,7 +127,7 @@ export async function start(db, opts) {
|
|
|
121
127
|
// use timeout
|
|
122
128
|
if (db.saveIntervalInSeconds > 0) {
|
|
123
129
|
db.saveInterval ??= setInterval(() => {
|
|
124
|
-
|
|
130
|
+
save(db);
|
|
125
131
|
}, db.saveIntervalInSeconds * 1e3);
|
|
126
132
|
}
|
|
127
133
|
if (db.schema) {
|
|
@@ -6,8 +6,19 @@ export declare const makeTreeKeyFromNodeId: (typeId: number, blockCapacity: numb
|
|
|
6
6
|
type Hash = Uint8Array;
|
|
7
7
|
export type VerifBlock = {
|
|
8
8
|
key: number;
|
|
9
|
+
/**
|
|
10
|
+
* Last acquired hash of the block.
|
|
11
|
+
* This is normally updated at load and save time but never during read/modify ops.
|
|
12
|
+
*/
|
|
9
13
|
hash: Hash;
|
|
14
|
+
/**
|
|
15
|
+
* If false the block is offloaded to fs;
|
|
16
|
+
* true doesn't necessarily mean that the block still exists because it could have been deleted.
|
|
17
|
+
*/
|
|
10
18
|
inmem: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* If set, the block is being loaded and it can be awaited with this promise.
|
|
21
|
+
*/
|
|
11
22
|
loadPromise: null | Promise<void>;
|
|
12
23
|
};
|
|
13
24
|
export declare class VerifTree {
|
package/dist/src/server/tree.js
CHANGED
|
@@ -1,12 +1,13 @@
|
|
|
1
|
+
import { MessagePort } from 'node:worker_threads';
|
|
1
2
|
import { DbServer } from '../index.js';
|
|
2
3
|
export declare abstract class DbWorker {
|
|
3
4
|
constructor(address: BigInt, db: DbServer, onExit: (code: number) => void, workerName: string);
|
|
4
5
|
protected db: DbServer;
|
|
5
|
-
|
|
6
|
+
protected channel: MessagePort;
|
|
6
7
|
private worker;
|
|
7
8
|
protected resolvers: ((x: any) => any)[];
|
|
8
9
|
readyPromise: Promise<true>;
|
|
9
|
-
terminate(): Promise<
|
|
10
|
+
terminate(): Promise<void>;
|
|
10
11
|
abstract handleMsg(buf: any): void;
|
|
11
12
|
protected callback: (resolve: (x: any) => any) => void;
|
|
12
13
|
/**
|
|
@@ -53,7 +53,8 @@ export class DbWorker {
|
|
|
53
53
|
resolvers = [];
|
|
54
54
|
readyPromise;
|
|
55
55
|
async terminate() {
|
|
56
|
-
|
|
56
|
+
// TODO do we want to force this.worker.terminate() after a timeout?
|
|
57
|
+
await this.call(0n);
|
|
57
58
|
}
|
|
58
59
|
callback = (resolve) => {
|
|
59
60
|
this.resolvers.push(resolve);
|
|
@@ -1,14 +1,8 @@
|
|
|
1
1
|
import { registerMsgHandler } from './worker.js';
|
|
2
|
-
import {
|
|
2
|
+
import { writeInt32 } from '@saulx/utils';
|
|
3
3
|
import native from '../../native.js';
|
|
4
4
|
function loadBlock(dbCtx, filepath) {
|
|
5
|
-
|
|
6
|
-
native.loadBlock(filepath, dbCtx);
|
|
7
|
-
}
|
|
8
|
-
catch (e) {
|
|
9
|
-
// need to get rid of the shared buffer
|
|
10
|
-
return new Uint8Array(ENCODER.encode(e.toString())).buffer;
|
|
11
|
-
}
|
|
5
|
+
native.loadBlock(filepath, dbCtx);
|
|
12
6
|
return null;
|
|
13
7
|
}
|
|
14
8
|
function unloadBlock(dbCtx, filepath, typeId, start) {
|
|
@@ -25,15 +19,26 @@ function unloadBlock(dbCtx, filepath, typeId, start) {
|
|
|
25
19
|
return buf;
|
|
26
20
|
}
|
|
27
21
|
registerMsgHandler((dbCtx, msg) => {
|
|
28
|
-
if (typeof msg?.type
|
|
29
|
-
|
|
30
|
-
if (job.type === 'load') {
|
|
31
|
-
return loadBlock(dbCtx, job.filepath);
|
|
32
|
-
}
|
|
33
|
-
else if (job.type === 'unload') {
|
|
34
|
-
return unloadBlock(dbCtx, job.filepath, job.typeId, job.start);
|
|
35
|
-
}
|
|
22
|
+
if (typeof msg?.type !== 'string') {
|
|
23
|
+
throw new Error('Invalid message');
|
|
36
24
|
}
|
|
37
|
-
|
|
25
|
+
const job = msg;
|
|
26
|
+
if (job.type === 'save') {
|
|
27
|
+
const LEN = 20;
|
|
28
|
+
return job.blocks.reduce((buf, block, index) => {
|
|
29
|
+
const errCodeBuf = new Uint8Array(buf, index * LEN, 4);
|
|
30
|
+
const hash = new Uint8Array(buf, index * LEN + 4, 16);
|
|
31
|
+
const err = native.saveBlock(block.filepath, block.typeId, block.start, dbCtx, hash);
|
|
32
|
+
writeInt32(errCodeBuf, err, 0);
|
|
33
|
+
return buf;
|
|
34
|
+
}, new ArrayBuffer(job.blocks.length * LEN));
|
|
35
|
+
}
|
|
36
|
+
else if (job.type === 'load') {
|
|
37
|
+
return loadBlock(dbCtx, job.filepath);
|
|
38
|
+
}
|
|
39
|
+
else if (job.type === 'unload') {
|
|
40
|
+
return unloadBlock(dbCtx, job.filepath, job.typeId, job.start);
|
|
41
|
+
}
|
|
42
|
+
throw new Error(`Unsupported type: "${msg.type}"`);
|
|
38
43
|
});
|
|
39
44
|
//# sourceMappingURL=io_worker.js.map
|
|
@@ -1,3 +1,11 @@
|
|
|
1
|
+
export type IoJobSave = {
|
|
2
|
+
type: 'save';
|
|
3
|
+
blocks: {
|
|
4
|
+
filepath: string;
|
|
5
|
+
typeId: number;
|
|
6
|
+
start: number;
|
|
7
|
+
}[];
|
|
8
|
+
};
|
|
1
9
|
type IoJobLoad = {
|
|
2
10
|
type: 'load';
|
|
3
11
|
filepath: string;
|
|
@@ -8,5 +16,5 @@ type IoJobUnload = {
|
|
|
8
16
|
typeId: number;
|
|
9
17
|
start: number;
|
|
10
18
|
};
|
|
11
|
-
export type IoJob = IoJobLoad | IoJobUnload;
|
|
19
|
+
export type IoJob = IoJobSave | IoJobLoad | IoJobUnload;
|
|
12
20
|
export {};
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import { isMainThread, parentPort, workerData } from 'node:worker_threads';
|
|
2
|
+
import { nextTick } from 'node:process';
|
|
2
3
|
import native from '../../native.js';
|
|
3
4
|
let dbCtx;
|
|
4
5
|
let wCtx; // This must be held until the worker exits otherwise the ctx will be autofreed instantly
|
|
@@ -21,9 +22,16 @@ export function registerMsgHandler(onMsg) {
|
|
|
21
22
|
const handleMsg = (msg) => {
|
|
22
23
|
try {
|
|
23
24
|
if (typeof msg === 'bigint') {
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
if (msg === 0n) {
|
|
26
|
+
// terminate
|
|
27
|
+
nextTick(() => typeof self === 'undefined' ? process.exit() : self.close());
|
|
28
|
+
channel.postMessage(null);
|
|
29
|
+
}
|
|
30
|
+
else {
|
|
31
|
+
// it's a ctx address
|
|
32
|
+
dbCtx = native.externalFromInt(msg);
|
|
33
|
+
channel.postMessage(null);
|
|
34
|
+
}
|
|
27
35
|
}
|
|
28
36
|
else {
|
|
29
37
|
// a message to the worker handler
|
package/dist/src/types.d.ts
CHANGED
package/dist/src/types.js
CHANGED
package/dist/src/utils.js
CHANGED
|
@@ -42,5 +42,5 @@ export const debugMode = (target, getInfo = null) => {
|
|
|
42
42
|
}
|
|
43
43
|
}
|
|
44
44
|
};
|
|
45
|
-
export const debugServer = (server) => debugMode(server, () => `p: ${server.
|
|
45
|
+
export const debugServer = (server) => debugMode(server, () => `p: ${server.activeReaders} m: ${server.modifyQueue.length} q: ${server.queryQueue.size}`);
|
|
46
46
|
//# sourceMappingURL=utils.js.map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@based/db",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.70",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/src/index.js",
|
|
@@ -20,6 +20,7 @@
|
|
|
20
20
|
"test": "npm run build && LOCPATH=../locale/locale-x86_64-gnu/locale ./scripts/lldb-node ./scripts/test.js",
|
|
21
21
|
"test-gdb": "npm run build && LOCPATH=../locale/locale-x86_64-gnu/locale gdb -ex run --args node ./scripts/test.js",
|
|
22
22
|
"test-fast": "LOCPATH=../locale/locale-x86_64-gnu/locale node ./scripts/test.js",
|
|
23
|
+
"test-fast-linux_aarch64-schema": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; npm run test-fast schemadebug'",
|
|
23
24
|
"test-fast-linux_aarch64": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; npm run test-fast'",
|
|
24
25
|
"test-fast-linux_aarch64-gdb": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; LOCPATH=../locale/locale-x86_64-gnu/locale gdb -ex run --args node ./scripts/test.js'",
|
|
25
26
|
"test-fast-linux_aarch64-valgrind": "podman run --rm -v \"$PWD/../..:/usr/src/based-db\" based-db-clibs-build-linux_aarch64 sh -c '\\. \"/usr/local/nvm/nvm.sh\"; cd /usr/src/based-db/packages/db; LOCPATH=../locale/locale-aarch64-gnu/locale valgrind --leak-check=full node ./scripts/test.js references:update2'",
|
|
@@ -38,7 +39,7 @@
|
|
|
38
39
|
"basedDbNative.cjs"
|
|
39
40
|
],
|
|
40
41
|
"dependencies": {
|
|
41
|
-
"@based/schema": "5.0.0-alpha.
|
|
42
|
+
"@based/schema": "5.0.0-alpha.26",
|
|
42
43
|
"@saulx/hash": "^3.0.0",
|
|
43
44
|
"@saulx/utils": "^6.7.2",
|
|
44
45
|
"exit-hook": "^4.0.0",
|
|
@@ -55,6 +56,7 @@
|
|
|
55
56
|
"axios": "^1.7.9",
|
|
56
57
|
"rimraf": "^3.0.2",
|
|
57
58
|
"tar": "^7.4.3",
|
|
58
|
-
"typescript": "^5.6.3"
|
|
59
|
+
"typescript": "^5.6.3",
|
|
60
|
+
"fs-extra": "^11.1.1"
|
|
59
61
|
}
|
|
60
62
|
}
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|