@based/db 0.0.27 → 0.0.29
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 +1 -399
- package/dist/lib/darwin_aarch64/include/selva/db.h +8 -4
- package/dist/lib/darwin_aarch64/include/selva/selva_hash128.h +17 -7
- package/dist/lib/darwin_aarch64/include/selva/sort.h +21 -14
- package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
- package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +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/darwin_aarch64/libnode-v22.node +0 -0
- package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
- package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
- package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
- package/dist/lib/linux_aarch64/include/selva/db.h +8 -4
- package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +17 -7
- package/dist/lib/linux_aarch64/include/selva/sort.h +21 -14
- package/dist/lib/linux_aarch64/libdeflate.so +0 -0
- package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +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_aarch64/libnode-v22.node +0 -0
- package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
- package/dist/lib/linux_aarch64/libselva.so +0 -0
- package/dist/lib/linux_x86_64/include/selva/db.h +8 -4
- package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +17 -7
- package/dist/lib/linux_x86_64/include/selva/sort.h +21 -14
- package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +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/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/libselva.so +0 -0
- package/dist/src/client/flushModify.d.ts +1 -1
- package/dist/src/client/flushModify.js +12 -17
- package/dist/src/client/index.d.ts +6 -4
- package/dist/src/client/index.js +19 -2
- package/dist/src/client/modify/ModifyRes.d.ts +1 -1
- package/dist/src/client/modify/ModifyRes.js +14 -18
- package/dist/src/client/modify/fixed.js +43 -8
- package/dist/src/client/modify/modify.js +0 -1
- package/dist/src/client/modify/references/{appendRefs.d.ts → appendEdgeRefs.d.ts} +1 -1
- package/dist/src/client/modify/references/{appendRefs.js → appendEdgeRefs.js} +5 -2
- package/dist/src/client/modify/references/edge.js +182 -175
- package/dist/src/client/modify/references/reference.js +4 -8
- package/dist/src/client/modify/references/references.js +18 -14
- package/dist/src/client/modify/string.js +0 -3
- package/dist/src/client/modify/text.js +11 -3
- package/dist/src/client/modify/types.d.ts +11 -0
- package/dist/src/client/modify/types.js +10 -0
- package/dist/src/client/modify/update.js +4 -1
- package/dist/src/client/modify/vector.js +13 -4
- package/dist/src/client/query/BasedDbQuery.d.ts +1 -1
- package/dist/src/client/query/BasedDbQuery.js +2 -2
- package/dist/src/client/query/BasedIterable.d.ts +1 -1
- package/dist/src/client/query/BasedIterable.js +7 -2
- package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +2 -1
- package/dist/src/client/query/filter/createFixedFilterBuffer.js +11 -28
- package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
- package/dist/src/client/query/filter/createReferenceFilter.js +10 -9
- package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
- package/dist/src/client/query/filter/createVariableFilterBuffer.js +8 -10
- package/dist/src/client/query/filter/parseFilterValue.js +1 -1
- package/dist/src/client/query/filter/primitiveFilter.js +9 -9
- package/dist/src/client/query/filter/toBuffer.js +0 -15
- package/dist/src/client/query/filter/types.d.ts +1 -0
- package/dist/src/client/query/filter/types.js +1 -0
- package/dist/src/client/query/include/walk.js +0 -1
- package/dist/src/client/query/read/read.js +4 -4
- package/dist/src/client/query/search/index.js +11 -15
- package/dist/src/client/query/subscription/markers.js +1 -2
- package/dist/src/client/query/subscription/run.js +0 -2
- package/dist/src/client/query/thresholds.d.ts +0 -2
- package/dist/src/client/query/thresholds.js +0 -2
- package/dist/src/client/query/toBuffer.js +16 -42
- package/dist/src/client/query/types.d.ts +3 -2
- package/dist/src/client/query/validation.d.ts +1 -3
- package/dist/src/client/query/validation.js +6 -18
- package/dist/src/client/string.d.ts +2 -0
- package/dist/src/client/string.js +9 -13
- package/dist/src/index.d.ts +1 -1
- package/dist/src/index.js +7 -15
- package/dist/src/native.d.ts +1 -1
- package/dist/src/native.js +3 -3
- package/dist/src/server/csmt/draw-dot.js +2 -2
- package/dist/src/server/csmt/tree.js +57 -6
- package/dist/src/server/csmt/types.d.ts +5 -0
- package/dist/src/server/index.d.ts +4 -3
- package/dist/src/server/index.js +44 -44
- package/dist/src/server/migrate/index.js +47 -29
- package/dist/src/server/migrate/worker.js +2 -2
- package/dist/src/server/save.js +40 -28
- package/dist/src/server/start.js +7 -19
- package/dist/src/server/tree.d.ts +2 -0
- package/dist/src/server/tree.js +34 -2
- package/dist/src/server/worker.js +3 -3
- package/dist/src/utils.d.ts +3 -1
- package/dist/src/utils.js +43 -19
- package/package.json +9 -3
- package/dist/lib/darwin_aarch64/include/selva/base64.h +0 -59
- package/dist/lib/darwin_aarch64/include/selva/base64url.h +0 -59
- package/dist/lib/linux_aarch64/include/selva/base64.h +0 -59
- package/dist/lib/linux_aarch64/include/selva/base64url.h +0 -59
- package/dist/lib/linux_x86_64/include/selva/base64.h +0 -59
- package/dist/lib/linux_x86_64/include/selva/base64url.h +0 -59
- package/dist/src/client/timestamp.d.ts +0 -1
- package/dist/src/client/timestamp.js +0 -68
package/README.md
CHANGED
|
@@ -18,7 +18,7 @@ BasedDb is a powerful database solution that supports various data types, refere
|
|
|
18
18
|
|
|
19
19
|
- recent GNU make
|
|
20
20
|
- gcc with recent enough C23 support
|
|
21
|
-
- zig 0.
|
|
21
|
+
- zig 0.14.0
|
|
22
22
|
- npm & node.js, v20.11.1 or newer
|
|
23
23
|
|
|
24
24
|
```bash
|
|
@@ -60,401 +60,3 @@ Builds nothing only runs tests
|
|
|
60
60
|
```bash
|
|
61
61
|
npm run test-fast
|
|
62
62
|
```
|
|
63
|
-
|
|
64
|
-
## Getting Started
|
|
65
|
-
|
|
66
|
-
To get started with BasedDb, follow these steps:
|
|
67
|
-
|
|
68
|
-
1. Install the package
|
|
69
|
-
2. Define your schema
|
|
70
|
-
3. Start the database
|
|
71
|
-
4. Perform operations like create, query, update, and delete
|
|
72
|
-
|
|
73
|
-
```ts
|
|
74
|
-
const db = new BasedDb({
|
|
75
|
-
path: '/persistent-file-path',
|
|
76
|
-
})
|
|
77
|
-
```
|
|
78
|
-
|
|
79
|
-
## Schema Definition
|
|
80
|
-
|
|
81
|
-
Define your schema using the `setSchema` method. Here is an example:
|
|
82
|
-
|
|
83
|
-
```typescript
|
|
84
|
-
await db.setSchema({
|
|
85
|
-
types: {
|
|
86
|
-
user: {
|
|
87
|
-
name: 'string',
|
|
88
|
-
age: 'number',
|
|
89
|
-
email: 'alias',
|
|
90
|
-
isNice: 'boolean',
|
|
91
|
-
roles: ['admin', 'editor', 'viewer'],
|
|
92
|
-
file: 'binary',
|
|
93
|
-
bestFriend: {
|
|
94
|
-
ref: 'user',
|
|
95
|
-
prop: 'bestFriend',
|
|
96
|
-
},
|
|
97
|
-
friends: {
|
|
98
|
-
items: {
|
|
99
|
-
ref: 'user',
|
|
100
|
-
prop: 'friends',
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
},
|
|
104
|
-
article: {
|
|
105
|
-
body: 'string',
|
|
106
|
-
myUniqueValuesCount: 'cardinality',
|
|
107
|
-
contributors: {
|
|
108
|
-
type: 'references',
|
|
109
|
-
items: {
|
|
110
|
-
ref: 'user',
|
|
111
|
-
prop: 'articles',
|
|
112
|
-
$role: ['writer', 'editor'],
|
|
113
|
-
},
|
|
114
|
-
},
|
|
115
|
-
},
|
|
116
|
-
page: {
|
|
117
|
-
name: 'string',
|
|
118
|
-
clients: {
|
|
119
|
-
items: {
|
|
120
|
-
ref: '_client',
|
|
121
|
-
prop: 'pages',
|
|
122
|
-
$viewers: 'uint8',
|
|
123
|
-
},
|
|
124
|
-
},
|
|
125
|
-
activeViewers: {
|
|
126
|
-
type: 'uint32',
|
|
127
|
-
path: 'clients.$viewers.#sum',
|
|
128
|
-
history: {
|
|
129
|
-
interval: 'second',
|
|
130
|
-
},
|
|
131
|
-
},
|
|
132
|
-
},
|
|
133
|
-
_client: {
|
|
134
|
-
name: 'string',
|
|
135
|
-
},
|
|
136
|
-
},
|
|
137
|
-
})
|
|
138
|
-
```
|
|
139
|
-
|
|
140
|
-
## Data Operations
|
|
141
|
-
|
|
142
|
-
### Create
|
|
143
|
-
|
|
144
|
-
Create new records using the `create` method:
|
|
145
|
-
|
|
146
|
-
```typescript
|
|
147
|
-
const userId = await db.create('user', {
|
|
148
|
-
name: 'youzi',
|
|
149
|
-
email: 'youzi@example.com',
|
|
150
|
-
isNice: true,
|
|
151
|
-
roles: 'admin',
|
|
152
|
-
})
|
|
153
|
-
```
|
|
154
|
-
|
|
155
|
-
### Query & Filters
|
|
156
|
-
|
|
157
|
-
Query records using the `query` method:
|
|
158
|
-
|
|
159
|
-
```typescript
|
|
160
|
-
const results = await db
|
|
161
|
-
.query('user')
|
|
162
|
-
.filter('isNice', '=', true)
|
|
163
|
-
.filter('name', '=', 'youzi')
|
|
164
|
-
.get()
|
|
165
|
-
.toObject()
|
|
166
|
-
```
|
|
167
|
-
|
|
168
|
-
### Update
|
|
169
|
-
|
|
170
|
-
Update records using the `update` method:
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
await db.update('user', userId, {
|
|
174
|
-
roles: 'editor',
|
|
175
|
-
})
|
|
176
|
-
```
|
|
177
|
-
|
|
178
|
-
### Delete
|
|
179
|
-
|
|
180
|
-
Delete records using the `delete` method:
|
|
181
|
-
|
|
182
|
-
```typescript
|
|
183
|
-
await db.delete('user', userId)
|
|
184
|
-
```
|
|
185
|
-
|
|
186
|
-
## Advanced Features
|
|
187
|
-
|
|
188
|
-
### Copy
|
|
189
|
-
|
|
190
|
-
Copy records with transformations:
|
|
191
|
-
|
|
192
|
-
```typescript
|
|
193
|
-
await db.copy('edition', editionId, {
|
|
194
|
-
copiedByYouzi: true,
|
|
195
|
-
versionOf({ id }) {
|
|
196
|
-
return id
|
|
197
|
-
},
|
|
198
|
-
name({ name }) {
|
|
199
|
-
return name + ' (edition copy)'
|
|
200
|
-
},
|
|
201
|
-
sequences({ sequences }) {
|
|
202
|
-
return sequences.map(({ id }) => {
|
|
203
|
-
return db.copy('sequence', id, {
|
|
204
|
-
copiedByYouzi: true,
|
|
205
|
-
name({ name }) {
|
|
206
|
-
return name + ' (sequence copy)'
|
|
207
|
-
},
|
|
208
|
-
pages({ pages }) {
|
|
209
|
-
return pages.map(({ id }) =>
|
|
210
|
-
db.copy('page', id, {
|
|
211
|
-
copiedByYouzi: true,
|
|
212
|
-
name({ name }) {
|
|
213
|
-
return name + ' (page copy)'
|
|
214
|
-
},
|
|
215
|
-
}),
|
|
216
|
-
)
|
|
217
|
-
},
|
|
218
|
-
})
|
|
219
|
-
})
|
|
220
|
-
},
|
|
221
|
-
})
|
|
222
|
-
```
|
|
223
|
-
|
|
224
|
-
### Concurrency
|
|
225
|
-
|
|
226
|
-
Concurrent write and read operations are supported. The example below shows multiple concurrent queries and creates. Handle concurrency carefully to avoid conflicts:
|
|
227
|
-
|
|
228
|
-
```typescript
|
|
229
|
-
let id = 0
|
|
230
|
-
let queries = 0
|
|
231
|
-
let refs = []
|
|
232
|
-
let timer = setTimeout(() => {
|
|
233
|
-
timer = null
|
|
234
|
-
}, 5e3)
|
|
235
|
-
|
|
236
|
-
const query = async () => {
|
|
237
|
-
queries++
|
|
238
|
-
try {
|
|
239
|
-
await db.query('user').include('friends').range(0, 1000_000).get()
|
|
240
|
-
} catch (e) {
|
|
241
|
-
console.error('err:', e)
|
|
242
|
-
}
|
|
243
|
-
queries--
|
|
244
|
-
}
|
|
245
|
-
|
|
246
|
-
while (timer) {
|
|
247
|
-
let i = 100
|
|
248
|
-
while (i--) {
|
|
249
|
-
query()
|
|
250
|
-
}
|
|
251
|
-
while (timer && queries) {
|
|
252
|
-
db.create('user', {
|
|
253
|
-
friends: refs,
|
|
254
|
-
})
|
|
255
|
-
refs.push(++id)
|
|
256
|
-
await db.drain()
|
|
257
|
-
await setTimeoutAsync()
|
|
258
|
-
}
|
|
259
|
-
}
|
|
260
|
-
|
|
261
|
-
clearTimeout(timer)
|
|
262
|
-
```
|
|
263
|
-
|
|
264
|
-
### Client-Server
|
|
265
|
-
|
|
266
|
-
Set up a client-server architecture:
|
|
267
|
-
|
|
268
|
-
```typescript
|
|
269
|
-
const server = new DbServer({
|
|
270
|
-
path: t.tmp,
|
|
271
|
-
onSchemaChange(schema) {
|
|
272
|
-
client1.putLocalSchema(schema)
|
|
273
|
-
client2.putLocalSchema(schema)
|
|
274
|
-
},
|
|
275
|
-
})
|
|
276
|
-
|
|
277
|
-
await server.start({ clean: true })
|
|
278
|
-
|
|
279
|
-
const hooks: DbClientHooks = {
|
|
280
|
-
async setSchema(schema, fromStart, transformFns) {
|
|
281
|
-
return server.setSchema(schema, fromStart, transformFns)
|
|
282
|
-
},
|
|
283
|
-
async flushModify(buf) {
|
|
284
|
-
const offsets = server.modify(buf)
|
|
285
|
-
return { offsets }
|
|
286
|
-
},
|
|
287
|
-
async getQueryBuf(buf) {
|
|
288
|
-
return server.getQueryBuf(buf)
|
|
289
|
-
},
|
|
290
|
-
}
|
|
291
|
-
|
|
292
|
-
const client1 = new DbClient({ hooks })
|
|
293
|
-
const client2 = new DbClient({ hooks })
|
|
294
|
-
|
|
295
|
-
await client1.setSchema({
|
|
296
|
-
types: {
|
|
297
|
-
user: {
|
|
298
|
-
name: 'string',
|
|
299
|
-
},
|
|
300
|
-
},
|
|
301
|
-
})
|
|
302
|
-
|
|
303
|
-
const youzi = await client1.create('user', { name: 'youzi' })
|
|
304
|
-
const jamez = await client1.create('user', { name: 'jamez' })
|
|
305
|
-
|
|
306
|
-
deepEqual(await client1.query('user').get().toObject(), [
|
|
307
|
-
{ id: 1, name: 'youzi' },
|
|
308
|
-
{ id: 2, name: 'jamez' },
|
|
309
|
-
])
|
|
310
|
-
```
|
|
311
|
-
|
|
312
|
-
### Checksum
|
|
313
|
-
|
|
314
|
-
Include checksum in queries:
|
|
315
|
-
|
|
316
|
-
```typescript
|
|
317
|
-
await db.query('article').include('*', '_checksum')
|
|
318
|
-
```
|
|
319
|
-
|
|
320
|
-
### Cardinality
|
|
321
|
-
|
|
322
|
-
Use cardinality for unique value counts:
|
|
323
|
-
|
|
324
|
-
```typescript
|
|
325
|
-
await db.setSchema({
|
|
326
|
-
types: {
|
|
327
|
-
article: {
|
|
328
|
-
myUniqueValuesCount: 'cardinality',
|
|
329
|
-
},
|
|
330
|
-
},
|
|
331
|
-
})
|
|
332
|
-
|
|
333
|
-
const myArticle = await db.create('article', {
|
|
334
|
-
myUniqueValuesCount: 'myCoolValue',
|
|
335
|
-
})
|
|
336
|
-
```
|
|
337
|
-
|
|
338
|
-
### Boolean
|
|
339
|
-
|
|
340
|
-
Handle boolean properties:
|
|
341
|
-
|
|
342
|
-
```typescript
|
|
343
|
-
await db.setSchema({
|
|
344
|
-
types: {
|
|
345
|
-
user: {
|
|
346
|
-
props: {
|
|
347
|
-
isNice: 'boolean',
|
|
348
|
-
},
|
|
349
|
-
},
|
|
350
|
-
},
|
|
351
|
-
})
|
|
352
|
-
|
|
353
|
-
db.create('user', {})
|
|
354
|
-
db.create('user', { isNice: true })
|
|
355
|
-
db.create('user', { isNice: false })
|
|
356
|
-
|
|
357
|
-
await db.drain()
|
|
358
|
-
|
|
359
|
-
deepEqual((await db.query('user').get()).toObject(), [
|
|
360
|
-
{ id: 1, isNice: false },
|
|
361
|
-
{ id: 2, isNice: true },
|
|
362
|
-
{ id: 3, isNice: false },
|
|
363
|
-
])
|
|
364
|
-
```
|
|
365
|
-
|
|
366
|
-
### Binary
|
|
367
|
-
|
|
368
|
-
Handle binary data:
|
|
369
|
-
|
|
370
|
-
```typescript
|
|
371
|
-
await db.setSchema({
|
|
372
|
-
types: {
|
|
373
|
-
user: {
|
|
374
|
-
props: {
|
|
375
|
-
file: { type: 'binary' },
|
|
376
|
-
},
|
|
377
|
-
},
|
|
378
|
-
},
|
|
379
|
-
})
|
|
380
|
-
|
|
381
|
-
db.create('user', {
|
|
382
|
-
file: new Uint32Array([1, 2, 3, 4]),
|
|
383
|
-
})
|
|
384
|
-
|
|
385
|
-
await db.drain()
|
|
386
|
-
|
|
387
|
-
deepEqual((await db.query('user').get()).toObject(), [
|
|
388
|
-
{
|
|
389
|
-
id: 1,
|
|
390
|
-
file: new Uint8Array(new Uint32Array([1, 2, 3, 4]).buffer),
|
|
391
|
-
},
|
|
392
|
-
])
|
|
393
|
-
```
|
|
394
|
-
|
|
395
|
-
### Analytics
|
|
396
|
-
|
|
397
|
-
Perform analytics on data:
|
|
398
|
-
|
|
399
|
-
```typescript
|
|
400
|
-
await db.setSchema({
|
|
401
|
-
types: {
|
|
402
|
-
page: {
|
|
403
|
-
name: 'string',
|
|
404
|
-
clients: {
|
|
405
|
-
items: {
|
|
406
|
-
ref: '_client',
|
|
407
|
-
prop: 'pages',
|
|
408
|
-
$viewers: 'uint8',
|
|
409
|
-
},
|
|
410
|
-
},
|
|
411
|
-
activeViewers: {
|
|
412
|
-
type: 'uint32',
|
|
413
|
-
path: 'clients.$viewers.#sum',
|
|
414
|
-
history: {
|
|
415
|
-
interval: 'second',
|
|
416
|
-
},
|
|
417
|
-
},
|
|
418
|
-
},
|
|
419
|
-
},
|
|
420
|
-
})
|
|
421
|
-
|
|
422
|
-
const client = await db.create('_client', {})
|
|
423
|
-
const page = await db.create('page', {
|
|
424
|
-
clients: [
|
|
425
|
-
{
|
|
426
|
-
id: client,
|
|
427
|
-
$viewers: { increment: 1 },
|
|
428
|
-
},
|
|
429
|
-
],
|
|
430
|
-
})
|
|
431
|
-
```
|
|
432
|
-
|
|
433
|
-
### Alias
|
|
434
|
-
|
|
435
|
-
Use aliases for properties:
|
|
436
|
-
|
|
437
|
-
```typescript
|
|
438
|
-
await db.setSchema({
|
|
439
|
-
types: {
|
|
440
|
-
user: {
|
|
441
|
-
props: {
|
|
442
|
-
externalId: 'alias',
|
|
443
|
-
potato: 'string',
|
|
444
|
-
},
|
|
445
|
-
},
|
|
446
|
-
},
|
|
447
|
-
})
|
|
448
|
-
|
|
449
|
-
const user1 = db.create('user', {
|
|
450
|
-
externalId: 'cool',
|
|
451
|
-
})
|
|
452
|
-
|
|
453
|
-
await db.drain()
|
|
454
|
-
|
|
455
|
-
deepEqual((await db.query('user', user1).get()).toObject(), {
|
|
456
|
-
id: 1,
|
|
457
|
-
externalId: 'cool',
|
|
458
|
-
potato: '',
|
|
459
|
-
})
|
|
460
|
-
```
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
#pragma once
|
|
6
6
|
|
|
7
|
+
#include <assert.h>
|
|
7
8
|
#include <sys/types.h>
|
|
8
9
|
#include "selva/_export.h"
|
|
9
10
|
#include "selva/types.h"
|
|
@@ -179,13 +180,16 @@ inline enum SelvaFieldType selva_get_fs_type(const struct SelvaFieldSchema *fs)
|
|
|
179
180
|
* struct SelvaFieldSchema *dst_fs = selva_get_fs_by_node(db, dst, efc->inverse_field);
|
|
180
181
|
*/
|
|
181
182
|
SELVA_EXPORT
|
|
183
|
+
__attribute__((returns_nonnull))
|
|
182
184
|
__attribute__((nonnull))
|
|
183
185
|
inline const struct EdgeFieldConstraint *selva_get_edge_field_constraint(const struct SelvaFieldSchema *fs)
|
|
184
186
|
#ifndef __zig
|
|
185
187
|
{
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
assert(fs->type == SELVA_FIELD_TYPE_REFERENCE ||
|
|
189
|
+
fs->type == SELVA_FIELD_TYPE_REFERENCES ||
|
|
190
|
+
fs->type == SELVA_FIELD_TYPE_WEAK_REFERENCE ||
|
|
191
|
+
fs->type == SELVA_FIELD_TYPE_WEAK_REFERENCES);
|
|
192
|
+
return &fs->edge_constraint;
|
|
189
193
|
}
|
|
190
194
|
#else
|
|
191
195
|
;
|
|
@@ -349,7 +353,7 @@ SELVA_EXPORT
|
|
|
349
353
|
selva_hash128_t selva_node_hash(struct SelvaDb *db, struct SelvaTypeEntry *type, struct SelvaNode *node);
|
|
350
354
|
|
|
351
355
|
SELVA_EXPORT
|
|
352
|
-
|
|
356
|
+
int selva_node_hash_range(struct SelvaDb *db, struct SelvaTypeEntry *type, node_id_t start, node_id_t end, selva_hash128_t *hash_out) __attribute__((nonnull, warn_unused_result));
|
|
353
357
|
|
|
354
358
|
/**
|
|
355
359
|
* @}
|
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2024 SAULX
|
|
2
|
+
* Copyright (c) 2024-2025 SAULX
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
#pragma once
|
|
6
6
|
#include "xxhash.h"
|
|
7
|
+
#include "jemalloc_selva.h"
|
|
7
8
|
#include "selva/types.h"
|
|
8
9
|
|
|
9
10
|
typedef struct XXH3_state_s selva_hash_state_t;
|
|
10
11
|
|
|
11
|
-
#define selva_hash_create_state XXH3_createState
|
|
12
12
|
#define selva_hash_reset XXH3_128bits_reset
|
|
13
|
-
#define selva_hash_free_state XXH3_freeState
|
|
14
13
|
#define selva_hash_update XXH3_128bits_update
|
|
15
14
|
|
|
16
15
|
SELVA_EXPORT
|
|
17
|
-
|
|
16
|
+
selva_hash_state_t *selva_hash_create_state(void);
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
SELVA_EXPORT
|
|
19
|
+
inline void selva_hash_free_state(selva_hash_state_t *state)
|
|
20
|
+
#ifndef __zig
|
|
21
|
+
{
|
|
22
|
+
selva_free(state);
|
|
23
|
+
}
|
|
21
24
|
#else
|
|
22
|
-
|
|
25
|
+
;
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
SELVA_EXPORT
|
|
29
|
+
inline selva_hash128_t selva_hash_digest(selva_hash_state_t *hash_state)
|
|
30
|
+
#ifndef __zig
|
|
23
31
|
{
|
|
24
32
|
XXH128_hash_t res;
|
|
25
33
|
|
|
@@ -36,4 +44,6 @@ retry:
|
|
|
36
44
|
|
|
37
45
|
return (selva_hash128_t)res.low64 | (selva_hash128_t)res.high64 << 64;
|
|
38
46
|
}
|
|
47
|
+
#else
|
|
48
|
+
;
|
|
39
49
|
#endif
|
|
@@ -40,8 +40,13 @@ enum SelvaSortOrder {
|
|
|
40
40
|
SELVA_SORT_ORDER_TEXT_DESC,
|
|
41
41
|
};
|
|
42
42
|
|
|
43
|
+
struct SelvaSortItem;
|
|
43
44
|
struct SelvaSortCtx;
|
|
44
45
|
|
|
46
|
+
struct SelvaSortIterator {
|
|
47
|
+
struct SelvaSortItem *next;
|
|
48
|
+
};
|
|
49
|
+
|
|
45
50
|
SELVA_EXPORT
|
|
46
51
|
struct SelvaSortCtx *selva_sort_init(enum SelvaSortOrder order);
|
|
47
52
|
|
|
@@ -91,43 +96,45 @@ SELVA_EXPORT
|
|
|
91
96
|
void selva_sort_remove_text(struct SelvaSortCtx *ctx, const char *str, size_t len, const void *p);
|
|
92
97
|
|
|
93
98
|
SELVA_EXPORT
|
|
94
|
-
void selva_sort_foreach_begin(struct SelvaSortCtx *ctx);
|
|
99
|
+
void selva_sort_foreach_begin(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it);
|
|
95
100
|
|
|
96
101
|
SELVA_EXPORT
|
|
97
|
-
void selva_sort_foreach_begin_reverse(struct SelvaSortCtx *ctx);
|
|
102
|
+
void selva_sort_foreach_begin_reverse(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it);
|
|
98
103
|
|
|
99
104
|
SELVA_EXPORT
|
|
100
|
-
void *selva_sort_foreach(struct SelvaSortCtx *ctx);
|
|
105
|
+
void *selva_sort_foreach(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it);
|
|
101
106
|
|
|
102
107
|
SELVA_EXPORT
|
|
103
|
-
void *selva_sort_foreach_reverse(struct SelvaSortCtx *ctx);
|
|
108
|
+
void *selva_sort_foreach_reverse(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it);
|
|
104
109
|
|
|
105
110
|
SELVA_EXPORT
|
|
106
|
-
void *selva_sort_foreach_i64(struct SelvaSortCtx *ctx, int64_t *v);
|
|
111
|
+
void *selva_sort_foreach_i64(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, int64_t *v);
|
|
107
112
|
|
|
108
113
|
SELVA_EXPORT
|
|
109
|
-
void *selva_sort_foreach_i64_reverse(struct SelvaSortCtx *ctx, int64_t *v);
|
|
114
|
+
void *selva_sort_foreach_i64_reverse(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, int64_t *v);
|
|
110
115
|
|
|
111
116
|
SELVA_EXPORT
|
|
112
|
-
void *selva_sort_foreach_float(struct SelvaSortCtx *ctx, float *f);
|
|
117
|
+
void *selva_sort_foreach_float(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, float *f);
|
|
113
118
|
|
|
114
119
|
SELVA_EXPORT
|
|
115
|
-
void *selva_sort_foreach_float_reverse(struct SelvaSortCtx *ctx, float *f);
|
|
120
|
+
void *selva_sort_foreach_float_reverse(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, float *f);
|
|
116
121
|
|
|
117
122
|
SELVA_EXPORT
|
|
118
|
-
void *selva_sort_foreach_double(struct SelvaSortCtx *ctx, double *d);
|
|
123
|
+
void *selva_sort_foreach_double(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, double *d);
|
|
119
124
|
|
|
120
125
|
SELVA_EXPORT
|
|
121
|
-
void *selva_sort_foreach_double_reverse(struct SelvaSortCtx *ctx, double *d);
|
|
126
|
+
void *selva_sort_foreach_double_reverse(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, double *d);
|
|
122
127
|
|
|
123
128
|
SELVA_EXPORT
|
|
124
|
-
void *selva_sort_foreach_buffer(struct SelvaSortCtx *ctx, void **buf, size_t *len);
|
|
129
|
+
void *selva_sort_foreach_buffer(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, void **buf, size_t *len);
|
|
125
130
|
|
|
126
131
|
SELVA_EXPORT
|
|
127
|
-
void *selva_sort_foreach_buffer_reverse(struct SelvaSortCtx *ctx, void **buf, size_t *len);
|
|
132
|
+
void *selva_sort_foreach_buffer_reverse(struct SelvaSortCtx *ctx, struct SelvaSortIterator *it, void **buf, size_t *len);
|
|
128
133
|
|
|
129
|
-
|
|
130
|
-
|
|
134
|
+
static inline bool selva_sort_foreach_done(struct SelvaSortIterator *it)
|
|
135
|
+
{
|
|
136
|
+
return !it->next;
|
|
137
|
+
}
|
|
131
138
|
|
|
132
139
|
SELVA_EXPORT
|
|
133
140
|
int selva_sort_defrag(struct SelvaSortCtx *ctx);
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
Binary file
|
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
*/
|
|
5
5
|
#pragma once
|
|
6
6
|
|
|
7
|
+
#include <assert.h>
|
|
7
8
|
#include <sys/types.h>
|
|
8
9
|
#include "selva/_export.h"
|
|
9
10
|
#include "selva/types.h"
|
|
@@ -179,13 +180,16 @@ inline enum SelvaFieldType selva_get_fs_type(const struct SelvaFieldSchema *fs)
|
|
|
179
180
|
* struct SelvaFieldSchema *dst_fs = selva_get_fs_by_node(db, dst, efc->inverse_field);
|
|
180
181
|
*/
|
|
181
182
|
SELVA_EXPORT
|
|
183
|
+
__attribute__((returns_nonnull))
|
|
182
184
|
__attribute__((nonnull))
|
|
183
185
|
inline const struct EdgeFieldConstraint *selva_get_edge_field_constraint(const struct SelvaFieldSchema *fs)
|
|
184
186
|
#ifndef __zig
|
|
185
187
|
{
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
188
|
+
assert(fs->type == SELVA_FIELD_TYPE_REFERENCE ||
|
|
189
|
+
fs->type == SELVA_FIELD_TYPE_REFERENCES ||
|
|
190
|
+
fs->type == SELVA_FIELD_TYPE_WEAK_REFERENCE ||
|
|
191
|
+
fs->type == SELVA_FIELD_TYPE_WEAK_REFERENCES);
|
|
192
|
+
return &fs->edge_constraint;
|
|
189
193
|
}
|
|
190
194
|
#else
|
|
191
195
|
;
|
|
@@ -349,7 +353,7 @@ SELVA_EXPORT
|
|
|
349
353
|
selva_hash128_t selva_node_hash(struct SelvaDb *db, struct SelvaTypeEntry *type, struct SelvaNode *node);
|
|
350
354
|
|
|
351
355
|
SELVA_EXPORT
|
|
352
|
-
|
|
356
|
+
int selva_node_hash_range(struct SelvaDb *db, struct SelvaTypeEntry *type, node_id_t start, node_id_t end, selva_hash128_t *hash_out) __attribute__((nonnull, warn_unused_result));
|
|
353
357
|
|
|
354
358
|
/**
|
|
355
359
|
* @}
|
|
@@ -1,25 +1,33 @@
|
|
|
1
1
|
/*
|
|
2
|
-
* Copyright (c) 2024 SAULX
|
|
2
|
+
* Copyright (c) 2024-2025 SAULX
|
|
3
3
|
* SPDX-License-Identifier: MIT
|
|
4
4
|
*/
|
|
5
5
|
#pragma once
|
|
6
6
|
#include "xxhash.h"
|
|
7
|
+
#include "jemalloc_selva.h"
|
|
7
8
|
#include "selva/types.h"
|
|
8
9
|
|
|
9
10
|
typedef struct XXH3_state_s selva_hash_state_t;
|
|
10
11
|
|
|
11
|
-
#define selva_hash_create_state XXH3_createState
|
|
12
12
|
#define selva_hash_reset XXH3_128bits_reset
|
|
13
|
-
#define selva_hash_free_state XXH3_freeState
|
|
14
13
|
#define selva_hash_update XXH3_128bits_update
|
|
15
14
|
|
|
16
15
|
SELVA_EXPORT
|
|
17
|
-
|
|
16
|
+
selva_hash_state_t *selva_hash_create_state(void);
|
|
18
17
|
|
|
19
|
-
|
|
20
|
-
|
|
18
|
+
SELVA_EXPORT
|
|
19
|
+
inline void selva_hash_free_state(selva_hash_state_t *state)
|
|
20
|
+
#ifndef __zig
|
|
21
|
+
{
|
|
22
|
+
selva_free(state);
|
|
23
|
+
}
|
|
21
24
|
#else
|
|
22
|
-
|
|
25
|
+
;
|
|
26
|
+
#endif
|
|
27
|
+
|
|
28
|
+
SELVA_EXPORT
|
|
29
|
+
inline selva_hash128_t selva_hash_digest(selva_hash_state_t *hash_state)
|
|
30
|
+
#ifndef __zig
|
|
23
31
|
{
|
|
24
32
|
XXH128_hash_t res;
|
|
25
33
|
|
|
@@ -36,4 +44,6 @@ retry:
|
|
|
36
44
|
|
|
37
45
|
return (selva_hash128_t)res.low64 | (selva_hash128_t)res.high64 << 64;
|
|
38
46
|
}
|
|
47
|
+
#else
|
|
48
|
+
;
|
|
39
49
|
#endif
|