dbx-native 0.1.2-beta → 0.2.0-beta
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 +88 -88
- package/artifacts/node-binary-macos-latest/index.node +0 -0
- package/artifacts/node-binary-ubuntu-latest/index.node +0 -0
- package/artifacts/node-binary-windows-latest/index.node +0 -0
- package/benchmarks/auto_batch_benchmark.js +98 -98
- package/benchmarks/benchmark.js +162 -162
- package/benchmarks/benchmark_batch.js +166 -166
- package/benchmarks/benchmark_sql.js +162 -162
- package/benchmarks/ffi_benchmark.js +72 -72
- package/benchmarks/zero_copy_benchmark.js +109 -109
- package/dbx-native-0.2.0-beta.tgz +0 -0
- package/examples/basic.js +34 -34
- package/index.js +2 -2
- package/package.json +46 -46
- package/smart_database.js +184 -184
- package/test/test_sql_insert.js +72 -72
- package/dbx-native-0.1.2-beta.tgz +0 -0
|
@@ -1,109 +1,109 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Zero-Copy FFI Performance Benchmark for DBX Node.js Bindings
|
|
3
|
-
*
|
|
4
|
-
* Compares standard API vs zero-copy API performance
|
|
5
|
-
*
|
|
6
|
-
* Run with: node benchmarks/zero_copy_benchmark.js
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const Benchmark = require('benchmark');
|
|
10
|
-
const { Database } = require('../');
|
|
11
|
-
|
|
12
|
-
const NUM_ENTRIES = 10_000;
|
|
13
|
-
|
|
14
|
-
function generateTestData() {
|
|
15
|
-
const data = [];
|
|
16
|
-
for (let i = 0; i < NUM_ENTRIES; i++) {
|
|
17
|
-
const key = Buffer.from(`key_${i.toString().padStart(8, '0')}`);
|
|
18
|
-
const value = Buffer.from(`value_${i.toString().padStart(8, '0')}_data`);
|
|
19
|
-
data.push([key, value]);
|
|
20
|
-
}
|
|
21
|
-
return data;
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
// Prepare databases
|
|
25
|
-
let standardDb, zeroCopyDb, batchDb;
|
|
26
|
-
let testData, testKeys;
|
|
27
|
-
|
|
28
|
-
const suite = new Benchmark.Suite();
|
|
29
|
-
|
|
30
|
-
suite
|
|
31
|
-
.add('Standard SCAN 10k', {
|
|
32
|
-
onStart: function () {
|
|
33
|
-
standardDb = Database.openInMemory();
|
|
34
|
-
const data = generateTestData();
|
|
35
|
-
for (const [key, value] of data) {
|
|
36
|
-
standardDb.insert('bench', key, value);
|
|
37
|
-
}
|
|
38
|
-
},
|
|
39
|
-
fn: function () {
|
|
40
|
-
standardDb.scan('bench');
|
|
41
|
-
}
|
|
42
|
-
})
|
|
43
|
-
.add('Zero-Copy SCAN 10k', {
|
|
44
|
-
onStart: function () {
|
|
45
|
-
zeroCopyDb = Database.openInMemory();
|
|
46
|
-
const data = generateTestData();
|
|
47
|
-
for (const [key, value] of data) {
|
|
48
|
-
zeroCopyDb.insert('bench', key, value);
|
|
49
|
-
}
|
|
50
|
-
},
|
|
51
|
-
fn: function () {
|
|
52
|
-
const result = zeroCopyDb.scanZeroCopy('bench');
|
|
53
|
-
// Access the buffer (zero-copy)
|
|
54
|
-
const buffer = result.asBuffer();
|
|
55
|
-
const count = result.count();
|
|
56
|
-
}
|
|
57
|
-
})
|
|
58
|
-
.add('Standard GET 10k', {
|
|
59
|
-
onStart: function () {
|
|
60
|
-
standardDb = Database.openInMemory();
|
|
61
|
-
testData = generateTestData();
|
|
62
|
-
testKeys = testData.map(([key]) => key);
|
|
63
|
-
for (const [key, value] of testData) {
|
|
64
|
-
standardDb.insert('bench', key, value);
|
|
65
|
-
}
|
|
66
|
-
},
|
|
67
|
-
fn: function () {
|
|
68
|
-
for (const key of testKeys) {
|
|
69
|
-
standardDb.get('bench', key);
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
})
|
|
73
|
-
.add('Batch GET 10k', {
|
|
74
|
-
onStart: function () {
|
|
75
|
-
batchDb = Database.openInMemory();
|
|
76
|
-
testData = generateTestData();
|
|
77
|
-
testKeys = testData.map(([key]) => key);
|
|
78
|
-
for (const [key, value] of testData) {
|
|
79
|
-
batchDb.insert('bench', key, value);
|
|
80
|
-
}
|
|
81
|
-
},
|
|
82
|
-
fn: function () {
|
|
83
|
-
batchDb.getBatch('bench', testKeys);
|
|
84
|
-
}
|
|
85
|
-
})
|
|
86
|
-
.on('cycle', function (event) {
|
|
87
|
-
console.log(String(event.target));
|
|
88
|
-
const timeMs = event.target.stats.mean * 1000;
|
|
89
|
-
console.log(` → ${timeMs.toFixed(2)}ms per operation\n`);
|
|
90
|
-
})
|
|
91
|
-
.on('complete', function () {
|
|
92
|
-
console.log('\n=== Performance Comparison ===');
|
|
93
|
-
|
|
94
|
-
const standardScan = this.filter(name => name === 'Standard SCAN 10k')[0];
|
|
95
|
-
const zeroCopyScan = this.filter(name => name === 'Zero-Copy SCAN 10k')[0];
|
|
96
|
-
const standardGet = this.filter(name => name === 'Standard GET 10k')[0];
|
|
97
|
-
const batchGet = this.filter(name => name === 'Batch GET 10k')[0];
|
|
98
|
-
|
|
99
|
-
if (standardScan && zeroCopyScan) {
|
|
100
|
-
const scanImprovement = ((standardScan.stats.mean - zeroCopyScan.stats.mean) / standardScan.stats.mean * 100).toFixed(1);
|
|
101
|
-
console.log(`SCAN: ${scanImprovement}% faster with zero-copy`);
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
if (standardGet && batchGet) {
|
|
105
|
-
const getImprovement = ((standardGet.stats.mean - batchGet.stats.mean) / standardGet.stats.mean * 100).toFixed(1);
|
|
106
|
-
console.log(`GET: ${getImprovement}% faster with batch API`);
|
|
107
|
-
}
|
|
108
|
-
})
|
|
109
|
-
.run({ 'async': false });
|
|
1
|
+
/**
|
|
2
|
+
* Zero-Copy FFI Performance Benchmark for DBX Node.js Bindings
|
|
3
|
+
*
|
|
4
|
+
* Compares standard API vs zero-copy API performance
|
|
5
|
+
*
|
|
6
|
+
* Run with: node benchmarks/zero_copy_benchmark.js
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const Benchmark = require('benchmark');
|
|
10
|
+
const { Database } = require('../');
|
|
11
|
+
|
|
12
|
+
const NUM_ENTRIES = 10_000;
|
|
13
|
+
|
|
14
|
+
function generateTestData() {
|
|
15
|
+
const data = [];
|
|
16
|
+
for (let i = 0; i < NUM_ENTRIES; i++) {
|
|
17
|
+
const key = Buffer.from(`key_${i.toString().padStart(8, '0')}`);
|
|
18
|
+
const value = Buffer.from(`value_${i.toString().padStart(8, '0')}_data`);
|
|
19
|
+
data.push([key, value]);
|
|
20
|
+
}
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
// Prepare databases
|
|
25
|
+
let standardDb, zeroCopyDb, batchDb;
|
|
26
|
+
let testData, testKeys;
|
|
27
|
+
|
|
28
|
+
const suite = new Benchmark.Suite();
|
|
29
|
+
|
|
30
|
+
suite
|
|
31
|
+
.add('Standard SCAN 10k', {
|
|
32
|
+
onStart: function () {
|
|
33
|
+
standardDb = Database.openInMemory();
|
|
34
|
+
const data = generateTestData();
|
|
35
|
+
for (const [key, value] of data) {
|
|
36
|
+
standardDb.insert('bench', key, value);
|
|
37
|
+
}
|
|
38
|
+
},
|
|
39
|
+
fn: function () {
|
|
40
|
+
standardDb.scan('bench');
|
|
41
|
+
}
|
|
42
|
+
})
|
|
43
|
+
.add('Zero-Copy SCAN 10k', {
|
|
44
|
+
onStart: function () {
|
|
45
|
+
zeroCopyDb = Database.openInMemory();
|
|
46
|
+
const data = generateTestData();
|
|
47
|
+
for (const [key, value] of data) {
|
|
48
|
+
zeroCopyDb.insert('bench', key, value);
|
|
49
|
+
}
|
|
50
|
+
},
|
|
51
|
+
fn: function () {
|
|
52
|
+
const result = zeroCopyDb.scanZeroCopy('bench');
|
|
53
|
+
// Access the buffer (zero-copy)
|
|
54
|
+
const buffer = result.asBuffer();
|
|
55
|
+
const count = result.count();
|
|
56
|
+
}
|
|
57
|
+
})
|
|
58
|
+
.add('Standard GET 10k', {
|
|
59
|
+
onStart: function () {
|
|
60
|
+
standardDb = Database.openInMemory();
|
|
61
|
+
testData = generateTestData();
|
|
62
|
+
testKeys = testData.map(([key]) => key);
|
|
63
|
+
for (const [key, value] of testData) {
|
|
64
|
+
standardDb.insert('bench', key, value);
|
|
65
|
+
}
|
|
66
|
+
},
|
|
67
|
+
fn: function () {
|
|
68
|
+
for (const key of testKeys) {
|
|
69
|
+
standardDb.get('bench', key);
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
})
|
|
73
|
+
.add('Batch GET 10k', {
|
|
74
|
+
onStart: function () {
|
|
75
|
+
batchDb = Database.openInMemory();
|
|
76
|
+
testData = generateTestData();
|
|
77
|
+
testKeys = testData.map(([key]) => key);
|
|
78
|
+
for (const [key, value] of testData) {
|
|
79
|
+
batchDb.insert('bench', key, value);
|
|
80
|
+
}
|
|
81
|
+
},
|
|
82
|
+
fn: function () {
|
|
83
|
+
batchDb.getBatch('bench', testKeys);
|
|
84
|
+
}
|
|
85
|
+
})
|
|
86
|
+
.on('cycle', function (event) {
|
|
87
|
+
console.log(String(event.target));
|
|
88
|
+
const timeMs = event.target.stats.mean * 1000;
|
|
89
|
+
console.log(` → ${timeMs.toFixed(2)}ms per operation\n`);
|
|
90
|
+
})
|
|
91
|
+
.on('complete', function () {
|
|
92
|
+
console.log('\n=== Performance Comparison ===');
|
|
93
|
+
|
|
94
|
+
const standardScan = this.filter(name => name === 'Standard SCAN 10k')[0];
|
|
95
|
+
const zeroCopyScan = this.filter(name => name === 'Zero-Copy SCAN 10k')[0];
|
|
96
|
+
const standardGet = this.filter(name => name === 'Standard GET 10k')[0];
|
|
97
|
+
const batchGet = this.filter(name => name === 'Batch GET 10k')[0];
|
|
98
|
+
|
|
99
|
+
if (standardScan && zeroCopyScan) {
|
|
100
|
+
const scanImprovement = ((standardScan.stats.mean - zeroCopyScan.stats.mean) / standardScan.stats.mean * 100).toFixed(1);
|
|
101
|
+
console.log(`SCAN: ${scanImprovement}% faster with zero-copy`);
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
if (standardGet && batchGet) {
|
|
105
|
+
const getImprovement = ((standardGet.stats.mean - batchGet.stats.mean) / standardGet.stats.mean * 100).toFixed(1);
|
|
106
|
+
console.log(`GET: ${getImprovement}% faster with batch API`);
|
|
107
|
+
}
|
|
108
|
+
})
|
|
109
|
+
.run({ 'async': false });
|
|
Binary file
|
package/examples/basic.js
CHANGED
|
@@ -1,34 +1,34 @@
|
|
|
1
|
-
const { Database } = require('../index.js');
|
|
2
|
-
|
|
3
|
-
console.log('DBX Native (napi-rs) - Basic Example\n');
|
|
4
|
-
|
|
5
|
-
// Open in-memory database
|
|
6
|
-
const db = Database.openInMemory();
|
|
7
|
-
console.log('✓ Opened in-memory database');
|
|
8
|
-
|
|
9
|
-
// Insert some data
|
|
10
|
-
db.insert('users', Buffer.from('user:1'), Buffer.from('Alice'));
|
|
11
|
-
db.insert('users', Buffer.from('user:2'), Buffer.from('Bob'));
|
|
12
|
-
console.log('✓ Inserted 2 users');
|
|
13
|
-
|
|
14
|
-
// Get data
|
|
15
|
-
const alice = db.get('users', Buffer.from('user:1'));
|
|
16
|
-
console.log(`✓ Retrieved: ${alice.toString()}`);
|
|
17
|
-
|
|
18
|
-
// Use transaction for batch operations
|
|
19
|
-
const tx = db.beginTransaction();
|
|
20
|
-
for (let i = 3; i <= 10; i++) {
|
|
21
|
-
tx.insert('users', Buffer.from(`user:${i}`), Buffer.from(`User${i}`));
|
|
22
|
-
}
|
|
23
|
-
tx.commit();
|
|
24
|
-
console.log('✓ Inserted 8 more users via transaction');
|
|
25
|
-
|
|
26
|
-
// Delete data
|
|
27
|
-
db.delete('users', Buffer.from('user:1'));
|
|
28
|
-
console.log('✓ Deleted user:1');
|
|
29
|
-
|
|
30
|
-
// Close database
|
|
31
|
-
db.close();
|
|
32
|
-
console.log('✓ Closed database');
|
|
33
|
-
|
|
34
|
-
console.log('\n✅ All operations completed successfully!');
|
|
1
|
+
const { Database } = require('../index.js');
|
|
2
|
+
|
|
3
|
+
console.log('DBX Native (napi-rs) - Basic Example\n');
|
|
4
|
+
|
|
5
|
+
// Open in-memory database
|
|
6
|
+
const db = Database.openInMemory();
|
|
7
|
+
console.log('✓ Opened in-memory database');
|
|
8
|
+
|
|
9
|
+
// Insert some data
|
|
10
|
+
db.insert('users', Buffer.from('user:1'), Buffer.from('Alice'));
|
|
11
|
+
db.insert('users', Buffer.from('user:2'), Buffer.from('Bob'));
|
|
12
|
+
console.log('✓ Inserted 2 users');
|
|
13
|
+
|
|
14
|
+
// Get data
|
|
15
|
+
const alice = db.get('users', Buffer.from('user:1'));
|
|
16
|
+
console.log(`✓ Retrieved: ${alice.toString()}`);
|
|
17
|
+
|
|
18
|
+
// Use transaction for batch operations
|
|
19
|
+
const tx = db.beginTransaction();
|
|
20
|
+
for (let i = 3; i <= 10; i++) {
|
|
21
|
+
tx.insert('users', Buffer.from(`user:${i}`), Buffer.from(`User${i}`));
|
|
22
|
+
}
|
|
23
|
+
tx.commit();
|
|
24
|
+
console.log('✓ Inserted 8 more users via transaction');
|
|
25
|
+
|
|
26
|
+
// Delete data
|
|
27
|
+
db.delete('users', Buffer.from('user:1'));
|
|
28
|
+
console.log('✓ Deleted user:1');
|
|
29
|
+
|
|
30
|
+
// Close database
|
|
31
|
+
db.close();
|
|
32
|
+
console.log('✓ Closed database');
|
|
33
|
+
|
|
34
|
+
console.log('\n✅ All operations completed successfully!');
|
package/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
// DBX Native Node.js bindings
|
|
2
|
-
module.exports = require('./index.node');
|
|
1
|
+
// DBX Native Node.js bindings
|
|
2
|
+
module.exports = require('./index.node');
|
package/package.json
CHANGED
|
@@ -1,46 +1,46 @@
|
|
|
1
|
-
{
|
|
2
|
-
"name": "dbx-native",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "DBX native Node.js bindings using napi-rs",
|
|
5
|
-
"main": "index.js",
|
|
6
|
-
"types": "index.d.ts",
|
|
7
|
-
"napi": {
|
|
8
|
-
"binaryName": "dbx-native",
|
|
9
|
-
"targets": [
|
|
10
|
-
"x86_64-pc-windows-msvc",
|
|
11
|
-
"x86_64-apple-darwin",
|
|
12
|
-
"aarch64-apple-darwin",
|
|
13
|
-
"x86_64-unknown-linux-gnu"
|
|
14
|
-
]
|
|
15
|
-
},
|
|
16
|
-
"scripts": {
|
|
17
|
-
"build": "napi build --platform --release --manifest-path ../../core/dbx-node/Cargo.toml",
|
|
18
|
-
"build:debug": "napi build --platform --manifest-path ../../core/dbx-node/Cargo.toml",
|
|
19
|
-
"prepublishOnly": "napi prepublish -t npm",
|
|
20
|
-
"test": "node examples/basic.js",
|
|
21
|
-
"bench": "node benchmarks/benchmark.js"
|
|
22
|
-
},
|
|
23
|
-
"devDependencies": {
|
|
24
|
-
"@napi-rs/cli": "^3.0.0",
|
|
25
|
-
"better-sqlite3": "^11.0.0"
|
|
26
|
-
},
|
|
27
|
-
"keywords": [
|
|
28
|
-
"database",
|
|
29
|
-
"key-value",
|
|
30
|
-
"rust",
|
|
31
|
-
"napi",
|
|
32
|
-
"native"
|
|
33
|
-
],
|
|
34
|
-
"homepage": "https://bytelogiccore-spec.github.io/DBX/english/packages/nodejs",
|
|
35
|
-
"repository": {
|
|
36
|
-
"type": "git",
|
|
37
|
-
"url": "https://github.com/bytelogiccore-spec/DBX.git"
|
|
38
|
-
},
|
|
39
|
-
"license": "MIT",
|
|
40
|
-
"engines": {
|
|
41
|
-
"node": ">= 16"
|
|
42
|
-
},
|
|
43
|
-
"dependencies": {
|
|
44
|
-
"benchmark": "^2.1.4"
|
|
45
|
-
}
|
|
46
|
-
}
|
|
1
|
+
{
|
|
2
|
+
"name": "dbx-native",
|
|
3
|
+
"version": "0.2.0-beta",
|
|
4
|
+
"description": "DBX native Node.js bindings using napi-rs",
|
|
5
|
+
"main": "index.js",
|
|
6
|
+
"types": "index.d.ts",
|
|
7
|
+
"napi": {
|
|
8
|
+
"binaryName": "dbx-native",
|
|
9
|
+
"targets": [
|
|
10
|
+
"x86_64-pc-windows-msvc",
|
|
11
|
+
"x86_64-apple-darwin",
|
|
12
|
+
"aarch64-apple-darwin",
|
|
13
|
+
"x86_64-unknown-linux-gnu"
|
|
14
|
+
]
|
|
15
|
+
},
|
|
16
|
+
"scripts": {
|
|
17
|
+
"build": "napi build --platform --release --manifest-path ../../core/dbx-node/Cargo.toml",
|
|
18
|
+
"build:debug": "napi build --platform --manifest-path ../../core/dbx-node/Cargo.toml",
|
|
19
|
+
"prepublishOnly": "napi prepublish -t npm",
|
|
20
|
+
"test": "node examples/basic.js",
|
|
21
|
+
"bench": "node benchmarks/benchmark.js"
|
|
22
|
+
},
|
|
23
|
+
"devDependencies": {
|
|
24
|
+
"@napi-rs/cli": "^3.0.0",
|
|
25
|
+
"better-sqlite3": "^11.0.0"
|
|
26
|
+
},
|
|
27
|
+
"keywords": [
|
|
28
|
+
"database",
|
|
29
|
+
"key-value",
|
|
30
|
+
"rust",
|
|
31
|
+
"napi",
|
|
32
|
+
"native"
|
|
33
|
+
],
|
|
34
|
+
"homepage": "https://bytelogiccore-spec.github.io/DBX/english/packages/nodejs",
|
|
35
|
+
"repository": {
|
|
36
|
+
"type": "git",
|
|
37
|
+
"url": "https://github.com/bytelogiccore-spec/DBX.git"
|
|
38
|
+
},
|
|
39
|
+
"license": "MIT",
|
|
40
|
+
"engines": {
|
|
41
|
+
"node": ">= 16"
|
|
42
|
+
},
|
|
43
|
+
"dependencies": {
|
|
44
|
+
"benchmark": "^2.1.4"
|
|
45
|
+
}
|
|
46
|
+
}
|