@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.
Files changed (105) hide show
  1. package/README.md +1 -399
  2. package/dist/lib/darwin_aarch64/include/selva/db.h +8 -4
  3. package/dist/lib/darwin_aarch64/include/selva/selva_hash128.h +17 -7
  4. package/dist/lib/darwin_aarch64/include/selva/sort.h +21 -14
  5. package/dist/lib/darwin_aarch64/libdeflate.dylib +0 -0
  6. package/dist/lib/darwin_aarch64/libjemalloc_selva.2.dylib +0 -0
  7. package/dist/lib/darwin_aarch64/libnode-v20.node +0 -0
  8. package/dist/lib/darwin_aarch64/libnode-v21.node +0 -0
  9. package/dist/lib/darwin_aarch64/libnode-v22.node +0 -0
  10. package/dist/lib/darwin_aarch64/libnode-v23.node +0 -0
  11. package/dist/lib/darwin_aarch64/libselva.dylib +0 -0
  12. package/dist/lib/darwin_aarch64/libxxhash.dylib +0 -0
  13. package/dist/lib/linux_aarch64/include/selva/db.h +8 -4
  14. package/dist/lib/linux_aarch64/include/selva/selva_hash128.h +17 -7
  15. package/dist/lib/linux_aarch64/include/selva/sort.h +21 -14
  16. package/dist/lib/linux_aarch64/libdeflate.so +0 -0
  17. package/dist/lib/linux_aarch64/libjemalloc_selva.so.2 +0 -0
  18. package/dist/lib/linux_aarch64/libnode-v20.node +0 -0
  19. package/dist/lib/linux_aarch64/libnode-v21.node +0 -0
  20. package/dist/lib/linux_aarch64/libnode-v22.node +0 -0
  21. package/dist/lib/linux_aarch64/libnode-v23.node +0 -0
  22. package/dist/lib/linux_aarch64/libselva.so +0 -0
  23. package/dist/lib/linux_x86_64/include/selva/db.h +8 -4
  24. package/dist/lib/linux_x86_64/include/selva/selva_hash128.h +17 -7
  25. package/dist/lib/linux_x86_64/include/selva/sort.h +21 -14
  26. package/dist/lib/linux_x86_64/libjemalloc_selva.so.2 +0 -0
  27. package/dist/lib/linux_x86_64/libnode-v20.node +0 -0
  28. package/dist/lib/linux_x86_64/libnode-v21.node +0 -0
  29. package/dist/lib/linux_x86_64/libnode-v22.node +0 -0
  30. package/dist/lib/linux_x86_64/libnode-v23.node +0 -0
  31. package/dist/lib/linux_x86_64/libselva.so +0 -0
  32. package/dist/src/client/flushModify.d.ts +1 -1
  33. package/dist/src/client/flushModify.js +12 -17
  34. package/dist/src/client/index.d.ts +6 -4
  35. package/dist/src/client/index.js +19 -2
  36. package/dist/src/client/modify/ModifyRes.d.ts +1 -1
  37. package/dist/src/client/modify/ModifyRes.js +14 -18
  38. package/dist/src/client/modify/fixed.js +43 -8
  39. package/dist/src/client/modify/modify.js +0 -1
  40. package/dist/src/client/modify/references/{appendRefs.d.ts → appendEdgeRefs.d.ts} +1 -1
  41. package/dist/src/client/modify/references/{appendRefs.js → appendEdgeRefs.js} +5 -2
  42. package/dist/src/client/modify/references/edge.js +182 -175
  43. package/dist/src/client/modify/references/reference.js +4 -8
  44. package/dist/src/client/modify/references/references.js +18 -14
  45. package/dist/src/client/modify/string.js +0 -3
  46. package/dist/src/client/modify/text.js +11 -3
  47. package/dist/src/client/modify/types.d.ts +11 -0
  48. package/dist/src/client/modify/types.js +10 -0
  49. package/dist/src/client/modify/update.js +4 -1
  50. package/dist/src/client/modify/vector.js +13 -4
  51. package/dist/src/client/query/BasedDbQuery.d.ts +1 -1
  52. package/dist/src/client/query/BasedDbQuery.js +2 -2
  53. package/dist/src/client/query/BasedIterable.d.ts +1 -1
  54. package/dist/src/client/query/BasedIterable.js +7 -2
  55. package/dist/src/client/query/filter/createFixedFilterBuffer.d.ts +2 -1
  56. package/dist/src/client/query/filter/createFixedFilterBuffer.js +11 -28
  57. package/dist/src/client/query/filter/createReferenceFilter.d.ts +2 -1
  58. package/dist/src/client/query/filter/createReferenceFilter.js +10 -9
  59. package/dist/src/client/query/filter/createVariableFilterBuffer.d.ts +2 -1
  60. package/dist/src/client/query/filter/createVariableFilterBuffer.js +8 -10
  61. package/dist/src/client/query/filter/parseFilterValue.js +1 -1
  62. package/dist/src/client/query/filter/primitiveFilter.js +9 -9
  63. package/dist/src/client/query/filter/toBuffer.js +0 -15
  64. package/dist/src/client/query/filter/types.d.ts +1 -0
  65. package/dist/src/client/query/filter/types.js +1 -0
  66. package/dist/src/client/query/include/walk.js +0 -1
  67. package/dist/src/client/query/read/read.js +4 -4
  68. package/dist/src/client/query/search/index.js +11 -15
  69. package/dist/src/client/query/subscription/markers.js +1 -2
  70. package/dist/src/client/query/subscription/run.js +0 -2
  71. package/dist/src/client/query/thresholds.d.ts +0 -2
  72. package/dist/src/client/query/thresholds.js +0 -2
  73. package/dist/src/client/query/toBuffer.js +16 -42
  74. package/dist/src/client/query/types.d.ts +3 -2
  75. package/dist/src/client/query/validation.d.ts +1 -3
  76. package/dist/src/client/query/validation.js +6 -18
  77. package/dist/src/client/string.d.ts +2 -0
  78. package/dist/src/client/string.js +9 -13
  79. package/dist/src/index.d.ts +1 -1
  80. package/dist/src/index.js +7 -15
  81. package/dist/src/native.d.ts +1 -1
  82. package/dist/src/native.js +3 -3
  83. package/dist/src/server/csmt/draw-dot.js +2 -2
  84. package/dist/src/server/csmt/tree.js +57 -6
  85. package/dist/src/server/csmt/types.d.ts +5 -0
  86. package/dist/src/server/index.d.ts +4 -3
  87. package/dist/src/server/index.js +44 -44
  88. package/dist/src/server/migrate/index.js +47 -29
  89. package/dist/src/server/migrate/worker.js +2 -2
  90. package/dist/src/server/save.js +40 -28
  91. package/dist/src/server/start.js +7 -19
  92. package/dist/src/server/tree.d.ts +2 -0
  93. package/dist/src/server/tree.js +34 -2
  94. package/dist/src/server/worker.js +3 -3
  95. package/dist/src/utils.d.ts +3 -1
  96. package/dist/src/utils.js +43 -19
  97. package/package.json +9 -3
  98. package/dist/lib/darwin_aarch64/include/selva/base64.h +0 -59
  99. package/dist/lib/darwin_aarch64/include/selva/base64url.h +0 -59
  100. package/dist/lib/linux_aarch64/include/selva/base64.h +0 -59
  101. package/dist/lib/linux_aarch64/include/selva/base64url.h +0 -59
  102. package/dist/lib/linux_x86_64/include/selva/base64.h +0 -59
  103. package/dist/lib/linux_x86_64/include/selva/base64url.h +0 -59
  104. package/dist/src/client/timestamp.d.ts +0 -1
  105. 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.13.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
