xitdb 0.12.0 → 0.14.0

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.
Files changed (63) hide show
  1. package/README.md +120 -118
  2. package/dist/core-buffered-file.d.ts +23 -25
  3. package/dist/core-buffered-file.js +182 -0
  4. package/dist/core-file.d.ts +8 -10
  5. package/dist/core-file.js +105 -0
  6. package/dist/core-memory.d.ts +15 -15
  7. package/dist/core-memory.js +152 -0
  8. package/dist/core.d.ts +14 -14
  9. package/dist/core.js +1 -0
  10. package/dist/database.d.ts +204 -80
  11. package/dist/database.js +3047 -0
  12. package/dist/exceptions.d.ts +4 -0
  13. package/dist/exceptions.js +62 -0
  14. package/dist/hasher.d.ts +2 -1
  15. package/dist/hasher.js +49 -0
  16. package/dist/index.d.ts +30 -26
  17. package/dist/index.js +35 -3986
  18. package/dist/read-array-list.d.ts +8 -8
  19. package/dist/read-array-list.js +35 -0
  20. package/dist/read-counted-hash-map.d.ts +3 -3
  21. package/dist/read-counted-hash-map.js +19 -0
  22. package/dist/read-counted-hash-set.d.ts +3 -3
  23. package/dist/read-counted-hash-set.js +19 -0
  24. package/dist/read-cursor.d.ts +29 -23
  25. package/dist/read-cursor.js +577 -0
  26. package/dist/read-hash-map.d.ts +22 -22
  27. package/dist/read-hash-map.js +65 -0
  28. package/dist/read-hash-set.d.ts +13 -13
  29. package/dist/read-hash-set.js +47 -0
  30. package/dist/read-linked-array-list.d.ts +8 -8
  31. package/dist/read-linked-array-list.js +35 -0
  32. package/dist/read-sorted-map.d.ts +21 -0
  33. package/dist/read-sorted-map.js +73 -0
  34. package/dist/read-sorted-set.d.ts +19 -0
  35. package/dist/read-sorted-set.js +65 -0
  36. package/dist/slot-pointer.d.ts +1 -1
  37. package/dist/slot-pointer.js +11 -0
  38. package/dist/slot.d.ts +2 -2
  39. package/dist/slot.js +41 -0
  40. package/dist/slotted.d.ts +1 -1
  41. package/dist/slotted.js +1 -0
  42. package/dist/tag.d.ts +3 -1
  43. package/dist/tag.js +25 -0
  44. package/dist/write-array-list.d.ts +13 -14
  45. package/dist/write-array-list.js +42 -0
  46. package/dist/write-counted-hash-map.d.ts +4 -5
  47. package/dist/write-counted-hash-map.js +18 -0
  48. package/dist/write-counted-hash-set.d.ts +4 -5
  49. package/dist/write-counted-hash-set.js +18 -0
  50. package/dist/write-cursor.d.ts +15 -15
  51. package/dist/write-cursor.js +124 -0
  52. package/dist/write-hash-map.d.ts +22 -23
  53. package/dist/write-hash-map.js +90 -0
  54. package/dist/write-hash-set.d.ts +16 -17
  55. package/dist/write-hash-set.js +59 -0
  56. package/dist/write-linked-array-list.d.ts +16 -17
  57. package/dist/write-linked-array-list.js +52 -0
  58. package/dist/write-sorted-map.d.ts +12 -0
  59. package/dist/write-sorted-map.js +37 -0
  60. package/dist/write-sorted-set.d.ts +10 -0
  61. package/dist/write-sorted-set.js +29 -0
  62. package/dist/writeable-data.js +68 -0
  63. package/package.json +6 -6
