dbx-native 0.1.1-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.1-beta.tgz +0 -0
package/README.md
CHANGED
|
@@ -1,88 +1,88 @@
|
|
|
1
|
-
# dbx-native
|
|
2
|
-
|
|
3
|
-
[](https://www.npmjs.com/package/dbx-native)
|
|
4
|
-
[](LICENSE)
|
|
5
|
-
[](https://bytelogiccore-spec.github.io/DBX/english/packages/nodejs)
|
|
6
|
-
|
|
7
|
-
> High-performance Node.js bindings for DBX embedded database
|
|
8
|
-
|
|
9
|
-
**dbx-native** provides native Node.js bindings to the DBX database engine via N-API, delivering near-zero overhead access to the high-performance Rust core.
|
|
10
|
-
|
|
11
|
-
## Installation
|
|
12
|
-
|
|
13
|
-
```bash
|
|
14
|
-
npm install dbx-native
|
|
15
|
-
```
|
|
16
|
-
|
|
17
|
-
## Quick Start
|
|
18
|
-
|
|
19
|
-
```javascript
|
|
20
|
-
const dbx = require('dbx-native');
|
|
21
|
-
|
|
22
|
-
// Open an in-memory database
|
|
23
|
-
const db = dbx.openInMemory();
|
|
24
|
-
|
|
25
|
-
// Insert data
|
|
26
|
-
db.insert('users', Buffer.from('user:1'), Buffer.from('Alice'));
|
|
27
|
-
db.insert('users', Buffer.from('user:2'), Buffer.from('Bob'));
|
|
28
|
-
|
|
29
|
-
// Get data
|
|
30
|
-
const value = db.get('users', Buffer.from('user:1'));
|
|
31
|
-
console.log(value.toString()); // Alice
|
|
32
|
-
|
|
33
|
-
// Delete data
|
|
34
|
-
db.delete('users', Buffer.from('user:2'));
|
|
35
|
-
|
|
36
|
-
// Close database
|
|
37
|
-
db.close();
|
|
38
|
-
```
|
|
39
|
-
|
|
40
|
-
## SQL Interface
|
|
41
|
-
|
|
42
|
-
```javascript
|
|
43
|
-
const dbx = require('dbx-native');
|
|
44
|
-
|
|
45
|
-
const db = dbx.openInMemory();
|
|
46
|
-
|
|
47
|
-
// Execute SQL
|
|
48
|
-
db.executeSql('CREATE TABLE users (id INTEGER, name TEXT)');
|
|
49
|
-
db.executeSql("INSERT INTO users VALUES (1, 'Alice')");
|
|
50
|
-
|
|
51
|
-
const result = db.executeSql('SELECT * FROM users');
|
|
52
|
-
console.log(result);
|
|
53
|
-
|
|
54
|
-
db.close();
|
|
55
|
-
```
|
|
56
|
-
|
|
57
|
-
## API Reference
|
|
58
|
-
|
|
59
|
-
| Method | Description |
|
|
60
|
-
|--------|-------------|
|
|
61
|
-
| `openInMemory()` | Open an in-memory database |
|
|
62
|
-
| `open(path)` | Open a file-based database |
|
|
63
|
-
| `insert(table, key, value)` | Insert a key-value pair |
|
|
64
|
-
| `get(table, key)` | Get value by key |
|
|
65
|
-
| `delete(table, key)` | Delete a key |
|
|
66
|
-
| `executeSql(sql)` | Execute a SQL statement |
|
|
67
|
-
| `close()` | Close and free resources |
|
|
68
|
-
|
|
69
|
-
## Benchmarks
|
|
70
|
-
|
|
71
|
-
```bash
|
|
72
|
-
npm run bench
|
|
73
|
-
```
|
|
74
|
-
|
|
75
|
-
## Requirements
|
|
76
|
-
|
|
77
|
-
- Node.js 18+
|
|
78
|
-
- Windows x64 (native addon included)
|
|
79
|
-
|
|
80
|
-
## License
|
|
81
|
-
|
|
82
|
-
Dual-licensed under:
|
|
83
|
-
- **MIT License** — for open-source projects
|
|
84
|
-
- **Commercial License** — for proprietary/commercial use
|
|
85
|
-
|
|
86
|
-
See [LICENSE](https://github.com/bytelogiccore-spec/DBX/blob/main/LICENSE) for details.
|
|
87
|
-
|
|
88
|
-
For commercial licensing inquiries, contact: [ByteLogicCore](https://github.com/bytelogiccore-spec)
|
|
1
|
+
# dbx-native
|
|
2
|
+
|
|
3
|
+
[](https://www.npmjs.com/package/dbx-native)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://bytelogiccore-spec.github.io/DBX/english/packages/nodejs)
|
|
6
|
+
|
|
7
|
+
> High-performance Node.js bindings for DBX embedded database
|
|
8
|
+
|
|
9
|
+
**dbx-native** provides native Node.js bindings to the DBX database engine via N-API, delivering near-zero overhead access to the high-performance Rust core.
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
```bash
|
|
14
|
+
npm install dbx-native
|
|
15
|
+
```
|
|
16
|
+
|
|
17
|
+
## Quick Start
|
|
18
|
+
|
|
19
|
+
```javascript
|
|
20
|
+
const dbx = require('dbx-native');
|
|
21
|
+
|
|
22
|
+
// Open an in-memory database
|
|
23
|
+
const db = dbx.openInMemory();
|
|
24
|
+
|
|
25
|
+
// Insert data
|
|
26
|
+
db.insert('users', Buffer.from('user:1'), Buffer.from('Alice'));
|
|
27
|
+
db.insert('users', Buffer.from('user:2'), Buffer.from('Bob'));
|
|
28
|
+
|
|
29
|
+
// Get data
|
|
30
|
+
const value = db.get('users', Buffer.from('user:1'));
|
|
31
|
+
console.log(value.toString()); // Alice
|
|
32
|
+
|
|
33
|
+
// Delete data
|
|
34
|
+
db.delete('users', Buffer.from('user:2'));
|
|
35
|
+
|
|
36
|
+
// Close database
|
|
37
|
+
db.close();
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## SQL Interface
|
|
41
|
+
|
|
42
|
+
```javascript
|
|
43
|
+
const dbx = require('dbx-native');
|
|
44
|
+
|
|
45
|
+
const db = dbx.openInMemory();
|
|
46
|
+
|
|
47
|
+
// Execute SQL
|
|
48
|
+
db.executeSql('CREATE TABLE users (id INTEGER, name TEXT)');
|
|
49
|
+
db.executeSql("INSERT INTO users VALUES (1, 'Alice')");
|
|
50
|
+
|
|
51
|
+
const result = db.executeSql('SELECT * FROM users');
|
|
52
|
+
console.log(result);
|
|
53
|
+
|
|
54
|
+
db.close();
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
## API Reference
|
|
58
|
+
|
|
59
|
+
| Method | Description |
|
|
60
|
+
|--------|-------------|
|
|
61
|
+
| `openInMemory()` | Open an in-memory database |
|
|
62
|
+
| `open(path)` | Open a file-based database |
|
|
63
|
+
| `insert(table, key, value)` | Insert a key-value pair |
|
|
64
|
+
| `get(table, key)` | Get value by key |
|
|
65
|
+
| `delete(table, key)` | Delete a key |
|
|
66
|
+
| `executeSql(sql)` | Execute a SQL statement |
|
|
67
|
+
| `close()` | Close and free resources |
|
|
68
|
+
|
|
69
|
+
## Benchmarks
|
|
70
|
+
|
|
71
|
+
```bash
|
|
72
|
+
npm run bench
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
## Requirements
|
|
76
|
+
|
|
77
|
+
- Node.js 18+
|
|
78
|
+
- Windows x64 (native addon included)
|
|
79
|
+
|
|
80
|
+
## License
|
|
81
|
+
|
|
82
|
+
Dual-licensed under:
|
|
83
|
+
- **MIT License** — for open-source projects
|
|
84
|
+
- **Commercial License** — for proprietary/commercial use
|
|
85
|
+
|
|
86
|
+
See [LICENSE](https://github.com/bytelogiccore-spec/DBX/blob/main/LICENSE) for details.
|
|
87
|
+
|
|
88
|
+
For commercial licensing inquiries, contact: [ByteLogicCore](https://github.com/bytelogiccore-spec)
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -1,98 +1,98 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Auto-Batching Performance Benchmark
|
|
3
|
-
*
|
|
4
|
-
* Compares standard individual get() calls vs auto-batched get() calls
|
|
5
|
-
*
|
|
6
|
-
* Run with: node benchmarks/auto_batch_benchmark.js
|
|
7
|
-
*/
|
|
8
|
-
|
|
9
|
-
const Benchmark = require('benchmark');
|
|
10
|
-
const { Database } = require('../');
|
|
11
|
-
const { SmartDatabase } = require('../smart_database');
|
|
12
|
-
|
|
13
|
-
const NUM_ENTRIES = 10_000;
|
|
14
|
-
|
|
15
|
-
function generateTestData() {
|
|
16
|
-
const data = [];
|
|
17
|
-
for (let i = 0; i < NUM_ENTRIES; i++) {
|
|
18
|
-
const key = Buffer.from(`key_${i.toString().padStart(8, '0')}`);
|
|
19
|
-
const value = Buffer.from(`value_${i.toString().padStart(8, '0')}_data`);
|
|
20
|
-
data.push([key, value]);
|
|
21
|
-
}
|
|
22
|
-
return data;
|
|
23
|
-
}
|
|
24
|
-
|
|
25
|
-
// Prepare databases
|
|
26
|
-
let standardDb, smartDb, testData, testKeys;
|
|
27
|
-
|
|
28
|
-
const suite = new Benchmark.Suite();
|
|
29
|
-
|
|
30
|
-
suite
|
|
31
|
-
.add('Standard GET 10k (individual calls)', {
|
|
32
|
-
onStart: function () {
|
|
33
|
-
standardDb = Database.openInMemory();
|
|
34
|
-
testData = generateTestData();
|
|
35
|
-
testKeys = testData.map(([key]) => key);
|
|
36
|
-
for (const [key, value] of testData) {
|
|
37
|
-
standardDb.insert('bench', key, value);
|
|
38
|
-
}
|
|
39
|
-
},
|
|
40
|
-
fn: function () {
|
|
41
|
-
for (const key of testKeys) {
|
|
42
|
-
standardDb.get('bench', key);
|
|
43
|
-
}
|
|
44
|
-
}
|
|
45
|
-
})
|
|
46
|
-
.add('Auto-Batched GET 10k (SmartDatabase)', {
|
|
47
|
-
onStart: function () {
|
|
48
|
-
const rawDb = Database.openInMemory();
|
|
49
|
-
smartDb = new SmartDatabase(rawDb);
|
|
50
|
-
testData = generateTestData();
|
|
51
|
-
testKeys = testData.map(([key]) => key);
|
|
52
|
-
for (const [key, value] of testData) {
|
|
53
|
-
smartDb.insert('bench', key, value);
|
|
54
|
-
}
|
|
55
|
-
},
|
|
56
|
-
fn: async function (deferred) {
|
|
57
|
-
// All get() calls are automatically batched
|
|
58
|
-
await Promise.all(testKeys.map(key => smartDb.get('bench', key)));
|
|
59
|
-
deferred.resolve();
|
|
60
|
-
},
|
|
61
|
-
defer: true
|
|
62
|
-
})
|
|
63
|
-
.add('Manual Batch GET 10k', {
|
|
64
|
-
onStart: function () {
|
|
65
|
-
standardDb = Database.openInMemory();
|
|
66
|
-
testData = generateTestData();
|
|
67
|
-
testKeys = testData.map(([key]) => key);
|
|
68
|
-
for (const [key, value] of testData) {
|
|
69
|
-
standardDb.insert('bench', key, value);
|
|
70
|
-
}
|
|
71
|
-
},
|
|
72
|
-
fn: function () {
|
|
73
|
-
standardDb.getBatch('bench', testKeys);
|
|
74
|
-
}
|
|
75
|
-
})
|
|
76
|
-
.on('cycle', function (event) {
|
|
77
|
-
console.log(String(event.target));
|
|
78
|
-
const timeMs = event.target.stats.mean * 1000;
|
|
79
|
-
console.log(` → ${timeMs.toFixed(2)}ms per operation\n`);
|
|
80
|
-
})
|
|
81
|
-
.on('complete', function () {
|
|
82
|
-
console.log('\n=== Performance Comparison ===');
|
|
83
|
-
|
|
84
|
-
const standard = this.filter(name => name === 'Standard GET 10k (individual calls)')[0];
|
|
85
|
-
const autoBatch = this.filter(name => name === 'Auto-Batched GET 10k (SmartDatabase)')[0];
|
|
86
|
-
const manualBatch = this.filter(name => name === 'Manual Batch GET 10k')[0];
|
|
87
|
-
|
|
88
|
-
if (standard && autoBatch) {
|
|
89
|
-
const improvement = ((standard.stats.mean - autoBatch.stats.mean) / standard.stats.mean * 100).toFixed(1);
|
|
90
|
-
console.log(`Auto-batching: ${improvement}% faster than individual calls`);
|
|
91
|
-
}
|
|
92
|
-
|
|
93
|
-
if (autoBatch && manualBatch) {
|
|
94
|
-
const overhead = ((autoBatch.stats.mean - manualBatch.stats.mean) / manualBatch.stats.mean * 100).toFixed(1);
|
|
95
|
-
console.log(`Auto-batching overhead: ${overhead}% vs manual batch`);
|
|
96
|
-
}
|
|
97
|
-
})
|
|
98
|
-
.run({ 'async': true });
|
|
1
|
+
/**
|
|
2
|
+
* Auto-Batching Performance Benchmark
|
|
3
|
+
*
|
|
4
|
+
* Compares standard individual get() calls vs auto-batched get() calls
|
|
5
|
+
*
|
|
6
|
+
* Run with: node benchmarks/auto_batch_benchmark.js
|
|
7
|
+
*/
|
|
8
|
+
|
|
9
|
+
const Benchmark = require('benchmark');
|
|
10
|
+
const { Database } = require('../');
|
|
11
|
+
const { SmartDatabase } = require('../smart_database');
|
|
12
|
+
|
|
13
|
+
const NUM_ENTRIES = 10_000;
|
|
14
|
+
|
|
15
|
+
function generateTestData() {
|
|
16
|
+
const data = [];
|
|
17
|
+
for (let i = 0; i < NUM_ENTRIES; i++) {
|
|
18
|
+
const key = Buffer.from(`key_${i.toString().padStart(8, '0')}`);
|
|
19
|
+
const value = Buffer.from(`value_${i.toString().padStart(8, '0')}_data`);
|
|
20
|
+
data.push([key, value]);
|
|
21
|
+
}
|
|
22
|
+
return data;
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
// Prepare databases
|
|
26
|
+
let standardDb, smartDb, testData, testKeys;
|
|
27
|
+
|
|
28
|
+
const suite = new Benchmark.Suite();
|
|
29
|
+
|
|
30
|
+
suite
|
|
31
|
+
.add('Standard GET 10k (individual calls)', {
|
|
32
|
+
onStart: function () {
|
|
33
|
+
standardDb = Database.openInMemory();
|
|
34
|
+
testData = generateTestData();
|
|
35
|
+
testKeys = testData.map(([key]) => key);
|
|
36
|
+
for (const [key, value] of testData) {
|
|
37
|
+
standardDb.insert('bench', key, value);
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
fn: function () {
|
|
41
|
+
for (const key of testKeys) {
|
|
42
|
+
standardDb.get('bench', key);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
})
|
|
46
|
+
.add('Auto-Batched GET 10k (SmartDatabase)', {
|
|
47
|
+
onStart: function () {
|
|
48
|
+
const rawDb = Database.openInMemory();
|
|
49
|
+
smartDb = new SmartDatabase(rawDb);
|
|
50
|
+
testData = generateTestData();
|
|
51
|
+
testKeys = testData.map(([key]) => key);
|
|
52
|
+
for (const [key, value] of testData) {
|
|
53
|
+
smartDb.insert('bench', key, value);
|
|
54
|
+
}
|
|
55
|
+
},
|
|
56
|
+
fn: async function (deferred) {
|
|
57
|
+
// All get() calls are automatically batched
|
|
58
|
+
await Promise.all(testKeys.map(key => smartDb.get('bench', key)));
|
|
59
|
+
deferred.resolve();
|
|
60
|
+
},
|
|
61
|
+
defer: true
|
|
62
|
+
})
|
|
63
|
+
.add('Manual Batch GET 10k', {
|
|
64
|
+
onStart: function () {
|
|
65
|
+
standardDb = Database.openInMemory();
|
|
66
|
+
testData = generateTestData();
|
|
67
|
+
testKeys = testData.map(([key]) => key);
|
|
68
|
+
for (const [key, value] of testData) {
|
|
69
|
+
standardDb.insert('bench', key, value);
|
|
70
|
+
}
|
|
71
|
+
},
|
|
72
|
+
fn: function () {
|
|
73
|
+
standardDb.getBatch('bench', testKeys);
|
|
74
|
+
}
|
|
75
|
+
})
|
|
76
|
+
.on('cycle', function (event) {
|
|
77
|
+
console.log(String(event.target));
|
|
78
|
+
const timeMs = event.target.stats.mean * 1000;
|
|
79
|
+
console.log(` → ${timeMs.toFixed(2)}ms per operation\n`);
|
|
80
|
+
})
|
|
81
|
+
.on('complete', function () {
|
|
82
|
+
console.log('\n=== Performance Comparison ===');
|
|
83
|
+
|
|
84
|
+
const standard = this.filter(name => name === 'Standard GET 10k (individual calls)')[0];
|
|
85
|
+
const autoBatch = this.filter(name => name === 'Auto-Batched GET 10k (SmartDatabase)')[0];
|
|
86
|
+
const manualBatch = this.filter(name => name === 'Manual Batch GET 10k')[0];
|
|
87
|
+
|
|
88
|
+
if (standard && autoBatch) {
|
|
89
|
+
const improvement = ((standard.stats.mean - autoBatch.stats.mean) / standard.stats.mean * 100).toFixed(1);
|
|
90
|
+
console.log(`Auto-batching: ${improvement}% faster than individual calls`);
|
|
91
|
+
}
|
|
92
|
+
|
|
93
|
+
if (autoBatch && manualBatch) {
|
|
94
|
+
const overhead = ((autoBatch.stats.mean - manualBatch.stats.mean) / manualBatch.stats.mean * 100).toFixed(1);
|
|
95
|
+
console.log(`Auto-batching overhead: ${overhead}% vs manual batch`);
|
|
96
|
+
}
|
|
97
|
+
})
|
|
98
|
+
.run({ 'async': true });
|