- return (fs->type == SELVA_FIELD_TYPE_REFERENCE || fs->type == SELVA_FIELD_TYPE_REFERENCES)
187
- ? &fs->edge_constraint
188
- : nullptr;
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
- selva_hash128_t selva_node_hash_range(struct SelvaDb *db, struct SelvaTypeEntry *type, node_id_t start, node_id_t end) __attribute__((nonnull));
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
- selva_hash128_t selva_hash_digest_zig(selva_hash_state_t *hash_state);
16
+ selva_hash_state_t *selva_hash_create_state(void);
18
17
 
19
- #ifdef __zig
20
- #define selva_hash_digest selva_hash_digest_zig
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
- static inline selva_hash128_t selva_hash_digest(selva_hash_state_t *hash_state)
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
- SELVA_EXPORT
130
- bool selva_sort_foreach_done(const struct SelvaSortCtx *ctx);
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);
@@ -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
- return (fs->type == SELVA_FIELD_TYPE_REFERENCE || fs->type == SELVA_FIELD_TYPE_REFERENCES)
187
- ? &fs->edge_constraint
188
- : nullptr;
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
- selva_hash128_t selva_node_hash_range(struct SelvaDb *db, struct SelvaTypeEntry *type, node_id_t start, node_id_t end) __attribute__((nonnull));
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
- selva_hash128_t selva_hash_digest_zig(selva_hash_state_t *hash_state);
16
+ selva_hash_state_t *selva_hash_create_state(void);
18
17
 
19
- #ifdef __zig
20
- #define selva_hash_digest selva_hash_digest_zig
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
- static inline selva_hash128_t selva_hash_digest(selva_hash_state_t *hash_state)
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