@@ -0,0 +1,182 @@
1
+ import { CoreFile } from './core-file.js';
2
+ import { CoreMemory } from './core-memory.js';
3
+ export class CoreBufferedFile {
4
+ file;
5
+ constructor(filePath, bufferSize) {
6
+ this.file = new RandomAccessBufferedFile(filePath, bufferSize);
7
+ }
8
+ reader() {
9
+ return this.file;
10
+ }
11
+ writer() {
12
+ return this.file;
13
+ }
14
+ length() {
15
+ return this.file.length();
16
+ }
17
+ seek(pos) {
18
+ this.file.seek(pos);
19
+ }
20
+ position() {
21
+ return this.file.position();
22
+ }
23
+ setLength(len) {
24
+ this.file.setLength(len);
25
+ }
26
+ flush() {
27
+ this.file.flush();
28
+ }
29
+ sync() {
30
+ this.file.sync();
31
+ }
32
+ [Symbol.dispose]() {
33
+ this.file.file[Symbol.dispose]();
34
+ }
35
+ }
36
+ const DEFAULT_BUFFER_SIZE = 8 * 1024 * 1024; // 8MB
37
+ class RandomAccessBufferedFile {
38
+ file;
39
+ memory;
40
+ bufferSize; // flushes when the memory is >= this size
41
+ filePos;
42
+ memoryPos;
43
+ constructor(filePath, bufferSize = DEFAULT_BUFFER_SIZE) {
44
+ this.file = new CoreFile(filePath);
45
+ this.memory = new CoreMemory();
46
+ this.bufferSize = bufferSize;
47
+ this.filePos = 0;
48
+ this.memoryPos = 0;
49
+ }
50
+ seek(pos) {
51
+ // flush if we are going past the end of the in-memory buffer
52
+ if (pos > this.memoryPos + this.memory.length()) {
53
+ this.flush();
54
+ }
55
+ this.filePos = pos;
56
+ // if the buffer is empty, set its position to this offset as well
57
+ if (this.memory.length() === 0) {
58
+ this.memoryPos = pos;
59
+ }
60
+ }
61
+ length() {
62
+ return Math.max(this.memoryPos + this.memory.length(), this.file.length());
63
+ }
64
+ position() {
65
+ return this.filePos;
66
+ }
67
+ setLength(len) {
68
+ this.flush();
69
+ this.file.setLength(len);
70
+ this.filePos = Math.min(len, this.filePos);
71
+ }
72
+ flush() {
73
+ if (this.memory.length() > 0) {
74
+ this.file.seek(this.memoryPos);
75
+ this.file.writer().write(this.memory.memory.toByteArray());
76
+ this.memoryPos = 0;
77
+ this.memory.memory.reset();
78
+ }
79
+ }
80
+ sync() {
81
+ this.flush();
82
+ this.file.sync();
83
+ }
84
+ // DataWriter interface
85
+ write(buffer) {
86
+ if (this.memory.length() + buffer.length > this.bufferSize) {
87
+ this.flush();
88
+ }
89
+ if (this.filePos >= this.memoryPos && this.filePos <= this.memoryPos + this.memory.length()) {
90
+ this.memory.seek(this.filePos - this.memoryPos);
91
+ this.memory.memory.write(buffer);
92
+ }
93
+ else {
94
+ // a direct disk write that overlaps the buffered region would be
95
+ // clobbered by a later flush of stale buffer bytes, so flush first
96
+ if (this.filePos < this.memoryPos + this.memory.length() && this.filePos + buffer.length > this.memoryPos) {
97
+ this.flush();
98
+ }
99
+ // Write directly to file
100
+ this.file.seek(this.filePos);
101
+ this.file.writer().write(buffer);
102
+ }
103
+ this.filePos += buffer.length;
104
+ }
105
+ writeByte(v) {
106
+ this.write(new Uint8Array([v & 0xff]));
107
+ }
108
+ writeShort(v) {
109
+ const buffer = new ArrayBuffer(2);
110
+ const view = new DataView(buffer);
111
+ view.setInt16(0, v & 0xffff, false); // big-endian
112
+ this.write(new Uint8Array(buffer));
113
+ }
114
+ writeLong(v) {
115
+ const buffer = new ArrayBuffer(8);
116
+ const view = new DataView(buffer);
117
+ view.setBigInt64(0, BigInt(v), false);
118
+ this.write(new Uint8Array(buffer));
119
+ }
120
+ // DataReader interface
121
+ readFully(buffer) {
122
+ let pos = 0;
123
+ // read from the disk -- before the in-memory buffer
124
+ if (this.filePos < this.memoryPos) {
125
+ const sizeBeforeMem = Math.min(this.memoryPos - this.filePos, buffer.length);
126
+ const tempBuffer = new Uint8Array(sizeBeforeMem);
127
+ this.file.seek(this.filePos);
128
+ this.file.reader().readFully(tempBuffer);
129
+ buffer.set(tempBuffer, pos);
130
+ pos += sizeBeforeMem;
131
+ this.filePos += sizeBeforeMem;
132
+ }
133
+ if (pos === buffer.length)
134
+ return;
135
+ // read from the in-memory buffer
136
+ if (this.filePos >= this.memoryPos && this.filePos < this.memoryPos + this.memory.length()) {
137
+ const memPos = this.filePos - this.memoryPos;
138
+ const sizeInMem = Math.min(this.memory.length() - memPos, buffer.length - pos);
139
+ this.memory.seek(memPos);
140
+ const memBuffer = new Uint8Array(sizeInMem);
141
+ this.memory.memory.readFully(memBuffer);
142
+ buffer.set(memBuffer, pos);
143
+ pos += sizeInMem;
144
+ this.filePos += sizeInMem;
145
+ }
146
+ if (pos === buffer.length)
147
+ return;
148
+ // read from the disk -- after the in-memory buffer
149
+ if (this.filePos >= this.memoryPos + this.memory.length()) {
150
+ const sizeAfterMem = buffer.length - pos;
151
+ const tempBuffer = new Uint8Array(sizeAfterMem);
152
+ this.file.seek(this.filePos);
153
+ this.file.reader().readFully(tempBuffer);
154
+ buffer.set(tempBuffer, pos);
155
+ pos += sizeAfterMem;
156
+ this.filePos += sizeAfterMem;
157
+ }
158
+ }
159
+ readByte() {
160
+ const bytes = new Uint8Array(1);
161
+ this.readFully(bytes);
162
+ return bytes[0];
163
+ }
164
+ readShort() {
165
+ const bytes = new Uint8Array(2);
166
+ this.readFully(bytes);
167
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
168
+ return view.getInt16(0, false); // big-endian
169
+ }
170
+ readInt() {
171
+ const bytes = new Uint8Array(4);
172
+ this.readFully(bytes);
173
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
174
+ return view.getInt32(0, false); // big-endian
175
+ }
176
+ readLong() {
177
+ const bytes = new Uint8Array(8);
178
+ this.readFully(bytes);
179
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
180
+ return Number(view.getBigInt64(0, false));
181
+ }
182
+ }
@@ -1,18 +1,16 @@
1
- import type { Core, DataReader, DataWriter } from './core';
2
- import type { FileHandle } from 'fs/promises';
1
+ import type { Core, DataReader, DataWriter } from './core.js';
3
2
  export declare class CoreFile implements Core {
4
3
  filePath: string;
5
4
  private _position;
6
- fileHandle: FileHandle;
7
- private constructor();
8
- static create(filePath: string): Promise<CoreFile>;
5
+ fd: number;
6
+ constructor(filePath: string);
9
7
  reader(): DataReader;
10
8
  writer(): DataWriter;
11
- length(): Promise<number>;
12
- seek(pos: number): Promise<void>;
9
+ length(): number;
10
+ seek(pos: number): void;
13
11
  position(): number;
14
- setLength(len: number): Promise<void>;
15
- flush(): Promise<void>;
16
- sync(): Promise<void>;
12
+ setLength(len: number): void;
13
+ flush(): void;
14
+ sync(): void;
17
15
  [Symbol.dispose](): void;
18
16
  }
