-
Notifications
You must be signed in to change notification settings - Fork 36
/
objectbox.h
2745 lines (2171 loc) · 158 KB
/
objectbox.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
/*
* Copyright 2018-2023 ObjectBox Ltd. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* @defgroup c ObjectBox C API
* @{
*/
// Single header file for the ObjectBox C API
//
// Naming conventions
// ------------------
// * methods: obx_thing_action()
// * structs: OBX_thing {}
// * error codes: OBX_ERROR_REASON
//
#ifndef OBJECTBOX_H
#define OBJECTBOX_H
#include <stdbool.h>
#include <stdint.h>
#include <stdio.h>
#ifdef __cplusplus
extern "C" {
#endif
// NOLINTBEGIN(modernize-use-using)
#ifndef OBX_C_API
#define OBX_C_API
#endif
//----------------------------------------------
// ObjectBox version codes
//----------------------------------------------
/// When using ObjectBox as a dynamic library, you should verify that a compatible version was linked using
/// obx_version() or obx_version_is_at_least().
#define OBX_VERSION_MAJOR 4
#define OBX_VERSION_MINOR 0
#define OBX_VERSION_PATCH 2 // values >= 100 are reserved for dev releases leading to the next minor/major increase
//----------------------------------------------
// Common types
//----------------------------------------------
/// Schema entity & property identifiers
typedef uint32_t obx_schema_id;
/// Universal identifier used in schema for entities & properties
typedef uint64_t obx_uid;
/// ID of a single Object stored in the database
typedef uint64_t obx_id;
/// Object ID with its associated query score, which is used for special query results.
typedef struct OBX_id_score {
obx_id id;
/// The query score indicates some quality measurement.
/// E.g. for vector nearest neighbor searches, the score is the distance to the given vector.
double score;
} OBX_id_score;
/// Error/success code returned by an obx_* function; see defines OBX_SUCCESS, OBX_NOT_FOUND, and OBX_ERROR_*
typedef int obx_err;
/// The callback for reading data (i.e. object bytes) one-by-one.
/// @param data is the read data buffer
/// @param size specifies the length of the read data
/// @param user_data is a pass-through argument passed to the called API
/// @return The visitor returns true to keep going or false to cancel.
typedef bool obx_data_visitor(const void* data, size_t size, void* user_data);
struct OBX_bytes_score; // Forward declaration for the obx_data_score_visitor typedef
/// The callback for reading data (i.e. object bytes) with a search score one-by-one.
/// @param data contains the current data with score element
/// @param user_data is a pass-through argument passed to the called API
/// @return The visitor returns true to keep going or false to cancel.
typedef bool obx_data_score_visitor(const struct OBX_bytes_score* data, void* user_data);
//----------------------------------------------
// Runtime library information
//
// Functions in this group provide information about the loaded ObjectBox library.
// Their return values are invariable during runtime - they depend solely on the loaded library and its build settings.
//----------------------------------------------
/// Return the (runtime) version of the library as ints. Pointers may be null
OBX_C_API void obx_version(int* major, int* minor, int* patch);
/// Check if the (runtime) version of the library is equal to or higher than the given version ints.
OBX_C_API bool obx_version_is_at_least(int major, int minor, int patch);
/// Return the (runtime) version of the library to be printed.
/// The current format is "major.minor.patch" (e.g. "1.0.0") but may change in any future release.
/// Thus, only use for information purposes.
/// @see obx_version() and obx_version_is_at_least() for integer based versions
OBX_C_API const char* obx_version_string(void);
/// Return the version of the ObjectBox core to be printed (currently also contains a version date and features).
/// The format may change in any future release; only use for information purposes.
OBX_C_API const char* obx_version_core_string(void);
typedef enum {
/// Functions that are returning multiple results (e.g. multiple objects) can be only used if this is available.
/// This is only available for 64-bit OSes and is the opposite of "chunked mode", which forces to consume results
/// in chunks (e.g. one by one).
/// Since chunked mode consumes a bit less RAM, ResultArray style functions are typically only preferable if
/// there's an additional overhead per call, e.g. caused by a higher level language abstraction like CGo.
OBXFeature_ResultArray = 1,
/// TimeSeries support (date/date-nano companion ID and other time-series functionality).
OBXFeature_TimeSeries = 2,
/// Sync client availability. Visit https://objectbox.io/sync for more details.
OBXFeature_Sync = 3,
/// Check whether debug log can be enabled during runtime.
OBXFeature_DebugLog = 4,
/// Admin UI including a database browser, user management, and more.
/// Depends on HttpServer (if Admin is available HttpServer is too).
OBXFeature_Admin = 5,
/// Tree with special GraphQL support
OBXFeature_Tree = 6,
/// Sync server availability. Visit https://objectbox.io/sync for more details.
OBXFeature_SyncServer = 7,
/// Implicitly added by Sync or SyncServer; disable via NoWebSockets
OBXFeature_WebSockets = 8,
/// Sync Server has cluster functionality.
/// Implicitly added by SyncServer; disable via NoCluster
OBXFeature_Cluster = 9,
/// Embedded HTTP server.
OBXFeature_HttpServer = 10,
/// Embedded GraphQL server (via HTTP).
/// Depends on HttpServer (if GraphQL is available HttpServer is too).
OBXFeature_GraphQL = 11,
/// Database Backup functionality; typically only enabled in Sync Server builds.
OBXFeature_Backup = 12,
/// The default database "provider"; writes data persistently to disk (ACID).
OBXFeature_Lmdb = 13,
/// Vector search functionality; enables indexing for nearest neighbor search.
OBXFeature_VectorSearch = 14,
/// WAL (write-ahead logging).
OBXFeature_Wal = 15,
/// Sync connector to integrate MongoDB with SyncServer.
OBXFeature_SyncMongoDb = 16,
} OBXFeature;
/// Checks whether the given feature is available in the currently loaded library.
OBX_C_API bool obx_has_feature(OBXFeature feature);
//----------------------------------------------
// Utilities
//----------------------------------------------
/// Log level as passed to obx_log_callback.
typedef enum {
/// Log level for verbose messages (not emitted at the moment)
OBXLogLevel_Verbose = 10,
/// Log level for debug messages (may be limited to special debug builds)
OBXLogLevel_Debug = 20,
/// Log level for info messages
OBXLogLevel_Info = 30,
/// Log level for warning messages
OBXLogLevel_Warn = 40,
/// Log level for error messages
OBXLogLevel_Error = 50,
} OBXLogLevel;
/// Callback for logging, which can be provided to store creation via options.
typedef void obx_log_callback(OBXLogLevel log_level, const char* message, size_t message_size, void* user_data);
/// To be used for putting objects with prepared ID slots, e.g. obx_cursor_put_object().
#define OBX_ID_NEW 0xFFFFFFFFFFFFFFFF
/// Delete the store files from the given directory
OBX_C_API obx_err obx_remove_db_files(char const* directory);
/// @returns the file size of the main database file, or 0 if the file does not exist or some error occurred.
OBX_C_API size_t obx_db_file_size(char const* directory);
/// Enable (or disable) debug logging for ObjectBox internals.
/// This requires a version of the library with the DebugLog feature.
/// You can check if the feature is available with obx_has_feature(OBXFeature_DebugLog).
OBX_C_API obx_err obx_debug_log(bool enabled);
/// Checks if debug logs are enabled for ObjectBox internals. This depends on the availability of the DebugLog feature.
/// If the feature is available, it returns the current state, which is adjustable via obx_debug_log().
/// Otherwise, it always returns false for standard release builds (or true if you are having a special debug version).
OBX_C_API bool obx_debug_log_enabled();
/// Gets the number, as used by ObjectBox, of the current thread.
/// This e.g. allows to "associate" the thread with ObjectBox logs (each log entry contains the thread number).
OBX_C_API int obx_thread_number();
//----------------------------------------------
// Return and error codes
//----------------------------------------------
/// Value returned when no error occurred (0)
#define OBX_SUCCESS 0
/// Returned by, e.g., get operations if nothing was found for a specific ID.
/// This is NOT an error condition, and thus no "last error" info (code/text) is set.
#define OBX_NOT_FOUND 404
/// Indicates that a function had "no success", which is typically a likely outcome and not a "hard error".
/// This is NOT an error condition, and thus no "last error" info is set.
#define OBX_NO_SUCCESS 1001
/// Indicates that a function reached a time out, which is typically a likely outcome and not a "hard error".
/// This is NOT an error condition, and thus no "last error" info is set.
#define OBX_TIMEOUT 1002
// --- General errors --------------------------------------------------------
/// A request does not make sense in the current state. For example, doing actions on a closed object.
#define OBX_ERROR_ILLEGAL_STATE 10001
/// The passed arguments were illegal; e.g. passed null to a non-null argument.
#define OBX_ERROR_ILLEGAL_ARGUMENT 10002
/// A resource could not be allocated. This usually indicates a severe system status, e.g running out of memory.
#define OBX_ERROR_ALLOCATION 10003
/// Thrown when a numeric value did overflow/underflow, e.g. an addition would result in a value of the type's limits.
#define OBX_ERROR_NUMERIC_OVERFLOW 10004
/// Tried to use a special feature that is not part of this lib edition.
/// The ObjectBox library comes in different flavors, and may not contain all features.
#define OBX_ERROR_FEATURE_NOT_AVAILABLE 10005
/// A required resource (e.g. a store or some internal queue) is shutting down, and thus, the current request could not
/// be fulfilled. Typically occurs in asynchronous operations.
#define OBX_ERROR_SHUTTING_DOWN 10006
/// An I/O operation failed, e.g. a file was not found, could not be written or read.
#define OBX_ERROR_IO 10007
/// A given backup file has invalid content and thus cannot be restored.
#define OBX_ERROR_BACKUP_FILE_INVALID 10008
/// An error occurred but error information could not be extracted.
/// This falls in the "should not happen" category and should be very rare;
/// please report if you ever encounter this in a reproducible fashion.
#define OBX_ERROR_NO_ERROR_INFO 10097
/// A general error occurred that did not fit in a more specific category.
#define OBX_ERROR_GENERAL 10098
/// An error of unknown type occurred.
/// This falls in the "should not happen" category and should be very rare;
/// please report if you ever encounter this in a reproducible fashion.
#define OBX_ERROR_UNKNOWN 10099
// --- Storage errors (often have a secondary error code) --------------------
/// The database has reached its given storage limit.
/// Note that is limit is user defined and thus you can set it as an option when opening a database via
/// obx_opt_max_db_size_in_kb(). Further note that this limit is in place to protect the system from unreasonable
/// storage consumption due to unexpected usage and user errors (e.g. inserting data in an infinite loop).
#define OBX_ERROR_DB_FULL 10101
/// Thrown when the maximum of readers (read transactions) was exceeded.
/// Verify that you run a reasonable amount of threads only.
/// If you actually intend to work with a very high number of threads (>100), consider increasing the number of maximum
/// readers via obx_opt_max_readers().
#define OBX_ERROR_MAX_READERS_EXCEEDED 10102
/// Can not continue, ObjectBox store must be closed.
/// This falls in the "should not happen" category and should be very rare;
/// please report if you ever encounter this in a reproducible fashion.
#define OBX_ERROR_STORE_MUST_SHUTDOWN 10103
/// Occurs when a transaction is about to commit but it would exceed the user-defined data size limit.
/// See obx_opt_max_data_size_in_kb() for details.
#define OBX_ERROR_MAX_DATA_SIZE_EXCEEDED 10104
/// A general database related error occurred that did not fit in a more specific category.
/// No secondary error code is available.
#define OBX_ERROR_DB_GENERAL 10198
/// A storage error occurred that did not fit in a more specific (storage) category.
/// A secondary error code is available via obx_last_error_secondary().
#define OBX_ERROR_STORAGE_GENERAL 10199
// --- Data errors -----------------------------------------------------------
/// A unique constraint of was violated when trying to put.
#define OBX_ERROR_UNIQUE_VIOLATED 10201
/// A result was supposed to be unique, but was not. E.g. a query results in multiple results where one one is expected.
#define OBX_ERROR_NON_UNIQUE_RESULT 10202
/// A Property did not match an expected type; e.g. when defining a string-based query condition for an integer type.
#define OBX_ERROR_PROPERTY_TYPE_MISMATCH 10203
/// A given ID already existed, e.g. when trying to insert with a pre-existing ID.
/// Should happen only with user assigned IDs.
#define OBX_ERROR_ID_ALREADY_EXISTS 10210
/// A given ID was not found (does not exist), e.g. when trying to update an object that does not exist.
/// Typically happens when an object was removed before while trying to update it.
#define OBX_ERROR_ID_NOT_FOUND 10211
/// A Time Series operation failed, e.g. a time value was out of range
#define OBX_ERROR_TIME_SERIES 10212
/// A constraint violation occurred that did not fit in a more specific (constraint violation) category.
#define OBX_ERROR_CONSTRAINT_VIOLATED 10299
// --- STD errors --------------------------------------------------------
// These are low-level errors falling in the "should not happen" category and should be very rare;
// please report if you ever encounter one of these in a reproducible fashion.
#define OBX_ERROR_STD_ILLEGAL_ARGUMENT 10301
#define OBX_ERROR_STD_OUT_OF_RANGE 10302
#define OBX_ERROR_STD_LENGTH 10303
#define OBX_ERROR_STD_BAD_ALLOC 10304
#define OBX_ERROR_STD_RANGE 10305
#define OBX_ERROR_STD_OVERFLOW 10306
#define OBX_ERROR_STD_OTHER 10399
// --- Schema and file errors ------------------------------------------------
/// Data schema (aka data model) related error;
/// typically when a provided schema is inconsistent/incompatible to an existing one (on disk).
#define OBX_ERROR_SCHEMA 10501
/// DB file has errors, e.g. illegal values or structural inconsistencies were detected.
#define OBX_ERROR_FILE_CORRUPT 10502
/// DB file has errors related to pages, e.g. bad page refs outside of the file.
#define OBX_ERROR_FILE_PAGES_CORRUPT 10503
/// A requested schema object (e.g. an entity or a property) was not found in the schema
#define OBX_ERROR_SCHEMA_OBJECT_NOT_FOUND 10504
// --- Tree errors: 106xx ----------------------------------------------------
/// Could not setup tree because the data model (schema) of the database does not contain all required tree
/// types/properties.
#define OBX_ERROR_TREE_MODEL_INVALID 10601
/// Accessing a tree value failed because the stored value was put using a different value type.
#define OBX_ERROR_TREE_VALUE_TYPE_MISMATCH 10602
/// At a given path, a leaf was expected but a branch node was found; e.g. values can only be stored in leaves.
#define OBX_ERROR_TREE_PATH_NON_UNIQUE 10603
/// When trying to put or get using an illegal tree path. Examples for illegal paths with delimiter '/':
/// "", "/", "a", "/a", "a/", "a//b", " ", " / ", "a/ /b", " a/b", "a/b ".
#define OBX_ERROR_TREE_PATH_ILLEGAL 10604
/// An error related to tree functionality was detected;
/// please check the error message for details (see obx_last_error_message()).
#define OBX_ERROR_TREE_OTHER 10699
//----------------------------------------------
// Error info; obx_last_error_*
//----------------------------------------------
/// Return the error status on the current thread and clear the error state.
/// The buffer returned in out_message is valid only until the next call into ObjectBox.
/// @param out_error receives the error code; optional: may be NULL
/// @param out_message receives the pointer to the error messages; optional: may be NULL
/// @returns true if an error was pending
OBX_C_API bool obx_last_error_pop(obx_err* out_error, const char** out_message);
/// The last error raised by an ObjectBox API call on the current thread, or OBX_SUCCESS if no error occurred yet.
/// Note that API calls do not clear this error code (also true for this method).
/// Thus, if you receive an error from this, it's usually a good idea to call obx_last_error_clear() to clear the error
/// state (or use obx_last_error_pop()) for future API calls.
OBX_C_API obx_err obx_last_error_code(void);
/// The error message string attached to the error returned by obx_last_error_code().
/// Like obx_last_error_code(), this is bound to the current thread, and this call does not clear the error state.
/// The buffer returned is valid only until the next call into ObjectBox.
OBX_C_API const char* obx_last_error_message(void);
/// The underlying error for the error returned by obx_last_error_code(). Where obx_last_error_code() may be a generic
/// error like OBX_ERROR_STORAGE_GENERAL, this will give a further underlying and possibly platform-specific error code.
OBX_C_API obx_err obx_last_error_secondary(void);
/// Clear the error state on the current thread; e.g. obx_last_error_code() will now return OBX_SUCCESS.
/// Note that clearing the error state does not happen automatically;
/// API calls set the error state when they produce an error, but do not clear it on success.
/// See also: obx_last_error_pop() to retrieve the error state and clear it.
OBX_C_API void obx_last_error_clear(void);
/// Set the last error code and test - reserved for internal use from generated code.
OBX_C_API bool obx_last_error_set(obx_err code, obx_err secondary, const char* message);
//----------------------------------------------
// Model
//----------------------------------------------
typedef enum {
OBXPropertyType_Unknown = 0, ///< Not a actual type; represents an uninitialized or invalid type
OBXPropertyType_Bool = 1, ///< A boolean (flag)
OBXPropertyType_Byte = 2, ///< 8-bit integer
OBXPropertyType_Short = 3, ///< 16-bit integer
OBXPropertyType_Char = 4, ///< 16-bit character
OBXPropertyType_Int = 5, ///< 32-bit integer
OBXPropertyType_Long = 6, ///< 64-bit integer
OBXPropertyType_Float = 7, ///< 32-bit floating point number
OBXPropertyType_Double = 8, ///< 64-bit floating point number
OBXPropertyType_String = 9, ///< UTF-8 encoded string (variable length)
OBXPropertyType_Date = 10, ///< 64-bit (integer) timestamp; milliseconds since 1970-01-01 (unix epoch)
OBXPropertyType_Relation = 11, ///< Relation to another entity
OBXPropertyType_DateNano = 12, ///< High precision 64-bit timestamp; nanoseconds since 1970-01-01 (unix epoch)
OBXPropertyType_Flex = 13, ///< Flexible" type, which may contain scalars (integers, floating points), strings or
///< containers (lists and maps). Note: a flex map must use string keys.
OBXPropertyType_BoolVector = 22, ///< Variable sized vector of Bool values (note: each value is one byte)
OBXPropertyType_ByteVector = 23, ///< Variable sized vector of Byte values (8-bit integers)
OBXPropertyType_ShortVector = 24, ///< Variable sized vector of Short values (16-bit integers)
OBXPropertyType_CharVector = 25, ///< Variable sized vector of Char values (16-bit characters)
OBXPropertyType_IntVector = 26, ///< Variable sized vector of Int values (32-bit integers)
OBXPropertyType_LongVector = 27, ///< Variable sized vector of Long values (64-bit integers)
OBXPropertyType_FloatVector = 28, ///< Variable sized vector of Float values (32-bit floating point numbers)
OBXPropertyType_DoubleVector = 29, ///< Variable sized vector of Double values (64-bit floating point numbers)
OBXPropertyType_StringVector = 30, ///< Variable sized vector of String values (UTF-8 encoded strings).
OBXPropertyType_DateVector = 31, ///< Variable sized vector of Date values (64-bit timestamp).
OBXPropertyType_DateNanoVector = 32, ///< Variable sized vector of Date values (high precision 64-bit timestamp).
} OBXPropertyType;
/// The vector distance algorithm used by an HNSW index (vector search).
typedef enum {
/// Not a real type, just best practice (e.g. forward compatibility)
OBXVectorDistanceType_Unknown = 0,
/// The default; typically "Euclidean squared" internally.
OBXVectorDistanceType_Euclidean = 1,
/// Cosine similarity compares two vectors irrespective of their magnitude (compares the angle of two vectors).
/// Often used for document or semantic similarity.
/// Value range: 0.0 - 2.0 (0.0: same direction, 1.0: orthogonal, 2.0: opposite direction)
OBXVectorDistanceType_Cosine = 2,
/// For normalized vectors (vector length == 1.0), the dot product is equivalent to the cosine similarity.
/// Because of this, the dot product is often preferred as it performs better.
/// Value range (normalized vectors): 0.0 - 2.0 (0.0: same direction, 1.0: orthogonal, 2.0: opposite direction)
OBXVectorDistanceType_DotProduct = 3,
OBXVectorDistanceType_Manhattan = 4,
OBXVectorDistanceType_Hamming = 5,
/// A custom dot product similarity measure that does not require the vectors to be normalized.
/// Note: this is no replacement for cosine similarity (like DotProduct for normalized vectors is).
/// The non-linear conversion provides a high precision over the entire float range (for the raw dot product).
/// The higher the dot product, the lower the distance is (the nearer the vectors are).
/// The more negative the dot product, the higher the distance is (the farther the vectors are).
/// Value range: 0.0 - 2.0 (nonlinear; 0.0: nearest, 1.0: orthogonal, 2.0: farthest)
OBXVectorDistanceType_DotProductNonNormalized = 10,
} OBXVectorDistanceType;
/// Utility function to calculate the distance of two given vectors.
/// Note: the memory of the two vectors may not overlap!
/// @param type The distance type that is to be used for the calculation.
/// @param dimension The dimension of the vectors (number of elements).
/// @returns A distance measure that is dependent on the distance type.
/// @returns NaN on error; e.g. if the distance type is unknown, or the vector search feature is unavailable.
OBX_C_API float obx_vector_distance_float32(OBXVectorDistanceType type, const float* vector1, const float* vector2,
size_t dimension);
/// Utility function to convert a vector distance (e.g. scores from query results) to a relevance score.
/// The relevance score is a value between 0.0 and 1.0, with 1.0 indicating the most relevant.
/// Note: the higher a distance (score), the lower the relevance score.
/// Note: while the distance (score) is potentially unbound (e.g. Euclidean and dot product) and dependent on the type,
/// relevance score always has fixed range (0.0 to 1.0).
/// @param type The distance type indicates how the given distance score was calculated.
/// @param distance distance score to convert (0.0 is the nearest; upper bound depends on the distance type).
/// @returns a relevance score between 0.0 and 1.0 (1.0 is the most relevant).
/// @returns NaN on error; e.g. if the distance type is unknown, or the vector search feature is unavailable.
OBX_C_API float obx_vector_distance_to_relevance(OBXVectorDistanceType type, float distance);
/// Bit-flags to influence the behavior of HNSW index (vector search).
typedef enum {
OBXHnswFlags_None = 0,
/// Enables debug logs.
OBXHnswFlags_DebugLogs = 1,
/// Enables "high volume" debug logs, e.g. individual gets/puts.
OBXHnswFlags_DebugLogsDetailed = 2,
/// Padding for SIMD is enabled by default, which uses more memory but may be faster. This flag turns it off.
OBXHnswFlags_VectorCacheSimdPaddingOff = 4,
/// If the speed of removing nodes becomes a concern in your use case, you can speed it up by setting this flag.
/// By default, repairing the graph after node removals creates more connections to improve the graph's quality.
/// The extra costs for this are relatively low (e.g. vs. regular indexing), and thus the default is recommended.
OBXHnswFlags_ReparationLimitCandidates = 8,
} OBXHnswFlags;
/// Bit-flags defining the behavior of entities.
/// Note: Numbers indicate the bit position
typedef enum {
/// Enable "data synchronization" for this entity type: objects will be synced with other stores over the network.
/// It's possible to have local-only (non-synced) types and synced types in the same store (schema/data model).
OBXEntityFlags_SYNC_ENABLED = 2,
/// Makes object IDs for a synced types (SYNC_ENABLED is set) global.
/// By default (not using this flag), the 64 bit object IDs have a local scope and are not unique globally.
/// This flag tells ObjectBox to treat object IDs globally and thus no ID mapping (local <-> global) is performed.
/// Often this is used with assignable IDs (ID_SELF_ASSIGNABLE property flag is set) and some special ID scheme.
/// Note: typically you won't do this with automatically assigned IDs, set by the local ObjectBox store.
/// Two devices would likely overwrite each other's object during sync as object IDs are prone to collide.
/// It might be OK if you can somehow ensure that only a single device will create new IDs.
OBXEntityFlags_SHARED_GLOBAL_IDS = 4,
} OBXEntityFlags;
/// Bit-flags defining the behavior of properties.
/// Note: Numbers indicate the bit position
typedef enum {
/// 64 bit long property (internally unsigned) representing the ID of the entity.
/// May be combined with: NON_PRIMITIVE_TYPE, ID_MONOTONIC_SEQUENCE, ID_SELF_ASSIGNABLE.
OBXPropertyFlags_ID = 1,
/// On languages like Java, a non-primitive type is used (aka wrapper types, allowing null)
OBXPropertyFlags_NON_PRIMITIVE_TYPE = 2,
/// Unused yet
OBXPropertyFlags_NOT_NULL = 4,
OBXPropertyFlags_INDEXED = 8,
/// Unused yet
OBXPropertyFlags_RESERVED = 16,
/// Unique index
OBXPropertyFlags_UNIQUE = 32,
/// Unused yet: Use a persisted sequence to enforce ID to rise monotonic (no ID reuse)
OBXPropertyFlags_ID_MONOTONIC_SEQUENCE = 64,
/// Allow IDs to be assigned by the developer
OBXPropertyFlags_ID_SELF_ASSIGNABLE = 128,
/// Unused yet
OBXPropertyFlags_INDEX_PARTIAL_SKIP_NULL = 256,
/// Used by References for 1) back-references and 2) to clear references to deleted objects (required for ID reuse)
OBXPropertyFlags_INDEX_PARTIAL_SKIP_ZERO = 512,
/// Virtual properties may not have a dedicated field in their entity class, e.g. target IDs of to-one relations
OBXPropertyFlags_VIRTUAL = 1024,
/// Index uses a 32 bit hash instead of the value
/// 32 bits is shorter on disk, runs well on 32 bit systems, and should be OK even with a few collisions
OBXPropertyFlags_INDEX_HASH = 2048,
/// Index uses a 64 bit hash instead of the value
/// recommended mostly for 64 bit machines with values longer >200 bytes; small values are faster with a 32 bit hash
OBXPropertyFlags_INDEX_HASH64 = 4096,
/// The actual type of the variable is unsigned (used in combination with numeric OBXPropertyType_*).
/// While our default are signed ints, queries & indexes need do know signing info.
/// Note: Don't combine with ID (IDs are always unsigned internally).
OBXPropertyFlags_UNSIGNED = 8192,
/// By defining an ID companion property, a special ID encoding scheme is activated involving this property.
///
/// For Time Series IDs, a companion property of type Date or DateNano represents the exact timestamp.
OBXPropertyFlags_ID_COMPANION = 16384,
/// Unique on-conflict strategy: the object being put replaces any existing conflicting object (deletes it).
OBXPropertyFlags_UNIQUE_ON_CONFLICT_REPLACE = 32768,
/// If a date property has this flag (max. one per entity type), the date value specifies the time by which
/// the object expires, at which point it MAY be removed (deleted), which can be triggered by an API call.
OBXPropertyFlags_EXPIRATION_TIME = 65536,
} OBXPropertyFlags;
struct OBX_model; // doxygen (only) picks up the typedef struct below
/// Model represents a database schema and must be provided when opening the store.
/// Model initialization is usually done by language bindings, which automatically build the model based on parsed
/// source code (for examples, see ObjectBox Go or Swift, which also use this C API).
///
/// For manual creation, these are the basic steps:
/// - define entity types using obx_model_entity() and obx_model_property()
/// - Pass the last ever used IDs with obx_model_last_entity_id(), obx_model_last_index_id(),
/// obx_model_last_relation_id()
typedef struct OBX_model OBX_model;
/// Create an (empty) data meta model which is to be consumed by obx_opt_model().
/// @returns NULL if the operation failed, see functions like obx_last_error_code() to get error details.
/// Note that obx_model_* functions handle OBX_model NULL pointers (will indicate an error but not crash).
OBX_C_API OBX_model* obx_model(void);
/// Only call when not calling obx_store_open() (which will free it internally)
/// @param model NULL-able; returns OBX_SUCCESS if model is NULL
OBX_C_API obx_err obx_model_free(OBX_model* model);
/// To minimise the amount of error handling code required when building a model, the first error is stored and can be
/// obtained here. All the obx_model_XXX functions are null operations after the first model error has occurred.
/// @param model NULL-able; returns OBX_ERROR_ILLEGAL_ARGUMENT if model is NULL
OBX_C_API obx_err obx_model_error_code(OBX_model* model);
/// To minimise the amount of error handling code required when building a model, the first error is stored and can be
/// obtained here. All the obx_model_XXX functions are null operations after the first model error has occurred.
/// @param model NULL-able; returns NULL if model is NULL
OBX_C_API const char* obx_model_error_message(OBX_model* model);
/// Starts the definition of a new entity type for the meta data model.
/// After this, call obx_model_property() to add properties to the entity type.
/// @param name A human readable name for the entity. Must be unique within the model
/// @param entity_id Must be unique within this version of the model
/// @param entity_uid Used to identify entities between versions of the model. Must be globally unique.
OBX_C_API obx_err obx_model_entity(OBX_model* model, const char* name, obx_schema_id entity_id, obx_uid entity_uid);
/// Refine the definition of the entity declared by the most recent obx_model_entity() call, specifying flags.
/// @param flags See OBXEntityFlags for values (use bitwise OR to combine multiple flags)
OBX_C_API obx_err obx_model_entity_flags(OBX_model* model, uint32_t flags);
/// Starts the definition of a new property for the entity type of the last obx_model_entity() call.
/// @param name A human readable name for the property. Must be unique within the entity
/// @param type The type of property required
/// @param property_id Must be unique within the entity
/// @param property_uid Used to identify properties between versions of the entity. Must be global unique.
OBX_C_API obx_err obx_model_property(OBX_model* model, const char* name, OBXPropertyType type,
obx_schema_id property_id, obx_uid property_uid);
/// Refine the definition of the property declared by the most recent obx_model_property() call, specifying flags.
/// @param flags See OBXPropertyFlags for values (use bitwise OR to combine multiple flags)
OBX_C_API obx_err obx_model_property_flags(OBX_model* model, uint32_t flags);
/// Refine the definition of the property declared by the most recent obx_model_property() call, declaring it a
/// relation.
/// @param target_entity The name of the entity linked to by the relation
/// @param index_id Must be unique within this version of the model
/// @param index_uid Used to identify relations between versions of the model. Must be globally unique.
OBX_C_API obx_err obx_model_property_relation(OBX_model* model, const char* target_entity, obx_schema_id index_id,
obx_uid index_uid);
/// Refine the definition of the property declared by the most recent obx_model_property() call, adding an index.
/// @param index_id Must be unique within this version of the model
/// @param index_uid Used to identify relations between versions of the model. Must be globally unique.
OBX_C_API obx_err obx_model_property_index_id(OBX_model* model, obx_schema_id index_id, obx_uid index_uid);
/// Sets the vector dimensionality for the HNSW index of the latest property (must be of a supported vector type).
/// This a mandatory option for all HNSW indexes.
/// Note 1: vectors with higher dimensions than this value are also indexed (ignoring the higher elements).
/// Note 2: vectors with lower dimensions than this value are completely ignored for indexing.
OBX_C_API obx_err obx_model_property_index_hnsw_dimensions(OBX_model* model, size_t value);
/// Sets the max number of neighbors per node (aka "M") for the HNSW index of the latest property.
/// Higher number increases the graph connectivity which can lead to better results, but higher resources usage.
/// If no value is set, a default value taken (currently 30).
/// Try e.g. 16 for faster but less accurate results, or 64 for more accurate results.
OBX_C_API obx_err obx_model_property_index_hnsw_neighbors_per_node(OBX_model* model, uint32_t value);
/// Sets the max number of neighbors searched while indexing (aka "efConstruction") for the HNSW index of the latest
/// property.
/// If no value is set, a default value taken (currently 100, which can change in future version).
/// The default value serves as a starting point that can likely be optimized for specific datasets and use cases.
/// The higher the value, the more accurate the search, but the longer the indexing will take.
/// If indexing time is not a major concern, a value of at least 200 is recommended to improve search quality.
OBX_C_API obx_err obx_model_property_index_hnsw_indexing_search_count(OBX_model* model, uint32_t value);
/// Sets flags for the HNSW index of the latest property ().
/// For details see OBXHnswFlags and its individual values.
/// @param flags See OBXHnswFlags for values (use bitwise OR to combine multiple flags)
OBX_C_API obx_err obx_model_property_index_hnsw_flags(OBX_model* model, uint32_t flags);
/// Sets the distance type for the HNSW index of the latest property.
OBX_C_API obx_err obx_model_property_index_hnsw_distance_type(OBX_model* model, OBXVectorDistanceType value);
/// Sets the reparation backlink probability, for the HNSW index of the latest property.
/// When repairing the graph after a node was removed, this gives the probability of adding backlinks to the repaired
/// neighbors. The default is 1.0 (aka "always") as this should be worth a bit of extra costs as it improves the graph's
/// quality.
OBX_C_API obx_err obx_model_property_index_hnsw_reparation_backlink_probability(OBX_model* model, float value);
/// Sets the vector cache hint size for the HNSW index of the latest property.
/// This is a non-binding hint of the maximum size of the vector cache in KB (default: 2097152 or 2 GB/GiB).
OBX_C_API obx_err obx_model_property_index_hnsw_vector_cache_hint_size_kb(OBX_model* model, size_t value);
/// Add a standalone relation between the active entity and the target entity to the model
/// @param relation_id Must be unique within this version of the model
/// @param relation_uid Used to identify relations between versions of the model. Must be globally unique.
/// @param target_id The id of the target entity of the relation
/// @param target_uid The uid of the target entity of the relation
OBX_C_API obx_err obx_model_relation(OBX_model* model, obx_schema_id relation_id, obx_uid relation_uid,
obx_schema_id target_id, obx_uid target_uid);
/// Set the highest ever known entity id in the model. Should always be equal to or higher than the
/// last entity id of the previous version of the model
OBX_C_API void obx_model_last_entity_id(OBX_model*, obx_schema_id entity_id, obx_uid entity_uid);
/// Set the highest ever known index id in the model. Should always be equal to or higher than the
/// last index id of the previous version of the model
OBX_C_API void obx_model_last_index_id(OBX_model* model, obx_schema_id index_id, obx_uid index_uid);
/// Set the highest every known relation id in the model. Should always be equal to or higher than the
/// last relation id of the previous version of the model.
OBX_C_API void obx_model_last_relation_id(OBX_model* model, obx_schema_id relation_id, obx_uid relation_uid);
/// Set the highest ever known property id in the entity. Should always be equal to or higher than the
/// last property id of the previous version of the entity.
OBX_C_API obx_err obx_model_entity_last_property_id(OBX_model* model, obx_schema_id property_id, obx_uid property_uid);
//----------------------------------------------
// Store
//----------------------------------------------
struct OBX_store; // doxygen (only) picks up the typedef struct below
/// \brief A ObjectBox store represents a database storing data in a given directory on a local file system or in-memory
/// using "memory:" directory prefix.
///
/// Once opened using obx_store_open(), it's an entry point to data access APIs such as box, query, cursor, transaction.
/// After your work is done, you must close obx_store_close() to safely release all the handles and avoid data loss.
///
/// It's possible open multiple stores in different directories.
typedef struct OBX_store OBX_store;
struct OBX_store_options; // doxygen (only) picks up the typedef struct below
/// Store options customize the behavior of ObjectBox before opening a store. Options can't be changed once the store is
/// open but of course you can close the store and open it again with the changed options.
/// Some of the notable options are obx_opt_directory() and obx_opt_max_db_size_in_kb().
typedef struct OBX_store_options OBX_store_options;
/// Debug flags typically enable additional "debug logging" that can be helpful to better understand what is going on
/// internally. These are intended for the development process only; typically one does not enable them for releases.
typedef enum {
OBXDebugFlags_LOG_TRANSACTIONS_READ = 1,
OBXDebugFlags_LOG_TRANSACTIONS_WRITE = 2,
OBXDebugFlags_LOG_QUERIES = 4,
OBXDebugFlags_LOG_QUERY_PARAMETERS = 8,
OBXDebugFlags_LOG_ASYNC_QUEUE = 16,
OBXDebugFlags_LOG_CACHE_HITS = 32,
OBXDebugFlags_LOG_CACHE_ALL = 64,
OBXDebugFlags_LOG_TREE = 128,
/// For a limited number of error conditions, this will try to print stack traces.
/// Note: this is Linux-only, experimental, and has several limitations:
/// The usefulness of these stack traces depends on several factors and might not be helpful at all.
OBXDebugFlags_LOG_EXCEPTION_STACK_TRACE = 256,
/// Run a quick self-test to verify basic threading; somewhat paranoia to check the platform and the library setup.
OBXDebugFlags_RUN_THREADING_SELF_TEST = 512,
} OBXDebugFlags;
/// Flags used to control pages validation options when opening the store.
typedef enum {
OBXValidateOnOpenPagesFlags_None = 0, ///< No special flags
/// Enable validation of leaf pages (by default only branch pages are validated)
OBXValidateOnOpenPagesFlags_VisitLeafPages = 1,
} OBXValidateOnOpenPagesFlags;
/// Flags used to control key/value pairs validation options when opening the store.
/// Note: this enum does not contain any actual values besides "None" yet; it's only used to future proof the API.
typedef enum {
OBXValidateOnOpenKvFlags_None = 0, ///< No special flags
} OBXValidateOnOpenKvFlags;
/// Defines a padding mode for putting data bytes.
/// Depending on how that data is created, this mode may optimize data handling by avoiding copying memory.
/// Internal background: data buffers used by put operations are required to have a size divisible by 4 for an
/// efficient data layout.
typedef enum {
/// Adds a padding when needed (may require a memory copy): this is the safe option and also the default.
/// The extra memory copy may impact performance, however this is usually not noticeable.
OBXPutPaddingMode_PaddingAutomatic = 1,
/// Indicates that data buffers are safe to be extended for padding (adding up to 3 bytes to size is OK).
/// Typically, it depends on the used FlatBuffers builder; e.g. the official C++ seems to ensure it, but
/// flatcc (3rd party implementation for plain C) may not.
OBXPutPaddingMode_PaddingAllowedByBuffer = 2,
/// The caller ensures that all data bytes are already padded.
/// ObjectBox will verify the buffer size and returns an error if it's not divisible by 4.
OBXPutPaddingMode_PaddingByCaller = 3,
} OBXPutPaddingMode;
/// Backup flags control how the store creates backup files.
/// E.g. when you want "deterministic" file content, you can exclude timestamp and salt.
typedef enum {
/// Do not include a timestamp in the backup file (time when the backup file is generated).
OBXBackupFlags_ExcludeTimestamp = 0x1,
/// Do not include a random salt in the backup file.
OBXBackupFlags_ExcludeSalt = 0x2,
} OBXBackupFlags;
/// WAL flags control how the store handles WAL files.
typedef enum {
/// Enable Wal
OBXWalFlags_EnableWal = 0x1,
/// Does not wait for the disk to acknowledge; faster but not ACID compliant (not generally recommended).
OBXWalFlags_NoSyncFile = 0x2,
} OBXWalFlags;
/// This bytes struct is an input/output wrapper used for a single data object (represented as FlatBuffers).
typedef struct OBX_bytes {
const void* data;
size_t size;
} OBX_bytes;
/// This bytes array struct is an input/output wrapper for multiple data objects (represented as FlatBuffers).
typedef struct OBX_bytes_array {
OBX_bytes* bytes;
size_t count;
} OBX_bytes_array;
/// This bytes score struct is an input/output wrapper used for a single data object (represented as FlatBuffers)
/// with its associated query score, which is used for special query results.
typedef struct OBX_bytes_score {
const void* data;
size_t size;
/// The query score indicates some quality measurement.
/// E.g. for vector nearest neighbor searches, the score is the distance to the given vector.
double score;
} OBX_bytes_score;
/// This bytes score array struct is an input/output wrapper pointing to multiple OBX_bytes_score instances.
/// If count is zero, bytes_scores is allowed to be invalid.
typedef struct OBX_bytes_score_array {
OBX_bytes_score* bytes_scores;
size_t count;
} OBX_bytes_score_array;
struct OBX_bytes_lazy; // doxygen (only) picks up the typedef struct below
/// Bytes, which must be resolved "lazily" via obx_bytes_lazy_get() and released via obx_bytes_lazy_free().
/// Unlike OBX_bytes, this may represent allocated resources and/or bytes that are only produced on demand.
typedef struct OBX_bytes_lazy OBX_bytes_lazy;
/// Get the actual bytes from the given OBX_bytes_lazy.
/// Because of the potential lazy creation of bytes, the given bytes are not const as it may be resolved internally.
/// For the same reason, this function is not thread-safe, at least for the first call on a OBX_bytes_lazy instance.
/// @param out_bytes The pointer to a data pointer may be null, e.g. if you are only interested in the size.
OBX_C_API obx_err obx_bytes_lazy_get(OBX_bytes_lazy* bytes, const void** out_bytes, size_t* out_size);
/// Releases any resources associated with the given OBX_bytes_lazy.
OBX_C_API void obx_bytes_lazy_free(OBX_bytes_lazy* bytes);
/// ID array struct is an input/output wrapper for an array of object IDs.
typedef struct OBX_id_array {
obx_id* ids;
size_t count;
} OBX_id_array;
/// ID score array struct is an input/output wrapper for an array of OBX_id_score structs.
/// If count is zero, bytes_scores is allowed to be invalid.
typedef struct OBX_id_score_array {
OBX_id_score* ids_scores;
size_t count;
} OBX_id_score_array;
/// String array struct is an input/output wrapper for an array of character strings.
typedef struct OBX_string_array {
const char** items;
size_t count;
} OBX_string_array;
/// Int64 array struct is an input/output wrapper for an array of int64 numbers.
typedef struct OBX_int64_array {
const int64_t* items;
size_t count;
} OBX_int64_array;
/// Int32 array struct is an input/output wrapper for an array of int32 numbers.
typedef struct OBX_int32_array {
const int32_t* items;
size_t count;
} OBX_int32_array;
/// Int16 array struct is an input/output wrapper for an array of int16 numbers.
typedef struct OBX_int16_array {
const int16_t* items;
size_t count;
} OBX_int16_array;
/// Int8 array struct is an input/output wrapper for an array of int8 numbers.
typedef struct OBX_int8_array {
const int8_t* items;
size_t count;
} OBX_int8_array;
/// Double array struct is an input/output wrapper for an array of double precision floating point numbers.
typedef struct OBX_double_array {
const double* items;
size_t count;
} OBX_double_array;
/// Float array struct is an input/output wrapper for an array of single precision floating point numbers.
typedef struct OBX_float_array {
const float* items;
size_t count;
} OBX_float_array;
//----------------------------------------------
// Store Options
//----------------------------------------------
/// Create a default set of store options.
/// @returns NULL on failure, a default set of options on success
OBX_C_API OBX_store_options* obx_opt();
/// Set the store directory on the options. The default is "objectbox".
/// Use prefix "memory:" to open an in-memory database, e.g. "memory:myApp" (see docs for details).
OBX_C_API obx_err obx_opt_directory(OBX_store_options* opt, const char* dir);
/// Set the maximum db size on the options. The default is 1Gb.
OBX_C_API void obx_opt_max_db_size_in_kb(OBX_store_options* opt, uint64_t size_in_kb);
/// Data size tracking is more involved than DB size tracking, e.g. it stores an internal counter.
/// Thus only use it if a stricter, more accurate limit is required (it's off by default).
/// It tracks the size of actual data bytes of objects (system and metadata is not considered).
/// On the upside, reaching the data limit still allows data to be removed (assuming DB limit is not reached).
/// Max data and DB sizes can be combined; data size must be below the DB size.
OBX_C_API void obx_opt_max_data_size_in_kb(OBX_store_options* opt, uint64_t size_in_kb);
/// Set the file mode on the options. The default is 0644 (unix-style).
OBX_C_API void obx_opt_file_mode(OBX_store_options* opt, unsigned int file_mode);
/// Set the maximum number of readers (related to read transactions) on the given options.
/// "Readers" are an finite resource for which we need to define a maximum number upfront.
/// The default value is enough for most apps and usually you can ignore it completely.
/// However, if you get the OBX_ERROR_MAX_READERS_EXCEEDED error, you should verify your threading.
/// For each thread, ObjectBox uses multiple readers.
/// Their number (per thread) depends on number of types, relations, and usage patterns.
/// Thus, if you are working with many threads (e.g. in a server-like scenario), it can make sense to increase the
/// maximum number of readers.
///
/// \note The internal default is currently 126. So when hitting this limit, try values around 200-500.
///
/// \attention Each thread that performed a read transaction and is still alive holds on to a reader slot.
/// These slots only get vacated when the thread ends. Thus be mindful with the number of active threads.
/// Alternatively, you can opt to try the experimental noReaderThreadLocals option flag.
OBX_C_API void obx_opt_max_readers(OBX_store_options* opt, unsigned int max_readers);
/// Disables the usage of thread locals for "readers" related to read transactions.
/// This can make sense if you are using a lot of threads that are kept alive.
/// \note This is still experimental, as it comes with subtle behavior changes at a low level and may affect
/// corner cases with e.g. transactions, which may not be fully tested at the moment.
OBX_C_API void obx_opt_no_reader_thread_locals(OBX_store_options* opt, bool flag);
/// Set the model on the options. The default is no model.
/// NOTE: the model is always freed by this function, including when an error occurs.
OBX_C_API obx_err obx_opt_model(OBX_store_options* opt, OBX_model* model);
/// Set the model on the options copying the given bytes. The default is no model.
OBX_C_API obx_err obx_opt_model_bytes(OBX_store_options* opt, const void* bytes, size_t size);
/// Like obx_opt_model_bytes BUT WITHOUT copying the given bytes.
/// Thus, you must keep the bytes available until after the store is created.
OBX_C_API obx_err obx_opt_model_bytes_direct(OBX_store_options* opt, const void* bytes, size_t size);
/// When the DB is opened initially, ObjectBox can do a consistency check on the given amount of pages.
/// Reliable file systems already guarantee consistency, so this is primarily meant to deal with unreliable
/// OSes, file systems, or hardware. Thus, usually a low number (e.g. 1-20) is sufficient and does not impact
/// startup performance significantly. To completely disable this you can pass 0, but we recommend a setting of
/// at least 1.
/// Note: ObjectBox builds upon ACID storage, which guarantees consistency given that the file system is working
/// correctly (in particular fsync).
/// @param page_limit limits the number of checked pages (currently defaults to 0, but will be increased in the future)
/// @param flags flags used to influence how the validation checks are performed;
/// see OBXValidateOnOpenPagesFlags for values (use bitwise OR to combine multiple flags)
OBX_C_API void obx_opt_validate_on_open_pages(OBX_store_options* opt, size_t page_limit, uint32_t flags);