Programming in C¶
Contents
Symbolic Constants¶
The libyottadb.h
file defines several symbolic constants, which are
one of the following types:
Function Return Codes, which in turn are one of:
Normal Return Codes
Error Return Codes
Limits
Other
Symbolic constants all fit within the range of a C int
.
Function Return Codes¶
Return codes from calls to YottaDB are usually of type int
and
occasionally other types. Normal return codes are non-negative
(greater than or equal to zero); error return codes are negative.
Normal Return Codes¶
Symbolic constants for normal return codes have YDB_
prefixes
other than YDB_ERR_
.
YDB_LOCK_TIMEOUT
— This return code from lock acquisition
functions indicates that the specified timeout was reached without
the requested locks being acquired.
YDB_OK
— This the standard return code of all functions following
successful execution.
YDB_TP_RESTART
— Return code to YottaDB from an application
function that implements a transaction to indicate that it wishes
YottaDB to restart the transaction, or by a YottaDB function invoked
within a transaction to its caller that the database engine has
detected that it will be unable to commit the transaction and will
need to restart. Application code designed to be executed within a
transaction should be written to recognize this return code and in
turn perform any cleanup required and return to the YottaDB
ydb_tp_s() / ydb_tp_st() invocation from which it was called. See
Transaction Processing for a discussion of restarts.
YDB_TP_ROLLBACK
— Return code to YottaDB from an application
function that implements a transaction, and in turn returned to the
caller indicating that the transaction was not committed.
Error Return Codes¶
Symbolic constants for error codes returned by calls to YottaDB are
prefixed with YDB_ERR_
and are all less than zero. The
symbolic constants below are not a complete list of all error messages
that YottaDB functions can return — error return codes can indicate
system errors and database errors, not just application errors. A
process that receives a negative return code, including one not listed
here, can call ydb_get_s() / ydb_get_st() to get the value of
$zstatus.
Error messages can be raised by the YottaDB runtime system or by the underlying operating system.
A full set of YottaDB error messages and numbers is in the YottaDB Messages and Recovery Procedures Manual.
Linux error messages are described in Linux documentation, e.g. errno.
Remember that the error codes returned by YottaDB functions are the negated numeric values of the error codes above.
YDB_ERR_CALLINAFTERXIT
– A YottaDB function was called after
ydb_exit()
was called.
YDB_ERR_FATALERROR1
– A fatal error occurred. The process is
generating a core dump and terminating. As a process cannot receive a
fatal error code, this error appears in the syslog.
YDB_ERR_FATALERROR2
– A fatal error occurred. The process is
terminating without generating a core dump. As a process cannot
receive a fatal error code, this error appears in the syslog.
YDB_ERR_GVUNDEF
— No value exists at a requested global variable
node.
YDB_ERR_INVNAMECOUNT
– A namecount
parameter has an invalid
value.
YDB_ERR_INSUFFSUBS
— A call to ydb_node_next_s() /
ydb_node_next_st() or ydb_node_previous_s() /
ydb_node_previous_st() did not provide enough parameters for the
return values. Note that as the number of parameters is a count, when
array subscripts start at 0, an array subscript of n corresponds to
n+1 parameters.
YDB_ERR_INVSTRLEN
— A buffer provided by the caller is not long
enough for a string to be returned, or the length of a string passed
as a parameter exceeds YDB_MAX_STR
. In the event the return code
is YDB_ERR_INVSTRLEN
and if *xyz
is a ydb_buffer_t
structure whose xyz->len_alloc
indicates insufficient space, then
xyz->len_used
is set to the size required of a sufficiently large
buffer. In this case the len_used
field of a ydb_buffer_t
structure is greater than the len_alloc
field, and the caller is
responsible for correcting the xyz->len_used
field.
YDB_ERR_INVSVN
— A special variable name provided by the caller
is invalid.
YDB_ERR_INVVARNAME
— A variable name provided by the caller is
invalid.
YDB_ERR_KEY2BIG
— The length of a global variable name and
subscripts exceeds the limit configured for the database region to
which it is mapped.
YDB_ERR_LVUNDEF
— No value exists at a requested local variable
node.
YDB_ERR_MAXNRSUBSCRIPTS
— The number of subscripts specified in
the call exceeds YDB_MAX_SUBS
.
YDB_ERR_MINNRSUBSCRIPTS
– The number of subscripts cannot be
negative.
YDB_ERR_NAMECOUNT2HI
– The number of variable names specified
to ydb_delete_excl_s() / ydb_delete_excl_st() or ydb_tp_s() /
ydb_tp_st() exceeded the YDB_MAX_NAMES
.
YDB_ERR_NODEEND
— In the event a call to ydb_node_next_s() /
ydb_node_next_st(), ydb_node_previous_s() /
ydb_node_previous_st(), ydb_subscript_next_s() /
ydb_subscript_next_st(), or ydb_subscript_previous_s() /
ydb_subscript_previous_st() wish to report that there no further
nodes/subscripts in their traversals, they return this value.
YDB_NOTOK
– ydb_file_name_to_id() was called with a NULL
pointer to a filename.
YDB_ERR_NUMOFLOW
— A ydb_incr_s() / ydb_incr_st() operation
resulted in a numeric overflow.
YDB_ERR_PARAMINVALID
— A parameter provided by the caller is
invalid.
YDB_ERR_SIMPLEAPINEST
– An attempt was made to nest Simple API
calls, which cannot be nested.
YDB_ERR_SUBSARRAYNULL
– The subs_used
parameter of a function
is greater than zero, but the subsarray
parameter is a NULL
pointer.
YDB_ERR_SVNOSET
— the application inappropriately attempted to
modify the value of an intrinsic special variable such as an attempt
to modify $trestart
using ydb_set_s() / ydb_set_st().
YDB_ERR_TIME2LONG
– This return code indicates that a value
greater than YDB_MAX_TIME_NSEC
was specified for a time duration.
YDB_ERR_TPTIMEOUT
— This return code from ydb_tp_s() /
ydb_tp_st() indicates that the transaction took too long to commit.
YDB_ERR_UNIMPLOP
— An operation that is not supported for an
intrinsic special variable – of the Simple API functions only
ydb_get_s() / ydb_get_st() and ydb_set_s() / ydb_set_st() are
supported – was attempted on an intrinsic special variable.
YDB_ERR_VARNAME2LONG
– A variable name length exceeds YottaDB’s
limit.
Limits¶
Symbolic constants for limits are prefixed with YDB_MAX_
or
YDB_MIN_
.
YDB_MAX_IDENT
— The maximum space in bytes required to store a
complete variable name, not including the preceding caret for a global
variable. Therefore, when allocating space for a string to hold a
global variable name, add 1 for the caret.
YDB_MAX_NAMES
– The maximum number of variable names that can
be passed to ydb_delete_excl_s() / ydb_delete_excl_st() or
ydb_tp_s() / ydb_tp_st().
YDB_MAX_STR
— The maximum length of a string (or blob) in
bytes. A caller to ydb_get_s() / ydb_get_st() whose
*ret_value
parameter provides a buffer of YDB_MAX_STR
will never get a YDB_ERR_INVSTRLEN
error.
YDB_MAX_SUBS
— The maximum number of subscripts for a local or
global variable.
YDB_MAX_TIME_NSEC
— The maximum value in nanoseconds that an
application can instruct libyottab to wait, e.g., until the process is
able to acquire locks it needs before timing out, or for
ydb_hiber_start(). Note that even if timer resolution is in
nanoseconds, the accuracy is always determined by the underlying
hardware and operating system, as well as factors such as system load.
YDB_MAX_YDBERR
– The absolute (positive) value of any YottaDB
function error return code. If the absolute value of an error return
code is greater than YDB_MAX_YDBERR
, then it is an error code
from elsewhere, e.g. errno. Also, see YDB_IS_YDBERR()
.
YDB_MIN_YDBERR
- The absolute (positive) value of any YottaDB
function error return code. If the absolute value of an error return
code is less than YDB_MIN_YDBERR
, then it is an error code
from elsewhere, e.g. errno. Also, see YDB_IS_YDBERR()
.
Severity¶
Symbolic constants for the severities of message numbers in return
codes and $zstatus
are prefixed with YDB_SEVERITY_
.
YDB_SEVERITY_ERROR
– The number corresponds to an error from which the
process can recover.
YDB_SEVERITY_FATAL
– The number corresponds to an error that terminated
the process.
YDB_SEVERITY_INFORMATIONAL
– The number corresponds to an informational
message.
YDB_SEVERITY_SUCCESS
– The number corresponds to the successful
completion of a requested operation.
YDB_SEVERITY_WARNING
– The number corresponds to a warning, i.e.,
it indicates a possible problem.
Other¶
Other symbolic constants have a prefix of YDB_
.
YDB_DEL_NODE
and YDB_DEL_TREE
— As values of the
deltype
parameter, these values indicate to ydb_delete_s() /
ydb_delete_st() whether to delete an entire subtree or just the node
at the root, leaving the subtree intact.
YDB_NOTTP
– As a value of the tptoken
parameter of the
Simple API multi-threaded functions – those ending in
_st()
, indicates that the caller is not within a
transaction.
Data Structures & Type Definitions¶
ydb_buffer_t
is a descriptor for a string 1 value, and consists of
the following fields:
buf_addr
— pointer to anunsigned char
, the starting address of a string.len_alloc
andlen_used
— fields of typeunsigned int
where:len_alloc
is the number of bytes allocated to store the string,len_used
is the length in bytes of the currently stored string, andlen_alloc
≥len_used
except when a YDB_ERR_INVSTRLEN occurs.
- 1
Strings in YottaDB are arbitrary sequences of bytes that are not null-terminated. Other languages may refer to them as binary data or blobs.
ydb_string_t
is a descriptor for a string provided for
compatibility with existing code, and consists of the following
fields:
address
— pointer to anunsigned char
, the starting address of a string.length
— the length of the string starting at theaddress
field.
ydb_tpfnptr_t
is a pointer to a function which returns an
integer, with one parameter, a pointer to an arbitrary structure:
typedef int (*ydb_tpfnptr_t)(void *tpfnparm);
ydb_tp2fnptr_t
is a pointer to a function which returns an
integer, with three parameters, a tptoken
, a *errstr
pointer, and a pointer to an arbitrary structure:
typedef int (*ydb_tp2fnptr_t)(uint64_t tptoken,
ydb_buffer_t *errstr, void *tpfnparm)
Functions to implement transaction processing logic for
single-threaded applications are referenced by ydb_tpfnptr_t
and functions to implement transaction processing logic for
multi-threaded applications are referenced by ydb_tp2fnptr_t
.
Macros¶
YDB_ASSERT(x)
– Conditionally include this macro in code for
debugging and testing purposes. If x
is non-zero, it prints an
error message on stderr
and generates a core file by calling
ydb_fork_n_core().
YDB_BUFFER_IS_SAME(buffer1, buffer2)
– Use this macro to test
whether the memory locations (strings) pointed to by two
ydb_buffer_t
structures have the same content, returning FALSE
(0) if they differ and a non-zero value if the contents are identical.
YDB_COPY_BUFFER_TO_BUFFER(source, destination, done)
– Use this
macro to copy the memory locations (strings) pointed to by source
to the memory locations pointed to by destination
and set:
destination->len_used
tosource->len_used
; anddone
toTRUE
ifdestination->len_alloc
≥source->len_used
and the underlyingmemcpy()
completed successfully, andFALSE
otherwise.
YDB_COPY_LITERAL_TO_BUFFER(literal, buffer, done)
- Use this macro
to copy a literal string to previously allocated memory referenced by
a ydb_buffer_t
structure (for example, to set an initial subscript
to sequence through nodes). It sets:
buffer->len_used
to the size of the literal; anddone
toTRUE
ifbuffer->len_alloc
≥ the size of the literal excluding its terminating null byte and the underlyingmemcpy()
completed successfully, andFALSE
otherwise.
YDB_COPY_STRING_TO_BUFFER(string, buffer, done)
– Use this
macro to copy a null-terminated string to previously allocated memory
referenced by a ydb_buffer_t
structure. This macro requires
the code to also #include <string.h>
. It sets:
buffer->len_used
to the size of the copied string; anddone
toTRUE
ifbuffer->len_alloc
≥ the size of the string to be copied and the underlyingmemcpy()
completed successfully, andFALSE
otherwise.
YDB_FREE_BUFFER(BUFFERP)
- Use this macro to free the buffer malloced using YDB_MALLOC_BUFFER
.
free() call is used on
BUFFERP->buf_addr
.
YDB_LITERAL_TO_BUFFER(literal, buffer)
– Use this macro to set
a ydb_buffer_t
structure to refer to a literal (such as a
variable name). With a string literal, and
a pointer to a ydb_buffer_t
structure,
set:
buffer->buf_addr
to the address ofliteral
; andbuffer->len_used
andbuffer->len_alloc
to the length ofliteral
excluding the terminating null byte.
YDB_IS_YDBERR(msgnum)
– returns TRUE if the absolute value of
msgnum
lies between YDB_MIN_YDBERR
and
YDB_MAX_YDBERR
.
YDB_MALLOC_BUFFER(BUFFERP,LEN)
- Use this macro to to allocate a buffer using malloc()
of length LEN and assign it to an already allocated ydb_buffer_t
structure.
BUFFERP->buf_addr
is set to the malloced buffer.BUFFERP->len_alloc
is set to the malloced length.BUFFERP->len_used
is set to 0.
YDB_SEVERITY(msgnum, severity)
– The error return code from a
function indicates both the nature of an error as well as its
severity. For message msgnum
, the variable severity
is set to
one of the YDB_SEVERITY_*
symbolic
constants. YDB_SEVERITY()
is only meaningful for error return
codes and not other numbers. Use YDB_IS_YDBERR()
to
determine whether a return code is a YottaDB error return code.
HASH128_STATE_INIT(hash128_state_t *state, ydb_uint8 addl_seed)
- Use this macro to initialize a variable in order to compute a 128-bit MurMurHash using ydb_mmrhash_128_ingest().
Example:
// Initialize state struct
HASH128_STATE_INIT(hash_state, 0);
YottaDB functions are divided into:
Simple API — a core set of functions that provides easy-to-use access to the major features of YottaDB.
Comprehensive API — a more elaborate set of functions for specialized or optimized access to additional functionality within
libyottadb.so
that YottaDB itself uses. The Comprehensive API is a project for the future.Utility Functions — Functions useful to a C application using YottaDB.
YDB_STRING_TO_BUFFER
— Sets a ydb_buffer_t
structure
to point to an existing null-terminated C string, i.e.,
#define YDB_STRING_TO_BUFFER(STRING, BUFFERP) \
{ \
(BUFFERP)->buf_addr = STRING; \
(BUFFERP)->len_used = (BUFFERP)->len_alloc = strlen(STRING); \
}
Simple API¶
As all subscripts and node data passed to YottaDB using the Simple API
are strings, use the sprintf()
and atoi()/strtoul()
family of
functions to convert between numeric values and strings which are
canonical numbers.
Note that all parameters passed to Simple API functions must be properly allocated and initialized where needed prior to the function call, including return values. This also specifically includes all members of ydb_buffer_t structs for parameters containing input values, but only buf_addr and len_alloc members for return values. To facilitate initialization of the ydb_buffer_t members, you may find the YDB_MALLOC_BUFFER macro helpful for heap allocations.
To allow the YottaDB Simple API functions to handle a variable tree whose nodes have varying numbers of subscripts, the actual number of subscripts is itself passed as a parameter. In the prototypes of functions, parameters of the form:
ydb_buffer_t *varname
refers to the name of a variable;int subs_used
andint *subs_used
refer to an actual number of subscripts; andydb_buffer_t *subsarray
refers to an array ofydb_buffer_t
structures used to pass subscripts whose actual number is defined bysubs_used
or*subs_used
parameters.
To pass an intrinsic special variable, or unsubscripted local or
global variable, subs_used
should be zero and *subsarray
should be NULL.
Caveat: Specifying a subs_used
that exceeds the actual number
of parameters passed in *subsarray
will almost certainly result in
an unpleasant bug that is difficult to troubleshoot.
Functions specific to the YottaDB Simple API for single-threaded
applications end in _s()
and those for multi-threaded
applications end in _st()
, with the latter functions typically
differing from their counterparts of the former type with two
additional parameters, tptoken
, and errstr
. The
discussion in Threads provides more detailed information.
ydb_data_s() / ydb_data_st()¶
int ydb_data_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
unsigned int *ret_value);
int ydb_data_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
unsigned int *ret_value);
In the location pointed to by ret_value
, ydb_data_s()
and ydb_data_st()
return the
following information about the local or global variable node
identified by *varname
, subs_used
and *subsarray
.
0 — There is neither a value nor a subtree, i.e., it is undefined.
1 — There is a value, but no subtree
10 — There is no value, but there is a subtree.
11 — There are both a value and a subtree.
It is an error to call ydb_data_s()
or ydb_data_st()
on an intrinsic special variable; doing so results in the
YDB_ERR_UNIMPLOP
error. ydb_data_s() / ydb_data_st()
returns:
YDB_OK
; or
The error YDB_ERR_PARAMINVALID
is returned when
ret_value
is NULLlen_alloc
<len_used
or thelen_used
is non-zero andbuf_addr
is NULL in at least one subscript, insubsarray
.
Please see the Simple API introduction for details about parameter allocation.
ydb_delete_s() / ydb_delete_st()¶
int ydb_delete_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
int deltype);
int ydb_delete_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
int deltype);
Delete nodes in the local or global variable tree or subtree
specified. A value of YDB_DEL_NODE
or YDB_DEL_TREE
for
deltype
specifies whether to delete just the node at the root,
leaving the (sub)tree intact, or to delete the node as well as the
(sub)tree.
Intrinsic special variables cannot be deleted.
ydb_delete_s()
and ydb_delete_st()
return YDB_OK
, a YDB_ERR_UNIMPLOP
if
deltype
is neither YDB_DEL_NODE
nor YDB_DEL_TREE
, YDB_ERR_PARAMINVALID
is returned when
len_alloc
< len_used
or the len_used
is non-zero
and buf_addr
is NULL in at least one subscript in subsarray
,
or another error return code.
YDB_OK
;YDB_ERR_UNIMPLOP
ifdeltype
is neitherYDB_DEL_NODE
norYDB_DEL_TREE
; oranother error return code.
Please see the Simple API introduction for details about parameter allocation.
ydb_delete_excl_s() / ydb_delete_excl_st()¶
int ydb_delete_excl_s(int namecount,
ydb_buffer_t *varnames);
int ydb_delete_excl_st(uint64_t tptoken,
ydb_buffer_t *errstr,
int namecount, ydb_buffer_t *varnames);
ydb_delete_excl_s()
and ydb_delete_excl_st()
delete
the trees of all local variables except those in the *varnames
array. It is an error for *varnames
to include a global or
intrinsic special variable.
In the special case where namecount
is zero,
ydb_delete_excl_s()
and ydb_delete_excl_st()
delete
all local variables.
If your application mixes M and non M code, and you wish to use
ydb_delete_excl_s()
to delete local variables that are aliases,
formal parameters, or actual parameters passed by reference, make sure
you understand what (sub)trees are being deleted. This warning does
not apply to applications that do not include M code.
ydb_delete_excl_s()
and ydb_delete_excl_st()`return :CODE:`YDB_OK
,
YDB_ERR_NAMECOUNT2HI
if more
than YDB_MAX_NAMES
are specified, or another error return
code. YDB_ERR_PARAMINVALID
is returned when len_alloc
< len_used
or the len_used
is non-zero
and buf_addr
is NULL in at least one variable name in “code:varnames.
Note that specifying a larger value for namecount
than the
number of variable names actually provided in *varnames
can result in a buffer overflow.
Please see the Simple API introduction for details about parameter allocation.
ydb_get_s() / ydb_get_st()¶
int ydb_get_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *ret_value);
int ydb_get_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *ret_value);
To the user-allocated location pointed to by ret_value->buf_addr
,
ydb_get_s()
and ydb_get_st()
copy the value of the
specified node or intrinsic special variable, setting
ret_value->len_used
on both normal and error returns (the
latter case as long as the data exists). Return values are:
YDB_OK
for a normal return;YDB_ERR_GVUNDEF
,YDB_ERR_INVSVN
, orYDB_ERR_LVUNDEF
as appropriate if no such variable or node exists;YDB_ERR_INVSTRLEN
ifret_value->len_alloc
is insufficient for the value at the node;YDB_ERR_PARAMINVALID
whenret_value
is NULL orret_value->buf_addr
is NULL and the return value has a non-zerolen_used
; orlen_alloc
<len_used
or thelen_used
is non-zero andbuf_addr
is NULL in at least one subscript insubsarray
; oranother applicable error return code.
Notes:
In the unlikely event an application wishes to know the length of the value at a node, but not access the data, it can call
ydb_get_s()
orydb_get_st()
and provide an output buffer (retvalue->len_alloc
) with a length of zero, since even in the case of aYDB_ERR_INVSTRLEN
error,retvalue->len_used
is set.Within a transaction implemented by ydb_tp_s() / ydb_tp_st() application code observes stable data at global variable nodes because YottaDB transaction processing ensures ACID properties, restarting the transaction if a value changes.
Outside a transaction, a global variable node can potentially be changed by another, concurrent, process between the time that a process calls ydb_data_s() / ydb_data_st() to ascertain the existence of the data and a subsequent call to ydb_get_s() / ydb_get_st() to get that data. A caller of ydb_get_s() / ydb_get_st() to access a global variable node should code in anticipation of a potential
YDB_ERR_GVUNDEF
, unless it is known from application design that this cannot happen.
Please see the Simple API introduction for details about parameter allocation.
ydb_incr_s() / ydb_incr_st()¶
int ydb_incr_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *increment,
ydb_buffer_t *ret_value);
int ydb_incr_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *increment,
ydb_buffer_t *ret_value);
ydb_incr_s()
and ydb_incr_st()
atomically:
convert the value in the specified node to a number if it is not one already, using a zero value if the node does not exist;
increment it by the value specified by
*increment
, converting the value to a number if it is not a canonical number, defaulting to 1 if the parameter is NULL; andstore the value as a canonical number in
*ret_value
.
Return values:
The normal return value is
YDB_OK
.If the atomic increment results in a numeric overflow, the function returns a
YDB_ERR_NUMOFLOW
error; in this case, the value in the node is untouched and that in*ret_value
is unreliable.YDB_ERR_INVSTRLEN
ifret_value->len_alloc
is insufficient for the result. As with ydb_get_s() / ydb_get_st(), in this caseret_value->len_used
is set to the required length.Other errors return the corresponding error return code.
Notes:
Intrinsic special variables cannot be atomically incremented, and an attempt to do so returns the
YDB_ERR_UNIMPLOP
error.The value of the empty string coerced to a numeric value is 0.
Please see the Simple API introduction for details about parameter allocation.
ydb_lock_s() / ydb_lock_st()¶
int ydb_lock_s(unsigned long long timeout_nsec,
int namecount[,
[ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray], ...]);
int ydb_lock_st(uint64_t tptoken,
ydb_buffer_t *errstr,
unsigned long long timeout_nsec,
int namecount[,
[ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray], ...]);
namecount
is the number of variable names in the call.
Release any locks held by the process, and attempt to acquire all the
requested locks. Except in the case of an error, the release is
unconditional. On return, the function will have acquired all
requested locks or none of them. If no locks are requested
(namecount
is zero), the function releases all locks and
returns YDB_OK
.
timeout_nsec
specifies a time in nanoseconds that the function
waits to acquire the requested locks. If timeout_nsec
is zero,
the function makes exactly one attempt to acquire the locks
Return values:
If all requested locks are successfully acquired, the function returns
YDB_OK
.If it is not able to acquire all requested locks in the specified time, it acquires no locks, returning with a
YDB_LOCK_TIMEOUT
return value.If the requested
timeout_nsec
exceedsYDB_MAX_TIME_NSEC
, the function immediately returnsYDB_ERR_TIME2LONG
.YDB_ERR_PARAMINVALID
is returned when len_alloc
< len_used
or the len_used
is non-zero
and buf_addr
is NULL in at least one subscript in subsarray
.
- In other cases, the function returns an error return code.
Please see the Simple API introduction for details about parameter allocation.
ydb_lock_decr_s() / ydb_lock_decr_st()¶
int ydb_lock_decr_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray);
int ydb_lock_decr_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray);
Decrements the count of the specified lock held by the process. As noted in the Concepts section, a lock whose count goes from 1 to 0 is released. A lock whose name is specified, but which the process does not hold, is ignored.
As releasing a lock cannot fail, the function returns YDB_OK
,
unless there is an error such as an invalid name that results in the
return of an error code such as YDB_ERR_INVVARNAME
. Errors
result in an appropriate error return code. YDB_ERR_PARAMINVALID
is returned when len_alloc
< len_used
or the len_used
is non-zero
and buf_addr
is NULL in at least one subscript in subsarray
.
Please see the Simple API introduction for details about parameter allocation.
ydb_lock_incr_s() / ydb_lock_incr_st()¶
int ydb_lock_incr_s(unsigned long long timeout_nsec,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray);
int ydb_lock_incr_st(uint64_t tptoken,
ydb_buffer_t *errstr,
unsigned long long timeout_nsec,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray);
Without releasing any locks held by the process, attempt to acquire the requested lock incrementing it if already held.
timeout_nsec
specifies a time in nanoseconds that the function
waits to acquire the requested locks. If timeout_nsec
is zero,
the function makes exactly one attempt to acquire the locks
Return values:
If all requested locks are successfully acquired, the function returns
YDB_OK
.If it is not able to acquire all requested locks in the specified time, it acquires no locks, returning with a
YDB_LOCK_TIMEOUT
return value.If the requested
timeout_nsec
exceedsYDB_MAX_TIME_NSEC
, the function immediately returnsYDB_ERR_TIME2LONG
.YDB_ERR_PARAMINVALID
is returned when len_alloc
< len_used
or the len_used
is non-zero
and buf_addr
is NULL in at least one subscript in subsarray
.
- In other cases, the function returns an error return code.
Please see the Simple API introduction for details about parameter allocation.
ydb_node_next_s() / ydb_node_next_st()¶
int ydb_node_next_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
int *ret_subs_used,
ydb_buffer_t *ret_subsarray);
int ydb_node_next_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
int *ret_subs_used,
ydb_buffer_t *ret_subsarray);
ydb_node_next_s()
and ydb_node_next_st()
facilitate
depth-first traversal of a local or global variable tree. As the
number of subscripts can differ between the input node of the call and
the output node reported by the call *ret_subs_used
is an
input as well as an output parameter:
On input,
*ret_subs_used
specifies the number of elements allocated for returning the subscripts of the next node.On normal output (
YDB_OK
return code),*ret_subs_used
contains the actual number of subscripts returned. See below for error return codes
Return values of ydb_node_next_s()
and
ydb_node_next_st()
are:
YDB_OK
with the next node, if there is one, changing*ret_subs_used
and*ret_subsarray
parameters to those of the next node. If there is no next node (i.e., the input node is the last),*ret_subs_used
on output isYDB_NODE_END
.YDB_ERR_INSUFFSUBS
if*ret_subs_used
specifies insufficient parameters to return the subscript. In this case*ret_subs_used
reports the actual number of subscripts required.YDB_ERR_INVSTRLEN
if one of theydb_buffer_t
structures pointed to by*ret_subsarray
does not have enough space for the subscript. In this case,*ret_subs_used
is the index into the*ret_subsarray
array with the error, and thelen_used
field of that structure specifies the size required.YDB_ERR_NODEEND
to indicate that that there are no more nodes. In this case,*ret_subs_used
is unchanged.YDB_ERR_PARAMINVALID
ifret_subs_used
is NULL orret_subsarray
is NULL or one of theydb_buffer_t
structures pointed to by*ret_subsarray
has a NULL buf_addr. In the last case,*ret_subs_used
is the index into the*ret_subsarray
array with the NULL buf_addr.Another error return code, in which case the application should consider the values of
*ret_subs_used
and the*ret_subsarray
to be undefined.
Please see the Simple API introduction for details about parameter allocation.
ydb_node_previous_s() / ydb_node_previous_st()¶
int ydb_node_previous_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
int *ret_subs_used,
ydb_buffer_t *ret_subsarray);
int ydb_node_previous_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
int *ret_subs_used,
ydb_buffer_t *ret_subsarray);
Analogous to ydb_node_next_s() / ydb_node_next_st(),
ydb_node_previous_s()
and ydb_node_previous_st()
facilitate reverse depth-first traversal of a local or global
variable tree, except that ydb_node_previous_s()
and
ydb_node_previous_st()
search for and report the predecessor
node. Unlike ydb_node_next_s() / ydb_node_next_st(),
*ret_subs_used
can be zero if the previous node is the
unsubscripted root.
Return values of ydb_node_previous_s()
and
ydb_node_previous_st()
are:
YDB_OK
with the previous node, if there is one, changing*ret_subs_used
and*ret_subsarray
parameters to those of the previous node.YDB_ERR_INSUFFSUBS
if*ret_subs_used
specifies insufficient parameters to return the subscript. In this case*ret_subs_used
reports the actual number of subscripts required.YDB_ERR_INVSTRLEN
if one of theydb_buffer_t
structures pointed to by*ret_subsarray
does not have enough space for the subscript. In this case,*ret_subs_used
is the index into the*ret_subsarray
array with the error, and thelen_used
field of that structure specifies the size required.YDB_ERR_NODEEND
to indicate that that there are no more nodes. In this case,*ret_subs_used
is unchanged.YDB_ERR_PARAMINVALID
ifret_subs_used
is NULL orret_subsarray
is NULL or one of theydb_buffer_t
structures pointed to by*ret_subsarray
has a NULL buf_addr. In the last case,*ret_subs_used
is the index into the*ret_subsarray
array with the NULL buf_addr.Another error return code, in which case the application should consider the values of
*ret_subs_used
and the*ret_subsarray
to be undefined.
Please see the Simple API introduction for details about parameter allocation.
ydb_set_s() / ydb_set_st()¶
int ydb_set_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *value);
int ydb_set_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *value);
ydb_set_s()
and ydb_set_st()
copy the
value->len_used
bytes at value->buf_addr
as the value
of the specified node or intrinsic special variable specified. A NULL
value
parameter is treated as equivalent to one that points to
a ydb_buffer_t
specifying an empty string. Return values are:
YDB_OK
for a normal return;YDB_ERR_INVSVN
if no such intrinsic special variable exists;YDB_ERR_PARAMINVALID
whenlen_alloc
<len_used
or thelen_used
is non-zero andbuf_addr
is NULL in at least one subscript insubsarray
orincrement
; oranother applicable error return code.
Please see the Simple API introduction for details about parameter allocation.
ydb_str2zwr_s() / ydb_str2zwr_st()¶
int ydb_str2zwr_s(ydb_buffer_t *str, ydb_buffer_t *zwr);
int ydb_str2zwr_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *str, ydb_buffer_t *zwr);
In the buffer referenced by *zwr
, ydb_str2zwr_s()
and
ydb_str2zwr_st()
provide the zwrite formatted version of
the string pointed to by *str
, returning:
YDB_OK
;YDB_ERR_INVSTRLEN
if the*zwr
buffer is not long enough;YDB_ERR_PARAMINVALID
ifzwr
is NULL orzwr->buf_addr
is NULL and the return value has a non-zerolen_used
; oranother applicable error return code.
Please see the Simple API introduction for details about parameter allocation.
ydb_subscript_next_s() / ydb_subscript_next_st()¶
int ydb_subscript_next_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *ret_value);
int ydb_subscript_next_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *ret_value);
ydb_subscript_next_s()
and ydb_subscript_next_st()
provide a primitive for implementing breadth-first traversal of a tree
by searching for the next subscript at the level specified by
subs_used
, i.e., the next subscript after the one referred to
by subsarray[subs_used-1].buf_addr
. A node need not exist at
the subscripted variable name provided as input to the function. If
subsarray[subs_used-1].len_used
is zero,
ret_value->buf_addr
points to first node at that level with a
subscript that is not the empty string. ydb_subscript_next_s()
and ydb_subscript_next_st()
return:
YDB_OK
, in which caseret_value->buf_addr
points to the value of that next subscript;YDB_ERR_NODEEND
when there are no more subscripts at that level, in which case*ret_value
is unchanged;YDB_ERR_PARAMINVALID
whenret_value
is NULL;ret_value->buf_addr
is NULL and the return value has a non-zerolen_used
; orlen_alloc
<len_used
or thelen_used
is non-zero andbuf_addr
is NULL in at least one subscript insubsarray
or another error return code.
In the special case where subs_used
is zero, and the function
returns YDB_OK
, ret_value->buf_addr
points to the next
local or global variable name, with YDB_ERR_NODEEND
indicating
an end to the traversal.
Please see the Simple API introduction for details about parameter allocation.
ydb_subscript_previous_s() / ydb_subscript_previous_st()¶
int ydb_subscript_previous_s(ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *ret_value);
int ydb_subscript_previous_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *varname,
int subs_used,
ydb_buffer_t *subsarray,
ydb_buffer_t *ret_value);
ydb_subscript_previous_s()
and
ydb_subscript_previous_st()
provide a primitive for implementing
reverse breadth-first traversal of a tree by searching for the
previous subscript at the level specified by subs_used
. i.e. the
subscript preceding the one referred to by
subsarray[subs_used-1].buf_addr
. A node need not exist at the
subscripted variable name provided as input to the function. If
subsarray[subs_used-1].len_used
is zero, ret_value->buf_addr
points to last node at that level with a subscript that is not the
empty string. ydb_subscript_previous_s()
and
ydb_subscript_previous_st()
return:
YDB_OK
, in which caseret_value->buf_addr
points to the value of that previous subscript;YDB_ERR_NODEEND
when there are no more subscripts at that level, in which case*ret_value
is unchanged;YDB_ERR_PARAMINVALID
whenret_value
is NULL;ret_value->buf_addr
is NULL and the return value has a non-zerolen_used
; orlen_alloc
<len_used
or thelen_used
is non-zero andbuf_addr
is NULL in at least one subscript insubsarray
or another error return code.
In the special case where subs_used
is zero, and the function
returns YDB_OK
, ret_value->buf_addr
points to the
previous local or global variable name, with YDB_ERR_NODEEND
indicating an end to the traversal.
Please see the Simple API introduction for details about parameter allocation.
ydb_tp_s() / ydb_tp_st()¶
int ydb_tp_s(ydb_tpfnptr_t tpfn,
void *tpfnparm,
const char *transid,
int namecount,
ydb_buffer_t *varnames);
int ydb_tp_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_tp2fnptr_t tpfn,
void *tpfnparm,
const char *transid,
int namecount,
ydb_buffer_t *varnames);
ydb_tp_s()
and ydp_tp_st()
call the function
referenced by tpfn
passing it tpfnparm
as a
parameter. Additionally, ydb_tp_st()
also generates a
new tptoken
that it passes as a parameter to the
function referenced by its tpfn
parameter.
As discussed under Transaction Processing, a function implementing
transaction processing logic should use the intrinsic special variable
$trestart
to manage any externally visible action (which
YottaDB recommends against, but which may be unavoidable). The
function referenced by tpfn
should return one of the
following:
YDB_OK
— application logic indicates that the transaction can be committed (the YottaDB engine may still decide that a restart is required to ensure ACID transaction properties) as discussed under Transaction Processing.YDB_TP_RESTART
— application logic indicates that the transaction should restart.YDB_TP_ROLLBACK
— application logic indicates that the transaction should not be committed.YDB_ERR_PARAMINVALID
whenlen_alloc
<len_used
or thelen_used
is non-zero andbuf_addr
is NULL in at least one variable name invarnames
.An error return code returned by a YottaDB function called by the function. This case is treated the same way as if YDB_TP_ROLLBACK was returned (i.e. the application indicates that this transaction should not be committed).
transid
is a string, up to the first 8 bytes of which are recorded
in the commit record of journal files for database regions
participating in the transaction. If not NULL or the empty string, a
case-insensitive value of "BA"
or "BATCH"
indicates that at
transaction commit, YottaDB need not ensure Durability (it always
ensures Atomicity, Consistency, and Isolation). Use of this value may
improve latency and throughput for those applications where an
alternative mechanism (such as a checkpoint) provides acceptable
Durability. If a transaction that is not flagged as "BATCH"
follows one or more transactions so flagged, Durability of the later
transaction ensures Durability of the the earlier "BATCH"
transaction(s).
If namecount>0
, varnames[i]
where 0≤i<namecount
specifies
local variable names whose values are restored to their original
values when the transaction is restarted. In the special case where
namecount=1
and varnames[0]
provides the value "*"
, all
local variables are restored on a restart. It is an error for a
varnames
to include a global or intrinsic special variable.
A top level ydb_tp_s()
and ydb-tp_st()
can return:
YDB_OK
;YDB_TP_ROLLBACK
;YDB_ERR_TPTIMEOUT
(see Transaction Processing); oran error return code, including
YDB_ERR_NAMECOUNT2HI
.
A ydb_tp_s()
or ydb_tp_st()
call that is within
another transaction (i.e., a nested transaction) can also return
YDB_TP_RESTART
to its caller. 2
- 2
An enclosing transaction can result not just from another
ydb_tp_s()
orydb_tp_st()
higher in the stack, but also (for single-threaded applications) from an Mtstart
command as well as a database trigger resulting from a ydb_delete_s() / ydb_delete_st(), or ydb_set_s() / ydb_set_st().
Note
If the transaction logic receives a YDB_TP_RESTART
from a YottaDB function that it calls, it must return that value to the calling ydb_tp_s()
or ydb_tp_st()
. Failure to do so could result in application level data inconsistencies and hard to debug application code.
Please see the Simple API introduction for details about parameter allocation.
ydb_zwr2str_s() / ydb_zwr2str_st()¶
int ydb_zwr2str_s(ydb_buffer_t *zwr, ydb_buffer_t *str);
int ydb_zwr2str_st(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_buffer_t *zwr, ydb_buffer_t *str);
In the buffer referenced by *str
, ydb_zwr2str_s()
and
ydb_zwr2str_st()
provide the
string described by the zwrite formatted string pointed to by
*zwr
, returning
YDB_OK
(withstr->len_used
set to zero if the zwrite formatted string has an error);YDB_ERR_INVSTRLEN
error if the*str
buffer is not long enough;YDB_ERR_PARAMINVALID
either if the*str
buffer is NULL or the return value contains a non-zerolen_used
and thestr->buf_addr
is NULL.
Please see the Simple API introduction for details about parameter allocation.
Comprehensive API¶
The Comprehensive API is a project for the future.
Utility Functions¶
Utility functions are functions that are not core to YottaDB functionality, but which are useful to application code.
Utility functions whose names end in _t()
are for use by
multi-threaded applications, and those which do not are for
single-threaded applications. The discussion in Threads provides
more detailed information.
ydb_hiber_start() and ydb_hiber_start_wait_any() are for use only with the SimpleAPI and not with the threaded Simple API.
ydb_exit(), ydb_fork_n_core(), and ydb_init() do not have separate variants for single- and multi-threaded applications and are suitable for both.
See also the description of the ydb_ci_t()
and
ydb_cip_t()
functions in the Programmers Guide.
ydb_child_init()¶
YottaDB r1.22 and before required the use of a function ydb_child_init()
immediately after a fork()
to avoid database damage and other possible
side-effects.
Effective YottaDB r1.24, this function is not needed. It gets automatically invoked by YottaDB as needed. Any existing usages of this function in an application can be safely removed assuming YottaDB r1.24 or later is in use.
ydb_ci_tab_open() / ydb_ci_tab_open_t()¶
int ydb_ci_tab_open(char *fname, uintptr_t *ret_value)
int ydb_ci_tab_open_t(uint64_t tptoken,
ydb_buffer_t *errstr, char *fname, uintptr_t *ret_value)
Opens the call-in table contained in the file name fname
. Using the filled in ret_value
handle in a later ydb_ci_tab_switch()
/ydb_ci_tab_switch_t()
call, one can switch to
this call-in table as the currently active call-in table. All calls to
ydb_cip()
/ydb_cip_t()
/ydb_ci()
/ydb_ci_t()
use the currently active
call-in table. This lets applications open any number of call-in tables across the lifetime of a process.
The ydb_ci
environment variable, if set, points to the default call-in table that YottaDB uses
unless the active call-in table is switched using ydb_ci_tab_switch()
/ydb_ci_tab_switch_t()
.
The call-in table pointed to by ydb_ci
, the default call-in table, need not be explicitly opened
with ydb_ci_tab_open()
/ydb_ci_tab_open_t()
.
Returns:
YDB_OK
if the open was successful and fills in a handle to the opened table inret_value
; orYDB_ERR_PARAMINVALID
if the input parametersfname
orret_value
are NULL; ora negative error return code (for example, if the call-in table in the file had parse errors).
Please see the Simple API introduction for details about parameter allocation.
ydb_ci_tab_switch() / ydb_ci_tab_switch_t()¶
int ydb_ci_tab_switch(uintptr_t new_handle, uintptr_t *ret_old_handle)
int ydb_ci_tab_switch_t(uint64_t tptoken,
ydb_buffer_t *errstr, uintptr_t new_handle, uintptr_t *ret_old_handle)
Switches the currently active call-in table to the handle new_handle
(returned by a previous call
to ydb_ci_tab_open()
/ydb_ci_tab_open_t()
) and fills in the previously
active call-in table handle in *ret_old_handle
. An application that wishes to switch back to the
previous call-in table at a later point would call ydb_ci_tab_switch()
/ydb_ci_tab_switch_t()
again with *ret_old_handle
as the new_handle
parameter. The special value of NULL passed in
new_handle
switches the active call-in table to the default call-in table (the call-in table pointed
to by the ydb_ci
environment variable).
Returns:
YDB_OK
if the open was successful and fills in a handle to the opened table inret_value
; orYDB_ERR_PARAMINVALID
if the output parameterret_old_handle
is NULL or if the input parameternew_handle
points to an invalid handle (i.e. not returned by a priorydb_ci_tab_open()
/ydb_ci_tab_open_t()
) call); ora negative error return code
Note that application code using the ydb_cip()
/ydb_cip_t()
functions provides
YottaDB with a pointer to a ci_name_descriptor
structure that includes a handle. YottaDB uses the
current call-in table to set the handle the first time that the associated function is called. Thereafter,
the handle is immutable, and switching the call-in table leaves unchanged the mapping for functions whose
handles have already been set. Use ydb_ci()
/ydb_ci_t()
for application code that requires
the called function to change when the call-in table changes.
ydb_eintr_handler() / ydb_eintr_handler_t()¶
int ydb_eintr_handler(void)
int ydb_eintr_handler_t(uint64_t tptoken, ydb_buffer_t *errstr)
ydb_eintr_handler()
needs to be invoked by a SimpleAPI application whenever a system call that it invokes
(e.g. accept()
, select()
) returns an error with errno set
to EINTR
(this usually means a signal interrupted the system call). This ensures that YottaDB takes
appropriate action corresponding to the interrupting signal in a timely fashion. For example, if the signal
SIGTERM
was sent externally to this SimpleAPI application process, the appropriate action is to terminate
the process as soon as a safe/logical point is reached.
Note that not invoking ydb_eintr_handler()
as part of an EINTR
situation can cause the SimpleAPI
application to behave unexpectedly. For example, in the SIGTERM
case, the process would not terminate
how ever many signals are sent.
ydb_eintr_handler_t()
is very similar to ydb_eintr_handler()
except that it needs to be invoked by
a SimpleThreadAPI application.
ydb_exit()¶
int ydb_exit(void)
When a caller no longer wishes to use YottaDB, a call to
ydb_exit()
cleans up the process
connection/access to all databases and cleans up its data
structures. Therafter, any attempt to call a YottaDB function produces
a YDB_ERR_CALLINAFTERXIT
error.
Note that:
a typical application should not need to call
ydb_exit()
, but should instead just terminate with a call toexit()
which will perform any cleanup needed by YottaDB; andcalling
ydb_exit()
before calling any other YottaDB function does nothing, i.e., it is a no-op.
ydb_exit()
returns YDB_OK
on success, and a positive non-zero value on error.
If ydb_exit()
has already been called, later calls to ydb_exit()
in the same process return YDB_OK
with no further action, since all resources related to YottaDB are already cleaned up by the first call.
If an external call attempts to call ydb_exit()
, a YDB_ERR_INVYDBEXIT
error is returned, since YottaDB
is required to remain operational even after the external call returns. For information about this error, see
INVYDBEXIT in the Messages and Recovery Procedures guide.
ydb_exit()
can be used with both the Simple API and threaded Simple API.
ydb_file_id_free() / ydb_file_id_free_t()¶
int ydb_file_id_free(ydb_fileid_ptr_t fileid)
int ydb_file_id_free_t(uint64_t tptoken,
ydb_buffer_t *errstr, ydb_fileid_ptr_t fileid)
Releases the memory used by a fileid
structure previously
generated by ydb_file_name_to_id() or
ydb_file_name_to_id_t(). Calling the function twice for the same
pointer, unless it has been returned a second time by a different
ydb_file_name_to_id() or ydb_file_name_to_id_t() is an
application error with undefined consequences.
A PARAMINVALID
error is issued if the input fileid
parameter is NULL.
Please see the Simple API introduction for details about parameter allocation.
ydb_file_is_identical() / ydb_file_is_identical_t()¶
int ydb_file_is_identical(ydb_fileid_ptr_t fileid1,
ydb_fileid_ptr_t fileid2)
int ydb_file_is_identical_t(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_fileid_ptr_t fileid1,
ydb_fileid_ptr_t fileid2)
Given two pointers to fileid
structures (see
ydb_file_name_to_id() / ydb_file_name_to_id_t()),
ydb_file_is_identical()
and ydb_file_is_identical_t()
return YDB_OK if the two fileid
structures are the same file
and YDB_NOTOK otherwise.
A PARAMINVALID
error is issued if the input fileid
parameter is NULL.
Please see the Simple API introduction for details about parameter allocation.
ydb_file_name_to_id() / ydb_file_name_to_id_t()¶
int ydb_file_name_to_id(ydb_string_t *filename,
ydb_fileid_ptr_t *fileid)
int ydb_file_name_to_id_t(uint64_t tptoken,
ydb_buffer_t *errstr,
ydb_string_t *filename,
ydb_fileid_ptr_t *fileid)
As a file is potentially reachable through different paths, and
application code may need to check whether two paths do indeed lead to
the same file, YottaDB provides a mechanism to do so. Provided with a
path to a file, YottaDB creates an internal structure called a
fileid
that uniquely identifies the file if such a structure
does not already exist for that file, and provides the caller with a
pointer to that structure. The layout and contents of the fileid
structure are opaque to the caller, which must not modify the
pointer or the structure it points to.
When the fileid
structure for a file is no longer needed, an
application should call ydb_file_id_free() or
ydb_file_id_free_t() to release the structure and avoid a memory
leak.
ydb_file_name_to_id()
and ydb_file_name_to_id_t()
return YDB_OK
, or an error return code.
A PARAMINVALID
error is issued if the input filename
or fileid
parameter is NULL.
Please see the Simple API introduction for details about parameter allocation.
ydb_fork_n_core()¶
void ydb_fork_n_core(void)
A core is a snapshot of a process, to help debug application code, for
example to troubleshoot an out-of-design condition. When a process
executes ydb_fork_n_core()
, it
forks. The child process sends itself a signal to generate a core and
terminate. On termination of the child process, the parent process
continues execution. Note that depending on the nature of the
condition necessitating a core, an exit()
may well be the
right action for the parent process. An exit()
call will drive
YottaDB exit handlers to perform clean shutdown of databases and
devices the process has open.
The content, location, and naming of cores is managed by the operating
system – see man 5 core
for details. We recommend that you set
kernel.core_uses_pid
to 1 to make it easier to identify and
track cores. As cores will likely contain protected confidential
information, you must ensure appropriate configuration and
management of cores.
In a multi-threaded environment, only the thread that executes
ydb_fork_n_core()
or ydb_fork_n_core()
survives in the
child and is dumped.
ydb_fork_n_core()
can be used with both the Simple API and threaded Simple API.
ydb_free()¶
void ydb_free(void *ptr)
Releases memory previously allocated by ydb_malloc(). Passing ydb_free()
a pointer not previously provided to the
application by ydb_malloc() can result in
unpredictable behavior. The signature of ydb_free()
matches
that of the POSIX free()
call.
ydb_free()
should not be used in
multiple threads in multi-threaded programs. (See the Threads section for details). However, the YDB_FREE_BUFFER
macro is safe
to use in multiple threads.
ydb_hiber_start()¶
int ydb_hiber_start(unsigned long long sleep_nsec)
The process or thread sleeps for the time in nanoseconds specified by
sleep_nsec
. If a value greater than YDB_MAX_TIME_NSEC
is specified, ydb_hiber_start()
immediately returns with a YDB_ERR_TIME2LONG
error; otherwise
they return YDB_OK
after the elapsed time.
ydb_hiber_start()
should not be used in multiple threads in multi-threaded programs. (See the Threads section for details).
ydb_hiber_start_wait_any()¶
int ydb_hiber_start_wait_any(unsigned long long sleep_nsec)
The process or thread sleeps for the time in nanoseconds specified by
sleep_nsec
or until it receives a signal. If a value greater
than YDB_MAX_TIME_NSEC
is specified, ydb_hiber_start_wait_any()
immediately returns with a
YDB_ERR_TIME2LONG
error; otherwise they return YDB_OK
after the elapsed time or when the wait is terminated by a signal.
ydb_hiber_start_wait_any()
should not be used in multiple threads in multi-threaded programs. (See the Threads section for details).
ydb_init()¶
int ydb_init(void)
ydb_init()
initializes the YottaDB
runtime environment. As YottaDB automatically initializes the runtime
on the first call to its API or first M code invocation, there is
usually no need to explicitly call ydb_init()
.
The exception is when an application wishes to
set its own signal handlers (see Signals): ydb_init()
sets signal handlers, and in case an application
wishes to set its own signal handlers for signals not used by YottaDB,
it can call ydb_init()
before setting
its signal handlers.
ydb_init()
returns YDB_OK
on success, and a positive non-zero value otherwise.
On failure, the error message text corresponding to the non-zero return value can be obtained
by immediately calling ydb_zstatus()
.
If ydb_init()
has already been called, later calls to ydb_init()
in the same
process return YDB_OK
with no further action, since the YottaDB runtime has already been initialized.
ydb_init()
can be used with both the Simple API and threaded Simple API.
ydb_malloc()¶
void *ydb_malloc(size_t size)
With a signature matching that of the POSIX malloc()
call,
ydb_malloc()
returns an address to a block of memory of the
requested size, or NULL if it is unable to satisfy the request.
ydb_malloc()
uses a buddy system, and
provides debugging functionality under the control of the environment
variable ydb_dbglvl
whose values are a mask as described in
gtmdbglvl.h.
ydb_malloc()
should not be used in
multiple threads in multi-threaded programs. (See the Threads section for details). However, the YDB_MALLOC_BUFFER
macro is safe
to use in multiple threads.
ydb_message() / ydb_message_t()¶
int ydb_message(int errnum, ydb_buffer_t *msg_buff)
int ydb_message_t(uint64_t tptoken, ydb_buffer_t *errstr,
int errnum, ydb_buffer_t *msg_buff)
The functions return the error message text template for the error
number specified by errnum
.
If
errnum
does not correspond to an error that YottaDB recognizes, the return the errorYDB_ERR_UNKNOWNSYSERR
, leaving the structures referenced bymsg_buff
unaltered.Otherwise, if the length of the text exceeds
msg_buff->len_alloc
they return the errorYDB_ERR_INVSTRLEN
. In this casemsg_buff->len_used
is greater thanmsg_buff->len_alloc
.Otherwise, if
msg_buff->buf_addr
is NULL, they return the errorYDB_ERR_PARAMINVALID
.Otherwise, the copy the text to the buffer specified by
msg_buff->buf_addr
, setmsg_buff->len_used
to its length, and returnYDB_OK
.
Please see the Simple API introduction for details about parameter allocation.
ydb_mmrhash_32()¶
void ydb_mmrhash_32(const void *key, int len, uint4 seed, uint4 *out4);
This function returns in *out4
the 32-bit (4-byte) MurmurHash of len
bytes at *key
.
Please see the Simple API introduction for details about parameter allocation.
ydb_mmrhash_128()¶
void ydb_mmrhash_128(const void *key, int len, uint4 seed, ydb_uint16 *out);
This function returns in *out
the 128-bit (16-byte) MurmurHash of len
bytes at *key
.
Please see the Simple API introduction for details about parameter allocation.
ydb_mmrhash_128_ingest() / ydb_mmrhash_128_result()¶
void ydb_mmrhash_128_ingest(hash128_state_t *state, const void *key, int len);
void ydb_mmrhash_128_result(hash128_state_t *state, uint4 addl_seed, ydb_uint16 *out);
These functions enable users to get a MurmurHash through a series of incremental operations.
The sequence is to first initialize the “state” variable using the HASH128_STATE_INIT() macro, then call ydb_mmrhash_128_ingest()
one or more times and finally call ydb_mmrhash_128_result()
to
obtain the final hash value. “key” points to the input character array (of length “len”) for the hash. “addl_seed” can either be the last four bytes of the input, or at the application’s discretion, an additional seed or salt.
An example is to set it to the sum of the “len” values passed in across all calls to ydb_mmrhash_128_ingest
before ydb_mmrhash_128_result
is called. “out” points to the structure holding the 16-byte hash result.
Example:
// Initialize state struct
HASH128_STATE_INIT(hash_state, 0);
// Create keys/strings to ingest
char *key1 = "ifembu8r308j243h5g3h84t7yf23h0h";
char *key2 = "ougoh2408rh2fhe08yh2ti8rhhrguo2r3huocdiWEN23";
// Add keys to hash
ydb_mmrhash_128_ingest(&hash_state, (void*)key1, strlen(key1));
ydb_mmrhash_128_ingest(&hash_state, (void*)key2, strlen(key2));
// Produce result
ydb_mmrhash_128_result(hash_state, 0, &hash);
Please see the Simple API introduction for details about parameter allocation.
ydb_mmrhash_128_hex()¶
void ydb_mmrhash_128_hex(const ydb_uint16 *hash, unsigned char *out);
This function returns a hex formatted representation of a 16-byte hash value. As the function does no checking, if *out
is not at least 32 bytes, a buffer overflow can occur, potentially with unpleasant consequences such as abnormal process termination with a SIG-11, or worse.
Example:
char out[16];
ydb_mmrhash_128_hex(&hash, out);
Please see the Simple API introduction for details about parameter allocation.
ydb_mmrhash_128_bytes()¶
void ydb_mmrhash_128_bytes(const ydb_uint16 *hash, unsigned char *out);
This function converts the 16-byte hash stored in a “ydb_uint16” structure (2 8-byte integers) into a byte array “out” of 16 characters. It is also internally used by ydb_mmrhash_128_hex().
Example:
char out[16];
ydb_mmrhash_128_bytes(&hash, out);
Please see the Simple API introduction for details about parameter allocation.
ydb_stdout_stderr_adjust() / ydb_stdout_stderr_adjust_t()¶
int ydb_stdout_stderr_adjust(void)
int ydb_stdout_stderr_adjust_t(uint64 tptoken,
ydb_buffer_t *errstr)
The functions check whether stdout (file descriptor 1) and stderr
(file descriptor 2) are the same file, and if so, route stderr writes
to stdout instead. This ensures that output appears in the order in
which it was written; otherwise owing to IO buffering, output can
appear in an order different from that in which it was
written. Application code which mixes C and M code, and which
explicitly redirects stdout or stderr (e.g., using dup2()
),
should call one of these functions as soon as possible after the
redirection. ydb_stdout_stderr_adjust()
and
ydb_stdout_stderr_adjust_t()
return YDB_OK
.
Please see the Simple API introduction for details about parameter allocation.
ydb_thread_is_main()¶
int ydb_thread_is_main(void)
The functions return YDB_OK
if the thread is the main thread
of the process, and another value if the thread is not. YottaDB
recommends against application code that requires use of these
functions, which exist only to provide backward compatibility to a
specific application code base (see discussion under Threads).
ydb_timer_cancel() / ydb_timer_cancel_t()¶
void ydb_timer_cancel(intptr_t timer_id)
void ydb_timer_cancel_t(uint64_t tptoken,
ydb_buffer_t *errstr, intptr_t timer_id)
Cancel a timer identified by timer_id
and previously started with
ydb_timer_start() or ydb_timer_start_t().
Please see the Simple API introduction for details about parameter allocation.
ydb_timer_start() / ydb_timer_start_t()¶
typedef void (*ydb_funcptr_retvoid_t)(intptr_t timer_id,
unsigned int handler_data_len,
char *handler_data);
int ydb_timer_start(intptr_t timer_id,
unsigned long long limit_nsec,
ydb_funcptr_retvoid_t handler,
unsigned int handler_data_len,
char *handler_data);
int ydb_timer_start_t(uint64_t tptoken,
ydb_buffer_t *errstr,
intptr_t timer_id,
unsigned long long limit_nsec,
ydb_funcptr_retvoid_t handler,
unsigned int handler_data_len,
char *handler_data);
Start a timer. Unless canceled, when the timer expires,
ydb_timer_start()
and ydb_timer_start_t()
invoke a
handler function, providing that function with input data.
timer_id
is an identifier for the the timer. It is the
responsibility of application code to ensure that timer_id
is
different from those of any other active / pending timers.
limit_nsec
is the minimum number of nanoseconds before the timer
expires and invokes the handler function. Owing to overhead and system
load, the actual time will almost always be greater than this value.
handler
is a pointer to the function to be called when the timer
expires.
handler_data
is a pointer to the data to be passed to handler
and handler_data_len
is the length of the data at
*handler_data
. Note that the data it points to must be on the
heap rather than on the stack, as the stack frame may no longer be
valid when the timer expires.
If the requested timeout_nsec
exceeds
YDB_MAX_TIME_NSEC
, the functions return
YDB_ERR_TIME2LONG
; otherwise they return YDB_OK
.
Please see the Simple API introduction for details about parameter allocation.
Calling M Routines¶
M routines can be called from C with the following functions which are described in the M Programmers Guide:
Historically, the predecessors of the functions to call M routines
returned positive return codes. In order to maintain backward
compatibility, values returned by the above are positive values, whereas
YottaDB error return codes are negative. For example, to return an
invalid string length (YDB_ERR_INVSTRLEN), the ydb_ci*()
functions
return -YDB_ERR_INVSTRLEN
, which is a positve value because
YDB_ERR_STRLEN
is a negative value.
Effective release
r1.30.
ydb_zstatus()
returns an int
.