@@ -0,0 +1,105 @@
1
+ import * as fs from 'fs';
2
+ export class CoreFile {
3
+ filePath;
4
+ _position = 0;
5
+ fd;
6
+ constructor(filePath) {
7
+ this.filePath = filePath;
8
+ // Create file if it doesn't exist
9
+ try {
10
+ fs.accessSync(filePath);
11
+ }
12
+ catch {
13
+ fs.writeFileSync(filePath, new Uint8Array(0));
14
+ }
15
+ // Open file for reading and writing
16
+ this.fd = fs.openSync(filePath, 'r+');
17
+ }
18
+ reader() {
19
+ return new FileDataReader(this);
20
+ }
21
+ writer() {
22
+ return new FileDataWriter(this);
23
+ }
24
+ length() {
25
+ const stats = fs.fstatSync(this.fd);
26
+ return stats.size;
27
+ }
28
+ seek(pos) {
29
+ this._position = pos;
30
+ }
31
+ position() {
32
+ return this._position;
33
+ }
34
+ setLength(len) {
35
+ fs.ftruncateSync(this.fd, len);
36
+ }
37
+ flush() {
38
+ }
39
+ sync() {
40
+ fs.fsyncSync(this.fd);
41
+ }
42
+ [Symbol.dispose]() {
43
+ fs.closeSync(this.fd);
44
+ }
45
+ }
46
+ class FileDataReader {
47
+ core;
48
+ constructor(core) {
49
+ this.core = core;
50
+ }
51
+ readFully(b) {
52
+ const position = this.core.position();
53
+ fs.readSync(this.core.fd, b, 0, b.length, position);
54
+ this.core.seek(position + b.length);
55
+ }
56
+ readByte() {
57
+ const bytes = new Uint8Array(1);
58
+ this.readFully(bytes);
59
+ return bytes[0];
60
+ }
61
+ readShort() {
62
+ const bytes = new Uint8Array(2);
63
+ this.readFully(bytes);
64
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
65
+ return view.getInt16(0, false);
66
+ }
67
+ readInt() {
68
+ const bytes = new Uint8Array(4);
69
+ this.readFully(bytes);
70
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
71
+ return view.getInt32(0, false);
72
+ }
73
+ readLong() {
74
+ const bytes = new Uint8Array(8);
75
+ this.readFully(bytes);
76
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
77
+ return Number(view.getBigInt64(0, false));
78
+ }
79
+ }
80
+ class FileDataWriter {
81
+ core;
82
+ constructor(core) {
83
+ this.core = core;
84
+ }
85
+ write(buffer) {
86
+ const position = this.core.position();
87
+ fs.writeSync(this.core.fd, buffer, 0, buffer.length, position);
88
+ this.core.seek(position + buffer.length);
89
+ }
90
+ writeByte(v) {
91
+ this.write(new Uint8Array([v & 0xff]));
92
+ }
93
+ writeShort(v) {
94
+ const buffer = new ArrayBuffer(2);
95
+ const view = new DataView(buffer);
96
+ view.setInt16(0, v, false);
97
+ this.write(new Uint8Array(buffer));
98
+ }
99
+ writeLong(v) {
100
+ const buffer = new ArrayBuffer(8);
101
+ const view = new DataView(buffer);
102
+ view.setBigInt64(0, BigInt(v), false);
103
+ this.write(new Uint8Array(buffer));
104
+ }
105
+ }
@@ -1,15 +1,15 @@
1
- import type { Core, DataReader, DataWriter } from './core';
1
+ import type { Core, DataReader, DataWriter } from './core.js';
2
2
  export declare class CoreMemory implements Core {
3
3
  memory: RandomAccessMemory;
4
4
  constructor();
5
5
  reader(): DataReader;
6
6
  writer(): DataWriter;
7
- length(): Promise<number>;
8
- seek(pos: number): Promise<void>;
7
+ length(): number;
8
+ seek(pos: number): void;
9
9
  position(): number;
10
- setLength(len: number): Promise<void>;
11
- flush(): Promise<void>;
12
- sync(): Promise<void>;
10
+ setLength(len: number): void;
11
+ flush(): void;
12
+ sync(): void;
13
13
  }
