Compare commits
2 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a92ad64d22 | |||
| 6537d42d7e |
Vendored
+879
-973
File diff suppressed because it is too large
Load Diff
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
BIN
Binary file not shown.
Vendored
+11
-12
@@ -15,29 +15,28 @@ main :: proc() {
|
|||||||
// Create environment for lmdb
|
// Create environment for lmdb
|
||||||
mdb.panic_on_err(mdb.env_create(&environment))
|
mdb.panic_on_err(mdb.env_create(&environment))
|
||||||
// Create directory for databases. Won't do anything if it already exists.
|
// Create directory for databases. Won't do anything if it already exists.
|
||||||
// 0o774 gives all permissions for owner and group, read for everyone else.
|
os.make_directory(DB_PATH)
|
||||||
os.make_directory(DB_PATH, 0o774)
|
|
||||||
// Open the database files (creates them if they don't already exist)
|
// Open the database files (creates them if they don't already exist)
|
||||||
mdb.panic_on_err(mdb.env_open(environment, DB_PATH, 0, DB_MODE))
|
mdb.panic_on_err(mdb.env_open(environment, DB_PATH, {}, DB_MODE))
|
||||||
|
|
||||||
// Transactions
|
// Transactions
|
||||||
txn_handle: ^mdb.Txn
|
txn_handle: ^mdb.Txn
|
||||||
db_handle: mdb.Dbi
|
db_handle: mdb.Dbi
|
||||||
// Put transaction
|
// Put transaction
|
||||||
key := 7
|
key := 7
|
||||||
key_val := mdb.autoval(&key)
|
key_val := mdb.blittable_val(&key)
|
||||||
put_data := 12
|
put_data := 12
|
||||||
put_data_val := mdb.autoval(&put_data)
|
put_data_val := mdb.blittable_val(&put_data)
|
||||||
mdb.panic_on_err(mdb.txn_begin(environment, nil, 0, &txn_handle))
|
mdb.panic_on_err(mdb.txn_begin(environment, nil, {}, &txn_handle))
|
||||||
mdb.panic_on_err(mdb.dbi_open(txn_handle, nil, 0, &db_handle))
|
mdb.panic_on_err(mdb.dbi_open(txn_handle, nil, {}, &db_handle))
|
||||||
mdb.panic_on_err(mdb.put(txn_handle, db_handle, &key_val.raw, &put_data_val.raw, 0))
|
mdb.panic_on_err(mdb.put(txn_handle, db_handle, &key_val, &put_data_val, {}))
|
||||||
mdb.panic_on_err(mdb.txn_commit(txn_handle))
|
mdb.panic_on_err(mdb.txn_commit(txn_handle))
|
||||||
|
|
||||||
// Get transaction
|
// Get transaction
|
||||||
get_data_val := mdb.nil_autoval(int)
|
data_val: mdb.Val
|
||||||
mdb.panic_on_err(mdb.txn_begin(environment, nil, 0, &txn_handle))
|
mdb.panic_on_err(mdb.txn_begin(environment, nil, {}, &txn_handle))
|
||||||
mdb.panic_on_err(mdb.get(txn_handle, db_handle, &key_val.raw, &get_data_val.raw))
|
mdb.panic_on_err(mdb.get(txn_handle, db_handle, &key_val, &data_val))
|
||||||
|
data_cpy := mdb.blittable_copy(&data_val, int)
|
||||||
mdb.panic_on_err(mdb.txn_commit(txn_handle))
|
mdb.panic_on_err(mdb.txn_commit(txn_handle))
|
||||||
data_cpy := mdb.autoval_get_data(&get_data_val)^
|
|
||||||
fmt.println("Get result:", data_cpy)
|
fmt.println("Get result:", data_cpy)
|
||||||
}
|
}
|
||||||
|
|||||||
Vendored
+195
-153
@@ -164,24 +164,123 @@
|
|||||||
*/
|
*/
|
||||||
package lmdb
|
package lmdb
|
||||||
|
|
||||||
foreign import lib "system:lmdb"
|
|
||||||
|
|
||||||
import "core:c"
|
import "core:c"
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
|
import "core:reflect"
|
||||||
import "core:sys/posix"
|
import "core:sys/posix"
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// ----- Added Odin Helpers ------------------------
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
// Wrap a blittable value's bytes as an LMDB Val.
|
||||||
|
// T must be a contiguous type with no indirection (no pointers, slices, strings, maps, etc.).
|
||||||
|
blittable_val :: #force_inline proc(val_ptr: ^$T) -> Val {
|
||||||
|
fmt.assertf(
|
||||||
|
reflect.has_no_indirections(type_info_of(T)),
|
||||||
|
"blitval: type '%v' contains indirection and cannot be stored directly in LMDB",
|
||||||
|
typeid_of(T),
|
||||||
|
)
|
||||||
|
return Val{size_of(T), val_ptr}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reads a blittable T out of the LMDB memory map by copying it into caller
|
||||||
|
// storage. The returned T has no lifetime tie to the transaction.
|
||||||
|
blittable_copy :: #force_inline proc(val: ^Val, $T: typeid) -> T {
|
||||||
|
fmt.assertf(
|
||||||
|
reflect.has_no_indirections(type_info_of(T)),
|
||||||
|
"blitval_copy: type '%v' contains indirection and cannot be read directly from LMDB",
|
||||||
|
typeid_of(T),
|
||||||
|
)
|
||||||
|
return (cast(^T)val.data)^
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero-copy pointer view into the LMDB memory map as a ^T.
|
||||||
|
// Useful for large blittable types where you want to read individual fields
|
||||||
|
// without copying the entire value (e.g. ptr.timestamp, ptr.flags).
|
||||||
|
// MUST NOT be written through — writes either segfault (default env mode)
|
||||||
|
// or silently corrupt the database (ENV_WRITEMAP).
|
||||||
|
// MUST NOT be retained past txn_commit, txn_abort, or any subsequent write
|
||||||
|
// operation on the same env — the pointer is invalidated.
|
||||||
|
blittable_view :: #force_inline proc(val: ^Val, $T: typeid) -> ^T {
|
||||||
|
fmt.assertf(
|
||||||
|
reflect.has_no_indirections(type_info_of(T)),
|
||||||
|
"blitval_view: type '%v' contains indirection and cannot be viewed directly from LMDB",
|
||||||
|
typeid_of(T),
|
||||||
|
)
|
||||||
|
return cast(^T)val.data
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap a slice of blittable elements as an LMDB Val for use with put/get.
|
||||||
|
// T must be a contiguous type with no indirection.
|
||||||
|
// The caller's slice must remain valid (not freed, not resized) for the
|
||||||
|
// duration of the put call that consumes this Val.
|
||||||
|
slice_val :: #force_inline proc(s: []$T) -> Val {
|
||||||
|
fmt.assertf(
|
||||||
|
reflect.has_no_indirections(type_info_of(T)),
|
||||||
|
"slice_val: element type '%v' contains indirection and cannot be stored directly in LMDB",
|
||||||
|
typeid_of(T),
|
||||||
|
)
|
||||||
|
return Val{uint(len(s) * size_of(T)), raw_data(s)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero-copy slice view into the LMDB memory map.
|
||||||
|
// T must match the element type that was originally stored.
|
||||||
|
// MUST NOT be modified — writes through this slice either segfault (default
|
||||||
|
// env mode) or silently corrupt the database (ENV_WRITEMAP).
|
||||||
|
// MUST be copied (e.g. slice.clone) if it needs to outlive the current
|
||||||
|
// transaction; the view is invalidated by txn_commit, txn_abort, or any
|
||||||
|
// subsequent write operation on the same env.
|
||||||
|
slice_view :: #force_inline proc(val: ^Val, $T: typeid) -> []T {
|
||||||
|
fmt.assertf(
|
||||||
|
reflect.has_no_indirections(type_info_of(T)),
|
||||||
|
"slice_view: element type '%v' contains indirection and cannot be read directly from LMDB",
|
||||||
|
typeid_of(T),
|
||||||
|
)
|
||||||
|
return (cast([^]T)val.data)[:val.size / size_of(T)]
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wrap a string's bytes as an LMDB Val for use with put/get.
|
||||||
|
// The caller's string must remain valid (backing memory not freed) for the
|
||||||
|
// duration of the put call that consumes this Val.
|
||||||
|
string_val :: #force_inline proc(s: string) -> Val {
|
||||||
|
return Val{uint(len(s)), raw_data(s)}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Zero-copy string view into the LMDB memory map.
|
||||||
|
// MUST NOT be modified — writes through the underlying bytes either segfault
|
||||||
|
// (default env mode) or silently corrupt the database (ENV_WRITEMAP).
|
||||||
|
// MUST be copied (e.g. strings.clone) if it needs to outlive the current
|
||||||
|
// transaction; the view is invalidated by txn_commit, txn_abort, or any
|
||||||
|
// subsequent write operation on the same env.
|
||||||
|
string_view :: #force_inline proc(val: ^Val) -> string {
|
||||||
|
return string((cast([^]u8)val.data)[:val.size])
|
||||||
|
}
|
||||||
|
|
||||||
|
// Panic if there is an error
|
||||||
|
panic_on_err :: #force_inline proc(error: Error, loc := #caller_location) {
|
||||||
|
if error != .NONE {
|
||||||
|
fmt.panicf("LMDB error %v: %s", error, strerror(i32(error)), loc = loc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
// ----- Bindings ------------------------
|
||||||
|
// ---------------------------------------------------------------------------------------------------------------------
|
||||||
|
|
||||||
_ :: c
|
_ :: c
|
||||||
|
|
||||||
when ODIN_OS == .Windows {
|
when ODIN_OS == .Windows {
|
||||||
|
#panic("TODO: Compile windows .lib for lmdb")
|
||||||
mode_t :: c.int
|
mode_t :: c.int
|
||||||
} else {
|
|
||||||
mode_t :: posix.mode_t
|
|
||||||
}
|
|
||||||
|
|
||||||
when ODIN_OS == .Windows {
|
|
||||||
filehandle_t :: rawptr
|
filehandle_t :: rawptr
|
||||||
} else {
|
} else when ODIN_OS ==
|
||||||
|
.Linux || ODIN_OS == .Darwin || ODIN_OS == .FreeBSD || ODIN_OS == .OpenBSD || ODIN_OS == .NetBSD {
|
||||||
|
foreign import lib "system:lmdb"
|
||||||
|
mode_t :: posix.mode_t
|
||||||
filehandle_t :: c.int
|
filehandle_t :: c.int
|
||||||
|
} else {
|
||||||
|
#panic("levlib/vendor/lmdb: unsupported OS target")
|
||||||
}
|
}
|
||||||
|
|
||||||
Env :: struct {}
|
Env :: struct {}
|
||||||
@@ -189,7 +288,7 @@ Env :: struct {}
|
|||||||
Txn :: struct {}
|
Txn :: struct {}
|
||||||
|
|
||||||
/** @brief A handle for an individual database in the DB environment. */
|
/** @brief A handle for an individual database in the DB environment. */
|
||||||
Dbi :: u32
|
Dbi :: c.uint
|
||||||
|
|
||||||
Cursor :: struct {}
|
Cursor :: struct {}
|
||||||
|
|
||||||
@@ -205,33 +304,8 @@ Cursor :: struct {}
|
|||||||
* Other data items can in theory be from 0 to 0xffffffff bytes long.
|
* Other data items can in theory be from 0 to 0xffffffff bytes long.
|
||||||
*/
|
*/
|
||||||
Val :: struct {
|
Val :: struct {
|
||||||
mv_size: uint, /**< size of the data item */
|
size: uint, /**< size of the data item */
|
||||||
mv_data: rawptr, /**< address of the data item */
|
data: rawptr, /**< address of the data item */
|
||||||
}
|
|
||||||
|
|
||||||
// Automatic `Val` handling for a given type 'T'.
|
|
||||||
// Will not traverse pointers. If `T` stores pointers, you probably don't want to use this.
|
|
||||||
Auto_Val :: struct($T: typeid) {
|
|
||||||
raw: Val,
|
|
||||||
}
|
|
||||||
|
|
||||||
autoval :: #force_inline proc "contextless" (val_ptr: ^$T) -> Auto_Val(T) {
|
|
||||||
return Auto_Val(T){Val{size_of(T), val_ptr}}
|
|
||||||
}
|
|
||||||
|
|
||||||
nil_autoval :: #force_inline proc "contextless" ($T: typeid) -> Auto_Val(T) {
|
|
||||||
return Auto_Val(T){Val{size_of(T), nil}}
|
|
||||||
}
|
|
||||||
|
|
||||||
autoval_get_data :: #force_inline proc "contextless" (val: ^Auto_Val($T)) -> ^T {
|
|
||||||
return cast(^T)val.raw.mv_data
|
|
||||||
}
|
|
||||||
|
|
||||||
// Panic if there is an error
|
|
||||||
panic_on_err :: #force_inline proc(error: Error) {
|
|
||||||
if error != .NONE {
|
|
||||||
fmt.panicf("Irrecoverable LMDB error", strerror(i32(error)))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief A callback function used to compare two keys in a database */
|
/** @brief A callback function used to compare two keys in a database */
|
||||||
@@ -253,85 +327,65 @@ Cmp_Func :: #type proc "c" (_: ^Val, _: ^Val) -> i32
|
|||||||
*/
|
*/
|
||||||
Rel_Func :: #type proc "c" (item: ^Val, oldptr, newptr, relctx: rawptr)
|
Rel_Func :: #type proc "c" (item: ^Val, oldptr, newptr, relctx: rawptr)
|
||||||
|
|
||||||
/** @defgroup mdb_env Environment Flags
|
/** @defgroup mdb_env Environment Flags
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** mmap at a fixed address (experimental) */
|
Env_Flag :: enum u32 {
|
||||||
ENV_FIXEDMAP :: 0x01
|
FIXEDMAP = 0, /**< mmap at a fixed address (experimental) */
|
||||||
/** no environment directory */
|
NOSUBDIR = 14, /**< no environment directory */
|
||||||
ENV_NOSUBDIR :: 0x4000
|
NOSYNC = 16, /**< don't fsync after commit */
|
||||||
/** don't fsync after commit */
|
RDONLY = 17, /**< read only */
|
||||||
ENV_NOSYNC :: 0x10000
|
NOMETASYNC = 18, /**< don't fsync metapage after commit */
|
||||||
/** read only */
|
WRITEMAP = 19, /**< use writable mmap */
|
||||||
ENV_RDONLY :: 0x20000
|
MAPASYNC = 20, /**< use asynchronous msync when WRITEMAP is used */
|
||||||
/** don't fsync metapage after commit */
|
NOTLS = 21, /**< tie reader locktable slots to Txn objects instead of to threads */
|
||||||
ENV_NOMETASYNC :: 0x40000
|
NOLOCK = 22, /**< don't do any locking, caller must manage their own locks */
|
||||||
/** use writable mmap */
|
NORDAHEAD = 23, /**< don't do readahead (no effect on Windows) */
|
||||||
ENV_WRITEMAP :: 0x80000
|
NOMEMINIT = 24, /**< don't initialize malloc'd memory before writing to datafile */
|
||||||
/** use asynchronous msync when #MDB_WRITEMAP is used */
|
PREVSNAPSHOT = 25, /**< use the previous snapshot rather than the latest one */
|
||||||
ENV_MAPASYNC :: 0x100000
|
}
|
||||||
/** tie reader locktable slots to #MDB_txn objects instead of to threads */
|
Env_Flags :: distinct bit_set[Env_Flag;c.uint]
|
||||||
ENV_NOTLS :: 0x200000
|
|
||||||
/** don't do any locking, caller must manage their own locks */
|
|
||||||
ENV_NOLOCK :: 0x400000
|
|
||||||
/** don't do readahead (no effect on Windows) */
|
|
||||||
ENV_NORDAHEAD :: 0x800000
|
|
||||||
/** don't initialize malloc'd memory before writing to datafile */
|
|
||||||
ENV_NOMEMINIT :: 0x1000000
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @defgroup mdb_dbi_open Database Flags
|
/** @defgroup mdb_dbi_open Database Flags
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** use reverse string keys */
|
Db_Flag :: enum u32 {
|
||||||
DB_REVERSEKEY :: 0x02
|
REVERSEKEY = 1, /**< use reverse string keys */
|
||||||
/** use sorted duplicates */
|
DUPSORT = 2, /**< use sorted duplicates */
|
||||||
DB_DUPSORT :: 0x04
|
INTEGERKEY = 3, /**< numeric keys in native byte order */
|
||||||
/** numeric keys in native byte order: either unsigned int or size_t.
|
DUPFIXED = 4, /**< with DUPSORT, sorted dup items have fixed size */
|
||||||
* The keys must all be of the same size. */
|
INTEGERDUP = 5, /**< with DUPSORT, dups are INTEGERKEY-style integers */
|
||||||
DB_INTEGERKEY :: 0x08
|
REVERSEDUP = 6, /**< with DUPSORT, use reverse string dups */
|
||||||
/** with #MDB_DUPSORT, sorted dup items have fixed size */
|
CREATE = 18, /**< create DB if not already existing */
|
||||||
DB_DUPFIXED :: 0x10
|
}
|
||||||
/** with #MDB_DUPSORT, dups are #MDB_INTEGERKEY-style integers */
|
Db_Flags :: distinct bit_set[Db_Flag;c.uint]
|
||||||
DB_INTEGERDUP :: 0x20
|
|
||||||
/** with #MDB_DUPSORT, use reverse string dups */
|
|
||||||
DB_REVERSEDUP :: 0x40
|
|
||||||
/** create DB if not already existing */
|
|
||||||
DB_CREATE :: 0x40000
|
|
||||||
/** @} */
|
/** @} */
|
||||||
|
|
||||||
/** @defgroup mdb_put Write Flags
|
/** @defgroup mdb_put Write Flags
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** For put: Don't write if the key already exists. */
|
Write_Flag :: enum u32 {
|
||||||
WRITE_NOOVERWRITE :: 0x10
|
NOOVERWRITE = 4, /**< For put: Don't write if the key already exists */
|
||||||
/** Only for #MDB_DUPSORT<br>
|
NODUPDATA = 5, /**< For DUPSORT: don't write if the key and data pair already exist.
|
||||||
* For put: don't write if the key and data pair already exist.<br>
|
For mdb_cursor_del: remove all duplicate data items. */
|
||||||
* For mdb_cursor_del: remove all duplicate data items.
|
CURRENT = 6, /**< For mdb_cursor_put: overwrite the current key/data pair */
|
||||||
*/
|
RESERVE = 16, /**< For put: Just reserve space for data, don't copy it */
|
||||||
WRITE_NODUPDATA :: 0x20
|
APPEND = 17, /**< Data is being appended, don't split full pages */
|
||||||
/** For mdb_cursor_put: overwrite the current key/data pair */
|
APPENDDUP = 18, /**< Duplicate data is being appended, don't split full pages */
|
||||||
WRITE_CURRENT :: 0x40
|
MULTIPLE = 19, /**< Store multiple data items in one call. Only for DUPFIXED. */
|
||||||
/** For put: Just reserve space for data, don't copy it. Return a
|
}
|
||||||
* pointer to the reserved space.
|
Write_Flags :: distinct bit_set[Write_Flag;c.uint]
|
||||||
*/
|
/** @} */
|
||||||
WRITE_RESERVE :: 0x10000
|
|
||||||
/** Data is being appended, don't split full pages. */
|
|
||||||
WRITE_APPEND :: 0x20000
|
|
||||||
/** Duplicate data is being appended, don't split full pages. */
|
|
||||||
WRITE_APPENDDUP :: 0x40000
|
|
||||||
/** Store multiple data items in one call. Only for #MDB_DUPFIXED. */
|
|
||||||
WRITE_MULTIPLE :: 0x80000
|
|
||||||
/* @} */
|
|
||||||
|
|
||||||
/** @defgroup mdb_copy Copy Flags
|
/** @defgroup mdb_copy Copy Flags
|
||||||
* @{
|
* @{
|
||||||
*/
|
*/
|
||||||
/** Compacting copy: Omit free space from copy, and renumber all
|
Copy_Flag :: enum u32 {
|
||||||
* pages sequentially.
|
COMPACT = 0, /**< Compacting copy: Omit free space from copy, and renumber all pages sequentially. */
|
||||||
*/
|
}
|
||||||
CP_COMPACT :: 0x01
|
Copy_Flags :: distinct bit_set[Copy_Flag;c.uint]
|
||||||
/* @} */
|
/** @} */
|
||||||
|
|
||||||
/** @brief Cursor Get operations.
|
/** @brief Cursor Get operations.
|
||||||
*
|
*
|
||||||
@@ -340,33 +394,24 @@ CP_COMPACT :: 0x01
|
|||||||
*/
|
*/
|
||||||
Cursor_Op :: enum c.int {
|
Cursor_Op :: enum c.int {
|
||||||
FIRST, /**< Position at first key/data item */
|
FIRST, /**< Position at first key/data item */
|
||||||
FIRST_DUP, /**< Position at first data item of current key.
|
FIRST_DUP, /**< Position at first data item of current key. Only for DUPSORT */
|
||||||
Only for #MDB_DUPSORT */
|
GET_BOTH, /**< Position at key/data pair. Only for DUPSORT */
|
||||||
GET_BOTH, /**< Position at key/data pair. Only for #MDB_DUPSORT */
|
GET_BOTH_RANGE, /**< Position at key, nearest data. Only for DUPSORT */
|
||||||
GET_BOTH_RANGE, /**< position at key, nearest data. Only for #MDB_DUPSORT */
|
|
||||||
GET_CURRENT, /**< Return key/data at current cursor position */
|
GET_CURRENT, /**< Return key/data at current cursor position */
|
||||||
GET_MULTIPLE, /**< Return up to a page of duplicate data items
|
GET_MULTIPLE, /**< Return up to a page of duplicate data items from current cursor position. Only for DUPFIXED */
|
||||||
from current cursor position. Move cursor to prepare
|
|
||||||
for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */
|
|
||||||
LAST, /**< Position at last key/data item */
|
LAST, /**< Position at last key/data item */
|
||||||
LAST_DUP, /**< Position at last data item of current key.
|
LAST_DUP, /**< Position at last data item of current key. Only for DUPSORT */
|
||||||
Only for #MDB_DUPSORT */
|
|
||||||
NEXT, /**< Position at next data item */
|
NEXT, /**< Position at next data item */
|
||||||
NEXT_DUP, /**< Position at next data item of current key.
|
NEXT_DUP, /**< Position at next data item of current key. Only for DUPSORT */
|
||||||
Only for #MDB_DUPSORT */
|
NEXT_MULTIPLE, /**< Return up to a page of duplicate data items from next cursor position. Only for DUPFIXED */
|
||||||
NEXT_MULTIPLE, /**< Return up to a page of duplicate data items
|
|
||||||
from next cursor position. Move cursor to prepare
|
|
||||||
for #MDB_NEXT_MULTIPLE. Only for #MDB_DUPFIXED */
|
|
||||||
NEXT_NODUP, /**< Position at first data item of next key */
|
NEXT_NODUP, /**< Position at first data item of next key */
|
||||||
PREV, /**< Position at previous data item */
|
PREV, /**< Position at previous data item */
|
||||||
PREV_DUP, /**< Position at previous data item of current key.
|
PREV_DUP, /**< Position at previous data item of current key. Only for DUPSORT */
|
||||||
Only for #MDB_DUPSORT */
|
|
||||||
PREV_NODUP, /**< Position at last data item of previous key */
|
PREV_NODUP, /**< Position at last data item of previous key */
|
||||||
SET, /**< Position at specified key */
|
SET, /**< Position at specified key */
|
||||||
SET_KEY, /**< Position at specified key, return key + data */
|
SET_KEY, /**< Position at specified key, return key + data */
|
||||||
SET_RANGE, /**< Position at first key greater than or equal to specified key. */
|
SET_RANGE, /**< Position at first key greater than or equal to specified key */
|
||||||
PREV_MULTIPLE, /**< Position at previous page and return up to
|
PREV_MULTIPLE, /**< Position at previous page and return up to a page of duplicate data items. Only for DUPFIXED */
|
||||||
a page of duplicate data items. Only for #MDB_DUPFIXED */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Error :: enum c.int {
|
Error :: enum c.int {
|
||||||
@@ -419,33 +464,28 @@ Error :: enum c.int {
|
|||||||
BAD_VALSIZE = -30781,
|
BAD_VALSIZE = -30781,
|
||||||
/** The specified DBI was changed unexpectedly */
|
/** The specified DBI was changed unexpectedly */
|
||||||
BAD_DBI = -30780,
|
BAD_DBI = -30780,
|
||||||
|
/** Unexpected problem - txn should abort */
|
||||||
|
PROBLEM = -30779,
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Statistics for a database in the environment */
|
/** @brief Statistics for a database in the environment */
|
||||||
Stat :: struct {
|
Stat :: struct {
|
||||||
ms_psize: u32,
|
psize: u32, /**< Size of a database page. This is currently the same for all databases. */
|
||||||
/**< Size of a database page.
|
depth: u32, /**< Depth (height) of the B-tree */
|
||||||
This is currently the same for all databases. */
|
branch_pages: uint, /**< Number of internal (non-leaf) pages */
|
||||||
ms_depth: u32,
|
leaf_pages: uint, /**< Number of leaf pages */
|
||||||
/**< Depth (height) of the B-tree */
|
overflow_pages: uint, /**< Number of overflow pages */
|
||||||
ms_branch_pages: uint,
|
entries: uint, /**< Number of data items */
|
||||||
/**< Number of internal (non-leaf) pages */
|
|
||||||
ms_leaf_pages: uint,
|
|
||||||
/**< Number of leaf pages */
|
|
||||||
ms_overflow_pages: uint,
|
|
||||||
/**< Number of overflow pages */
|
|
||||||
ms_entries: uint,
|
|
||||||
/**< Number of data items */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief Information about the environment */
|
/** @brief Information about the environment */
|
||||||
Env_Info :: struct {
|
Env_Info :: struct {
|
||||||
me_mapaddr: rawptr, /**< Address of map, if fixed */
|
mapaddr: rawptr, /**< Address of map, if fixed */
|
||||||
me_mapsize: uint, /**< Size of the data memory map */
|
mapsize: uint, /**< Size of the data memory map */
|
||||||
me_last_pgno: uint, /**< ID of the last used page */
|
last_pgno: uint, /**< ID of the last used page */
|
||||||
me_last_txnid: uint, /**< ID of the last committed transaction */
|
last_txnid: uint, /**< ID of the last committed transaction */
|
||||||
me_maxreaders: u32, /**< max reader slots in the environment */
|
maxreaders: u32, /**< max reader slots in the environment */
|
||||||
me_numreaders: u32, /**< max reader slots used in the environment */
|
numreaders: u32, /**< max reader slots used in the environment */
|
||||||
}
|
}
|
||||||
|
|
||||||
/** @brief A callback function for most LMDB assert() failures,
|
/** @brief A callback function for most LMDB assert() failures,
|
||||||
@@ -454,7 +494,7 @@ Env_Info :: struct {
|
|||||||
* @param[in] env An environment handle returned by #mdb_env_create().
|
* @param[in] env An environment handle returned by #mdb_env_create().
|
||||||
* @param[in] msg The assertion message, not including newline.
|
* @param[in] msg The assertion message, not including newline.
|
||||||
*/
|
*/
|
||||||
Assert_Func :: proc "c" (_: ^Env, _: cstring)
|
Assert_Func :: #type proc "c" (_: ^Env, _: cstring)
|
||||||
|
|
||||||
/** @brief A callback function used to print a message from the library.
|
/** @brief A callback function used to print a message from the library.
|
||||||
*
|
*
|
||||||
@@ -462,7 +502,7 @@ Assert_Func :: proc "c" (_: ^Env, _: cstring)
|
|||||||
* @param[in] ctx An arbitrary context pointer for the callback.
|
* @param[in] ctx An arbitrary context pointer for the callback.
|
||||||
* @return < 0 on failure, >= 0 on success.
|
* @return < 0 on failure, >= 0 on success.
|
||||||
*/
|
*/
|
||||||
Msg_Func :: proc "c" (_: cstring, _: rawptr) -> i32
|
Msg_Func :: #type proc "c" (_: cstring, _: rawptr) -> i32
|
||||||
|
|
||||||
@(default_calling_convention = "c", link_prefix = "mdb_")
|
@(default_calling_convention = "c", link_prefix = "mdb_")
|
||||||
foreign lib {
|
foreign lib {
|
||||||
@@ -623,7 +663,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
env_open :: proc(env: ^Env, path: cstring, flags: u32, mode: mode_t) -> Error ---
|
env_open :: proc(env: ^Env, path: cstring, flags: Env_Flags, mode: mode_t) -> Error ---
|
||||||
|
|
||||||
/** @brief Copy an LMDB environment to the specified path.
|
/** @brief Copy an LMDB environment to the specified path.
|
||||||
*
|
*
|
||||||
@@ -682,7 +722,7 @@ foreign lib {
|
|||||||
* @return A non-zero error value on failure and 0 on success.
|
* @return A non-zero error value on failure and 0 on success.
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
env_copy2 :: proc(env: ^Env, path: cstring, flags: u32) -> Error ---
|
env_copy2 :: proc(env: ^Env, path: cstring, flags: Copy_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Copy an LMDB environment to the specified file descriptor,
|
/** @brief Copy an LMDB environment to the specified file descriptor,
|
||||||
* with options.
|
* with options.
|
||||||
@@ -702,7 +742,7 @@ foreign lib {
|
|||||||
* @return A non-zero error value on failure and 0 on success.
|
* @return A non-zero error value on failure and 0 on success.
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
env_copyfd2 :: proc(env: ^Env, fd: filehandle_t, flags: u32) -> Error ---
|
env_copyfd2 :: proc(env: ^Env, fd: filehandle_t, flags: Copy_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Return statistics about the LMDB environment.
|
/** @brief Return statistics about the LMDB environment.
|
||||||
*
|
*
|
||||||
@@ -767,7 +807,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
env_set_flags :: proc(env: ^Env, flags: u32, onoff: i32) -> Error ---
|
env_set_flags :: proc(env: ^Env, flags: Env_Flags, onoff: i32) -> Error ---
|
||||||
|
|
||||||
/** @brief Get environment flags.
|
/** @brief Get environment flags.
|
||||||
*
|
*
|
||||||
@@ -780,7 +820,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
env_get_flags :: proc(env: ^Env, flags: ^u32) -> Error ---
|
env_get_flags :: proc(env: ^Env, flags: ^Env_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Return the path that was used in #mdb_env_open().
|
/** @brief Return the path that was used in #mdb_env_open().
|
||||||
*
|
*
|
||||||
@@ -973,7 +1013,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
txn_begin :: proc(env: ^Env, parent: ^Txn, flags: u32, txn: ^^Txn) -> Error ---
|
txn_begin :: proc(env: ^Env, parent: ^Txn, flags: Env_Flags, txn: ^^Txn) -> Error ---
|
||||||
|
|
||||||
/** @brief Returns the transaction's #MDB_env
|
/** @brief Returns the transaction's #MDB_env
|
||||||
*
|
*
|
||||||
@@ -1126,7 +1166,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
dbi_open :: proc(txn: ^Txn, name: cstring, flags: u32, dbi: ^Dbi) -> Error ---
|
dbi_open :: proc(txn: ^Txn, name: cstring, flags: Db_Flags, dbi: ^Dbi) -> Error ---
|
||||||
|
|
||||||
/** @brief Retrieve statistics for a database.
|
/** @brief Retrieve statistics for a database.
|
||||||
*
|
*
|
||||||
@@ -1151,7 +1191,7 @@ foreign lib {
|
|||||||
* @return A non-zero error value on failure and 0 on success.
|
* @return A non-zero error value on failure and 0 on success.
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
dbi_flags :: proc(txn: ^Txn, dbi: Dbi, flags: ^u32) -> Error ---
|
dbi_flags :: proc(txn: ^Txn, dbi: Dbi, flags: ^Db_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Close a database handle. Normally unnecessary. Use with care:
|
/** @brief Close a database handle. Normally unnecessary. Use with care:
|
||||||
*
|
*
|
||||||
@@ -1229,6 +1269,7 @@ foreign lib {
|
|||||||
@(require_results)
|
@(require_results)
|
||||||
set_dupsort :: proc(txn: ^Txn, dbi: Dbi, cmp: Cmp_Func) -> Error ---
|
set_dupsort :: proc(txn: ^Txn, dbi: Dbi, cmp: Cmp_Func) -> Error ---
|
||||||
|
|
||||||
|
// NOTE: Unimplemented in current LMDB — this function has no effect.
|
||||||
/** @brief Set a relocation function for a #MDB_FIXEDMAP database.
|
/** @brief Set a relocation function for a #MDB_FIXEDMAP database.
|
||||||
*
|
*
|
||||||
* @todo The relocation function is called whenever it is necessary to move the data
|
* @todo The relocation function is called whenever it is necessary to move the data
|
||||||
@@ -1250,6 +1291,7 @@ foreign lib {
|
|||||||
@(require_results)
|
@(require_results)
|
||||||
set_relfunc :: proc(txn: ^Txn, dbi: Dbi, rel: Rel_Func) -> Error ---
|
set_relfunc :: proc(txn: ^Txn, dbi: Dbi, rel: Rel_Func) -> Error ---
|
||||||
|
|
||||||
|
// NOTE: Unimplemented in current LMDB — this function has no effect.
|
||||||
/** @brief Set a context pointer for a #MDB_FIXEDMAP database's relocation function.
|
/** @brief Set a context pointer for a #MDB_FIXEDMAP database's relocation function.
|
||||||
*
|
*
|
||||||
* See #mdb_set_relfunc and #MDB_rel_func for more details.
|
* See #mdb_set_relfunc and #MDB_rel_func for more details.
|
||||||
@@ -1344,7 +1386,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
put :: proc(txn: ^Txn, dbi: Dbi, key: ^Val, data: ^Val, flags: u32) -> Error ---
|
put :: proc(txn: ^Txn, dbi: Dbi, key: ^Val, data: ^Val, flags: Write_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Delete items from a database.
|
/** @brief Delete items from a database.
|
||||||
*
|
*
|
||||||
@@ -1517,7 +1559,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
cursor_put :: proc(cursor: ^Cursor, key: ^Val, data: ^Val, flags: u32) -> Error ---
|
cursor_put :: proc(cursor: ^Cursor, key: ^Val, data: ^Val, flags: Write_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Delete current key/data pair
|
/** @brief Delete current key/data pair
|
||||||
*
|
*
|
||||||
@@ -1541,7 +1583,7 @@ foreign lib {
|
|||||||
* </ul>
|
* </ul>
|
||||||
*/
|
*/
|
||||||
@(require_results)
|
@(require_results)
|
||||||
cursor_del :: proc(cursor: ^Cursor, flags: u32) -> Error ---
|
cursor_del :: proc(cursor: ^Cursor, flags: Write_Flags) -> Error ---
|
||||||
|
|
||||||
/** @brief Return count of duplicates for current key.
|
/** @brief Return count of duplicates for current key.
|
||||||
*
|
*
|
||||||
|
|||||||
Reference in New Issue
Block a user