14
14
  declare class RandomAccessMemory implements DataReader, DataWriter {
15
15
  private buffer;
@@ -23,14 +23,14 @@ declare class RandomAccessMemory implements DataReader, DataWriter {
23
23
  setLength(len: number): void;
24
24
  reset(): void;
25
25
  toByteArray(): Uint8Array;
26
- write(data: Uint8Array): Promise<void>;
27
- writeByte(v: number): Promise<void>;
28
- writeShort(v: number): Promise<void>;
29
- writeLong(v: number): Promise<void>;
30
- readFully(b: Uint8Array): Promise<void>;
31
- readByte(): Promise<number>;
32
- readShort(): Promise<number>;
33
- readInt(): Promise<number>;
34
- readLong(): Promise<number>;
26
+ write(data: Uint8Array): void;
27
+ writeByte(v: number): void;
28
+ writeShort(v: number): void;
29
+ writeLong(v: number): void;
30
+ readFully(b: Uint8Array): void;
31
+ readByte(): number;
32
+ readShort(): number;
33
+ readInt(): number;
34
+ readLong(): number;
35
35
  }
36
36
  export {};
@@ -0,0 +1,152 @@
1
+ export class CoreMemory {
2
+ memory;
3
+ constructor() {
4
+ this.memory = new RandomAccessMemory();
5
+ }
6
+ reader() {
7
+ return this.memory;
8
+ }
9
+ writer() {
10
+ return this.memory;
11
+ }
12
+ length() {
13
+ return this.memory.size();
14
+ }
15
+ seek(pos) {
16
+ this.memory.seek(pos);
17
+ }
18
+ position() {
19
+ return this.memory.getPosition();
20
+ }
21
+ setLength(len) {
22
+ this.memory.setLength(len);
23
+ }
24
+ flush() {
25
+ // no-op for in-memory
26
+ }
27
+ sync() {
28
+ // no-op for in-memory
29
+ }
30
+ }
31
+ class RandomAccessMemory {
32
+ buffer;
33
+ _position = 0;
34
+ _count = 0;
35
+ constructor(initialSize = 1024) {
36
+ this.buffer = new Uint8Array(initialSize);
37
+ }
38
+ ensureCapacity(minCapacity) {
39
+ if (minCapacity > this.buffer.length) {
40
+ let newCapacity = this.buffer.length * 2;
41
+ if (newCapacity < minCapacity) {
42
+ newCapacity = minCapacity;
43
+ }
44
+ const newBuffer = new Uint8Array(newCapacity);
45
+ newBuffer.set(this.buffer.subarray(0, this._count));
46
+ this.buffer = newBuffer;
47
+ }
48
+ }
49
+ size() {
50
+ return this._count;
51
+ }
52
+ seek(pos) {
53
+ if (pos > this._count) {
54
+ this._position = this._count;
55
+ }
56
+ else {
57
+ this._position = pos;
58
+ }
59
+ }
60
+ getPosition() {
61
+ return this._position;
62
+ }
63
+ setLength(len) {
64
+ if (len === 0) {
65
+ this.reset();
66
+ }
67
+ else {
68
+ if (len > this._count)
69
+ throw new Error('Cannot extend length');
70
+ this._count = len;
71
+ if (this._position > len) {
72
+ this._position = len;
73
+ }
74
+ }
75
+ }
76
+ reset() {
77
+ this._count = 0;
78
+ this._position = 0;
79
+ }
80
+ toByteArray() {
81
+ return this.buffer.slice(0, this._count);
82
+ }
83
+ // DataWriter interface
84
+ write(data) {
85
+ const pos = this._position;
86
+ if (pos < this._count) {
87
+ const bytesBeforeEnd = Math.min(data.length, this._count - pos);
88
+ for (let i = 0; i < bytesBeforeEnd; i++) {
89
+ this.buffer[pos + i] = data[i];
90
+ }
91
+ if (bytesBeforeEnd < data.length) {
92
+ const bytesAfterEnd = data.length - bytesBeforeEnd;
93
+ this.ensureCapacity(this._count + bytesAfterEnd);
94
+ this.buffer.set(data.subarray(bytesBeforeEnd), this._count);
95
+ this._count += bytesAfterEnd;
96
+ }
97
+ }
98
+ else {
99
+ this.ensureCapacity(this._count + data.length);
100
+ this.buffer.set(data, this._count);
101
+ this._count += data.length;
102
+ }
103
+ this._position = pos + data.length;
104
+ }
105
+ writeByte(v) {
106
+ this.write(new Uint8Array([v & 0xff]));
107
+ }
108
+ writeShort(v) {
109
+ const buffer = new ArrayBuffer(2);
110
+ const view = new DataView(buffer);
111
+ view.setInt16(0, v, false); // big-endian
112
+ this.write(new Uint8Array(buffer));
113
+ }
114
+ writeLong(v) {
115
+ const buffer = new ArrayBuffer(8);
116
+ const view = new DataView(buffer);
117
+ view.setBigInt64(0, BigInt(v), false);
118
+ this.write(new Uint8Array(buffer));
119
+ }
120
+ // DataReader interface
121
+ readFully(b) {
122
+ const pos = this._position;
123
+ if (pos + b.length > this._count) {
124
+ throw new Error('End of stream');
125
+ }
126
+ b.set(this.buffer.subarray(pos, pos + b.length));
127
+ this._position = pos + b.length;
128
+ }
129
+ readByte() {
130
+ const bytes = new Uint8Array(1);
131
+ this.readFully(bytes);
132
+ return bytes[0];
133
+ }
134
+ readShort() {
135
+ const bytes = new Uint8Array(2);
136
+ this.readFully(bytes);
137
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
138
+ return view.getInt16(0, false); // big-endian
139
+ }
140
+ readInt() {
141
+ const bytes = new Uint8Array(4);
142
+ this.readFully(bytes);
143
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
144
+ return view.getInt32(0, false); // big-endian
145
+ }
146
+ readLong() {
147
+ const bytes = new Uint8Array(8);
148
+ this.readFully(bytes);
149
+ const view = new DataView(bytes.buffer, bytes.byteOffset, bytes.byteLength);
150
+ return Number(view.getBigInt64(0, false));
151
+ }
152
+ }
package/dist/core.d.ts CHANGED
@@ -1,23 +1,23 @@
1
1
  export interface DataReader {
2
- readFully(buffer: Uint8Array): Promise<void>;
3
- readByte(): Promise<number>;
4
- readShort(): Promise<number>;
5
- readInt(): Promise<number>;
6
- readLong(): Promise<number>;
2
+ readFully(buffer: Uint8Array): void;
3
+ readByte(): number;
4
+ readShort(): number;
5
+ readInt(): number;
6
+ readLong(): number;
7
7
  }
8
8
  export interface DataWriter {
9
- write(buffer: Uint8Array): Promise<void>;
10
- writeByte(v: number): Promise<void>;
11
- writeShort(v: number): Promise<void>;
12
- writeLong(v: number): Promise<void>;
9
+ write(buffer: Uint8Array): void;
10
+ writeByte(v: number): void;
11
+ writeShort(v: number): void;
12
+ writeLong(v: number): void;
13
13
  }
14
14
  export interface Core {
15
15
  reader(): DataReader;
16
16
  writer(): DataWriter;
17
- length(): Promise<number>;
18
- seek(pos: number): Promise<void>;
17
+ length(): number;
18
+ seek(pos: number): void;
19
19
  position(): number;
20
- setLength(len: number): Promise<void>;
21
- flush(): Promise<void>;
22
- sync(): Promise<void>;
20
+ setLength(len: number): void;
21
+ flush(): void;
22
+ sync(): void;
23
23
  }
package/dist/core.js ADDED
@@ -0,0 +1 @@
1
+ export {};