6.5. C

6.5.1. Introduction

The quasardb C API is the lowest-level API offered but also the fastest and the most powerful.

6.5.2. Installing

The C API package is downloadable from the quasardb download site. All information regarding the quasardb download site are in your welcome e-mail.

\qdb-<version>-<platform>-c-api
    \bin        // QDB API shared libraries (.dll, Windows only)
    \examples   // C and C++ API examples
    \include    // C and C++ header files
    \lib        // QDB API shared libraries
    \share
        \doc    // This documentation

Most C functions, typedefs and enums are available in the include/qdb/client.h header file. The object specific functions for hsets, integers, double-ended queues, and tags are in their respective include/qdb/*.h files.

6.5.3. Connecting to a cluster

The first thing to do is to initialize a handle. A handle is an opaque structure that represents a client-side instance. It is initialized using the function qdb_open():

qdb_handle_t handle;
qdb_error_t error = qdb_open(&handle, qdb_p_tcp);
if (QDB_FAILURE(error)) return EXIT_FAILURE;

We can also use the convenience function qdb_open_tcp():

qdb_handle_t handle = qdb_open_tcp();
if (!handle) return EXIT_FAILURE;

Once the handle is initialized, you need to add credentials information before you can establish a connection, unless security is disabled on the cluster.

For that you need to set the cluster public key, which will make sure you connect to the right cluster, and the user credentials which consist in the user name and the user private key and are necessary to authenticate the connection. These information are given to you by your administrator. You need to use qdb_option_set_cluster_public_key() and qdb_option_set_user_credentials().

error = qdb_option_set_cluster_public_key(handle, "PZMBhqk43w+HNr9lLGe+RYq+qWZPrksFWMF1k1UG/vwc=");
if (QDB_FAILURE(error))
{
    // error management
}

error = qdb_option_set_user_credentials(handle, "user_name", "SL8sm9dM5xhPE6VNhfYY4ib4qk3vmAFDXCZ2FDi8AuJ4=");
if (QDB_FAILURE(error))
{
    // error management
}

If the server has full traffic encryption, you must enable it on the client side before establishing the connection:

error = qdb_option_set_encryption(handle, qdb_crypt_aes_gcm_256);
if (QDB_FAILURE(error))
{
    // error management
}

You are now ready to establish the connection. This code will establish a connection to a single quasardb node listening on the localhost with the qdb_connect() function:

qdb_error_t error_connect = qdb_connect(handle, "qdb://localhost:2836");
if (QDB_FAILURE(error_connect))
{
    // error management
}

Note that we could have used the IP address instead:

qdb_error_t error_connect = qdb_connect(handle, "qdb://127.0.0.1:2836");
if (error_connect)
{
    // error management
}

Caution

Concurrent calls to qdb_connect() using the same handle results in undefined behaviour.

IPv6 is also supported if the node listens on an IPv6 address:

qdb_error_t error_connect = qdb_connect(handle, "qdb://[::1]:2836");
if (error_connect)
{
    // error management
}

Note

When you call qdb_open() and qdb_connect(), a lot of initialization and system calls are made. It is therefore advised to reduce the calls to these functions to the strict minimum, ideally keeping the same handle alive for the lifetime of the program.

6.5.4. Connecting to multiple nodes within the same cluster

Although quasardb is fault-tolerant, if the client tries to connect to the cluster through a node that is unavailable, the connection will fail. To prevent that, it is advised to pass a URI string to qdb_connect() with multiple comma-separated hosts and ports. If the client can establish a connection with any of the nodes, the call will succeed.

const char * remote_nodes = "qdb://192.168.1.1:2836,192.168.1.2:2836,192.168.1.3:2836";

// The call to qdb_connect will be successful if any of the connections succeeds.
qdb_error_t error_connect = qdb_connect(handle, remote_nodes);
if (error_connect)
{
    // error management
}

If the same address/port pair is present multiple times within the string, only the first occurrence is used.

6.5.5. Adding entries

Each entry is identified by a unique alias. See Aliases for more information.

The content is a buffer containing arbitrary data. You need to specify the size of the content buffer. There is no built-in limit on the content’s size; you just need to ensure you have enough free memory to allocate it at least once on the client side and on the server side.

There are two ways to add entries into the repository. You can use qdb_blob_put():

error = qdb_blob_put(handle, alias, (const void *)content, strlen(content), qdb_never_expires);
if (error)
{
    // error management
}

or you can use qdb_blob_update():

error = qdb_blob_update(handle, alias, (const void *)content, strlen(content), qdb_preserve_expiration);
if (error && (error != qdb_e_ok_created))
{
    // error management
}

The difference is that qdb_blob_put() fails when the entry already exists. qdb_blob_update() will create the entry if it does not (and return qdb_e_ok_created), or update its content if it does (and return qdb_e_ok). qdb_blob_update() may be called with expiry time equal to qdb_preserve_expiration, in which case, it will not modify the expiration of the updated entry. Should the entry be created, it will have no expiration. qdb_blob_put(), if called with expiry time equal to qdb_preserve_expiration, will behave as if the argument were equal to qdb_never_expires.

6.5.6. Getting entries

The most convenient way to fetch an entry is qdb_blob_get():

const char * alias = argv[2];
const void * allocated_content;
qdb_size_t allocated_content_length = 0u;
error = qdb_blob_get(handle, alias, &allocated_content, &allocated_content_length);
if (error)
{
    // error management
}

The function will allocate the buffer and update the length. You will need to release the memory later with qdb_release():

qdb_release(handle, allocated_content);

However, for maximum performance you might want to manage allocation yourself and reuse buffers (for example). In which case you will prefer to use qdb_blob_get_noalloc():

const char * alias = argv[2];
char content[1024];
// content_length must be initialized with the buffer's size
// and will be updated with the retrieved content's size
qdb_size_t content_length = sizeof(content);
error = qdb_blob_get_noalloc(handle, alias, content, &content_length);
if (error)
{
    // error management
}

The function will update content_length even if the buffer isn’t large enough, giving you a chance to increase the buffer’s size and try again.

6.5.7. Removing entries

Removing is done with the function qdb_remove():

error = qdb_remove(handle, alias);
if (error)
{
    // error management
}

The function fails if the entry does not exist.

6.5.8. Cleaning up

When you are done working with a quasardb cluster, call qdb_close():

qdb_close(handle);

qdb_close() does not guarantee to release memory allocated by qdb_blob_get(). You will need to make appropriate calls to qdb_release() for each call to qdb_blob_get().

Note

Avoid opening and closing connections needlessly. A handle consumes very little memory and resources. It is safe to keep it open for the duration of your program.

6.5.9. Timeout

It is possible to configure the client-side timeout with the qdb_option_set_timeout():

// Set the timeout to 5 seconds (5000 ms).
qdb_option_set_timeout(handle, 5000);

Currently running requests are not affected by the modification, only new requests will use the new timeout value. The default client-side timeout is one minute. Keep in mind that the server-side timeout might be shorter.

6.5.10. Expiry

Expiry is set with qdb_expires_at() and qdb_expires_from_now(). It is obtained with qdb_get_expiry_time(). Expiry time is always passed in as milliseconds, either relative to epoch (January 1st, 1970 00:00 UTC) when using qdb_expires_at() or relative to the call time when using qdb_expires_from_now().

Values in the past are considered invalid, except for a couple of minutes to account for the potential desynchronization between the client and the server. A value slightly in the past will cause an immediate expiry.

Warning

The behavior of qdb_expires_from_now() is undefined if the time zone or the clock of the client computer is improperly configured.

To set the expiry time of an entry relatively to the call time:

// Set the entry to expire in 1 minute (60 s).
error = qdb_expires_from_now(handle, alias, 60);
if (error)
{
    // error management
}

To prevent an entry from ever expiring:

error = qdb_expires_from_now(handle, alias, qdb_never_expires);
if (error)
{
    // error management
}

By default, entries never expire. To obtain the expiry time of an existing entry:

qdb_time_t expiry_time = 0;
error = qdb_get_expiry_time(handle, alias, &expiry_time);
if (error)
{
    // error management
}

6.5.11. Integers

Quasardb supports signed 64-bit integers natively. All operations on integers are guaranteed to be atomic. Likes blobs, integers support put (qdb_int_put()), update (qdb_int_update()), get (qdb_int_get()) and remove (qdb_remove()):

qdb_int_t value = 3;

error = qdb_int_put(handle, alias, value, qdb_never_expires);
if (error)
{
    // error management
}
else
{
    qdb_int_t found_value = 0;

    error = qdb_int_get(handle, alias, &found_value);
    if (error)
    {
        // error management
    }
}

Quasardb API defines a cross platform integer to be used with all integer operations: qdb_int_t. You are strongly encouraged to use this type.

In addition to basic put/update/get/remove operations, integers support atomic increment and decrement through the qdb_int_add() function:

const char * begin = argv[3];
char * end = NULL;
qdb_int_t increment = (qdb_int_t)strtol(begin, &end, /*base=*/10);
if (errno || (begin == end))
{
    // error management
}
qdb_int_t result = 0;

// add increment and returns the value
error = qdb_int_add(handle, alias, increment, &result);
if (error)
{
    // error management
}

The qdb_int_add() function requires the entry to already exist.

Quasardb integers storage on disk is highly optimized and increment/decrement use native instructions. If you are working on 64-bit signed integers, using quasardb native integers can deliver a significant performance boost compared to blobs.

6.5.12. Tags

Any entry can have an arbitrary number of tags, and you can lookup entries based on their tags. In other words, you can ask quasardb questions like “give me all the entry with the tag X”. You can only tag existing entries. There is no predetermined limit on the number of tags per entry, or the number of entries a tag may refer to.

You can attach one tag at a time to an entry (qdb_attach_tag()), or several tags at once (qdb_attach_tags()):

error = qdb_attach_tag(handle, alias, tag);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_attach_tag", qdb_error(error), error);
}

const char * tags_to_attach[2] = {"my_tag1", "my_tag2"};

error = qdb_attach_tags(handle, alias, tags_to_attach, 2);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_attach_tags", qdb_error(error), error);
}

If the tag is already set, the error code returned will be qdb_e_tag_already_set. You can only attach tag to previously created entries.

To remove a tag, use qdb_detach_tag():

error = qdb_detach_tag(handle, alias, tag);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_detach_tag", qdb_error(error), error);
}

const char * tags_to_detach[2] = {"my_tag1", "my_tag2"};

error = qdb_detach_tags(handle, alias, tags_to_detach, 2);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_detach_tags", qdb_error(error), error);
}

It is an error to detach a non-existing tag.

Note

The qdb_attach_tags() and qdb_detach_tags() take as the tags list an array of pointers to null-terminated strings.

To retrieve the entries matching a tag, there are two possibilities: fetch everything at once or iterate on the entries.

If you think the number of returned entries will be reasonable (e.g. easily fits in RAM), you can use qdb_get_tagged():

const char ** aliases = NULL;
qdb_size_t alias_count = 0;

error = qdb_get_tagged(handle, tag, &aliases, &alias_count);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_get_tagged", qdb_error(error), error);
}

qdb_release(handle, aliases);

Note

You must use qdb_release() on the aliases returned by qdb_get_tagged().

If you suspect the number of results to be very high, you may want to iterate over the results:

qdb_const_tag_iterator_t it;

error = qdb_tag_iterator_begin(handle, tag, &it);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_tag_iterator_begin", qdb_error(error), error);
}

for (error = qdb_tag_iterator_begin(handle, tag, &it); error == qdb_e_ok; error = qdb_tag_iterator_next(&it))
{
    // read content
    // it.alias
    // it.type
}
if (error && (error != qdb_e_iterator_end))
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_tag_iterator_next", qdb_error(error), error);
}

error = qdb_tag_iterator_close(&it);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_tag_iterator_close", qdb_error(error), error);
}

Iteration prefetches the results to optimize network traffic and occurs on a snapshot of the database. Once you are finished with an iterator, call qdb_tag_iterator_close(). When iteration reaches the final entry, qdb_tag_iterator_next() will return qdb_e_iterator_end.

Removing an entry correctly updates the associated tags, in other words, a removed entry will no longer be reported as tagged.

Forward lookup is also supported. For any entry, you can test the existence of a tag or just retrieve the list of tags:

error = qdb_has_tag(handle, alias, tag);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_has_tag", qdb_error(error), error);
}

const char ** entry_tags = NULL;
qdb_size_t tag_count = 0;

error = qdb_get_tags(handle, alias, &entry_tags, &tag_count);
if (error)
{
    fprintf(stderr, "[%s] error: %s (%d)\n", "qdb_get_tags", qdb_error(error), error);
}

qdb_release(handle, entry_tags);

qdb_has_tag() will return qdb_e_tag_not_set if the tag isn’t set.

Note

Tags returned by qdb_get_tags() must be freed with qdb_release().

6.5.13. Double-ended queues

Warning

Experimental feature

Double-ended queues (deques) are distributed containers that support concurrent insertion and removal at the beginning and the end. Random access to any element within the deque is also supported.

The flexibility of the deque API enables you to implement at-most-once and at-least-once semantics.

There is no limit to the number of entries in a deque, no limit to the size of the entries within the deque.

To create a deque, you push elements to it using either qdb_deque_push_front() or qdb_deque_push_back(). Each function has a constant complexity and will span the deque accross nodes as it grows.

error = qdb_deque_push_back(handle, alias, content, strlen(content));
if (error)
{
    // error management
}

error = qdb_deque_push_front(handle, alias, content, strlen(content));
if (error)
{
    // error management
}

Push operations are atomic and safe to use concurrently.

To access elements within a deque, you can either use qdb_deque_front(), qdb_deque_back() or qdb_deque_get_at(). Each function has a constant complexity, independant of the length of the deque. The qdb_deque_get_at() function uses 0 based index, 0 representing the front item.

const void * entry = NULL;
qdb_size_t entry_length = 0;

error = qdb_deque_back(handle, alias, &entry, &entry_length);
if (error)
{
    // error management
}

qdb_release(handle, entry);

error = qdb_deque_front(handle, alias, &entry, &entry_length);
if (error)
{
    // error management
}

qdb_release(handle, entry);

error = qdb_deque_get_at(handle, alias, (qdb_int_t)1, &entry, &entry_length);
if (error)
{
    // error management
}

qdb_release(handle, entry);

It is possible to atomically update any entry within the deque with qdb_deque_set_at():

error = qdb_deque_set_at(handle, alias, (qdb_int_t)1, content, strlen(content));
if (error)
{
    // error management
}

Note

You must call qdb_release() on entries returned by deque accessors.

In addition to accessing entries, it is also possible to atomically remove and retrieve an entry with the qdb_deque_pop_front() and qdb_deque_pop_back() functions:

error = qdb_deque_pop_back(handle, alias, &entry, &entry_length);
if (error)
{
    // error management
}

qdb_release(handle, entry);

error = qdb_deque_pop_front(handle, alias, &entry, &entry_length);
if (error)
{
    // error management
}

qdb_release(handle, entry);

Note

You must call qdb_release() on entries returned by qdb_deque_pop_front(), qdb_deque_pop_back() and qdb_deque_get_at().

A deque can be empty. You can query the size of the deque with the qdb_deque_size() function:

qdb_size_t s = 0;

error = qdb_deque_size(handle, alias, &s);
if (error)
{
    // error management
}

To fully a deque, use qdb_remove(), like any other entry type:

error = qdb_remove(handle, alias);
if (error)
{
    // error management
}

Removing a deque has a linear complexity.

6.5.14. Hashed sets

Warning

Experimental feature

Hashed sets are distributed over the nodes and have no limit in the number of entries or the size of the entries. Hashed set currently support only insertion, erasure and querying. Entries are hashed using a cryptographically strong 256-bit hash, making collision extremely unlikely.

Insertion, access and removal are logarithmic respective to the size of the set.

To create a set, you insert an entry to a previously non existing set with qdb_hset_insert():

error = qdb_hset_insert(handle, alias, content, strlen(content));
if (error)
{
    // error management
}

When you need to remove an entry from a set, use qdb_hset_erase():

error = qdb_hset_erase(handle, alias, content, strlen(content));
if (error)
{
    // error management
}

To test the existence of an entry within a set, use qdb_hset_contains():

error = qdb_hset_contains(handle, alias, content, strlen(content));
if (error)
{
    // error management
}

To fully remove a set, use qdb_remove(), like any other entry type:

error = qdb_remove(handle, alias);
if (error)
{
    // error management
}

6.5.15. Batch operations

Batch operations can greatly increase performance when it is necessary to run many small operations. Using batch operations requires initializing, running and freeing an array of operations.

The qdb_init_operations() ensures that the operations are properly reset before setting any value:

#define OPERATION_COUNT 4
qdb_operation_t ops[OPERATION_COUNT];
error = qdb_init_operations(ops, OPERATION_COUNT);
if (error)
{
    // error management
}

Once this is done, you can fill the array with the operations you would like to run. qdb_init_operations() makes sure all the values have proper defaults:

// the first operation will be a get for "entry1"
ops[0].type = qdb_op_blob_get;
ops[0].alias = "entry1";

// the second operation will be a get for "entry2"
ops[1].type = qdb_op_blob_get;
ops[1].alias = "entry2";

// the third operation will be an update for "entry3"
#define CONTENT_SIZE 100
char content[CONTENT_SIZE];
ops[2].type = qdb_op_blob_update;
ops[2].alias = "entry3";
ops[2].blob_update.content = content;
ops[2].blob_update.content_size = CONTENT_SIZE;

// the fourth operation will be increasing an integer "int_value" by 42
ops[3].type = qdb_op_int_add;
ops[3].alias = "int_value";
ops[3].int_add.addend = 42;

You now have an operations batch that can be run on the cluster:

// Runs the batch on the cluster and returns the count of successfully executed operations.
qdb_size_t success_count = qdb_run_batch(handle, ops, OPERATION_COUNT);

Note that the order in which operations run is undefined. Error management with batch operations is a little bit more delicate than with other functions. qdb_run_batch() returns the number of successful operations. If this number is not equal to the number of submitted operations, it means you have an error.

The error field of each operation is updated to reflect its status. If it is not qdb_e_ok or qdb_e_ok_created, an error occured.

Let’s imagine the previous example returned an error. Here is some simple code for error detection:

if (success_count != OPERATION_COUNT)
{
    for (qdb_size_t i = 0; i < OPERATION_COUNT; ++i)
    {
        if ((ops[i].error != qdb_e_ok) && (ops[i].error != qdb_e_ok_created))
        {
            // we have an error in this operation
        }
    }
}

What you must do when an error occurs is entirely dependent on your application.

In our case, there have been four operations, two blob gets, one blob update and one int increase. In the case of the update, we only care if the operation has been successful or not. But what about the gets and the increase? The content is available in the result field for blobs:

const char * entry1_content = ops[0].blob_get.content;
qdb_size_t entry1_size = ops[0].blob_get.content_size;

const char * entry2_content = ops[1].blob_get.content;
qdb_size_t entry2_size = ops[1].blob_get.content_size;

And for the integer in result_value:

qdb_int_t result = ops[3].int_add.result;

Once you are finished with a series of batch operations, you must release the memory that the API allocated using qdb_release(). The call releases all buffers at once:

qdb_release(handle, ops);

6.5.16. Memory management

You may have noticed the qdb_release() function. It takes two parameters: a handle and a buffer. Internally, the quasardb API will track every buffer it allocated. When you pass a structure to the qdb_release() function it knows all the attached resources that must be freed.

For example if you ran a batch, it may have resulted in client-side allocations. When passing the pointer to your batch array to the qdb_release(), every allocated buffer, if any, will be freed. There is no need to call the function for each item in the batch.

To sum up: for every function that allocates memory, release the resource with qdb_release().

6.5.17. Iteration

Iteration on the cluster’s entries can be done forward and backward. You initialize the iterator with qdb_iterator_begin() or qdb_iterator_rbegin() depending on whether you want to start from the first entry or the last entry.

Actual iteration is done with qdb_iterator_next() and qdb_iterator_previous(). Once completed, the iterator should be freed with qdb_iterator_close():

qdb_const_iterator_t it;

// Forward iteration.
for (qdb_error_t error = qdb_iterator_begin(handle, &it); error == qdb_e_ok; error = qdb_iterator_next(&it))
{
    // Work on the entry here:
    // * it.alias contains the entry alias (key)
    // * it.content and it.content_size is the entry content
}

qdb_iterator_close(&it);
qdb_const_iterator_t rit;

// Backward iteration.
for (qdb_error_t error = qdb_iterator_rbegin(handle, &rit); error == qdb_e_ok; error = qdb_iterator_previous(&rit))
{
    // Work on the entry here:
    // * rit.alias contains the entry alias (key)
    // * rit.content and rit.content_size is the entry content
}

qdb_iterator_close(&rit);

Note

Although each entry is returned only once, the order in which entries are returned is undefined.

6.5.18. Queries

To run a query on quasardb, use the function qdb_query(). The API transparently runs the query accross the cluster, and returns the list of aliases matching the query result.

const char ** aliases = NULL;
size_t count = 0;

error = qdb_query(handle, query, &aliases, &count);
if (QDB_SUCCESS(error))
{
    for (size_t i = 0; i < count; ++i)
    {
        fwrite(aliases[i], strlen(aliases[i]), 1, stdout);
    }
}
else
{
    // error management
}

qdb_release(handle, aliases);

Aliases returned by qdb_query() must be freed with qdb_release().

If the query exceeds the maximum allowed cardinality, an error qdb_e_query_too_complex will be returned. It is possible to increase the maximum cardinality with qdb_option_set_max_cardinality().

For more information about queries, see quasardb queries.

6.5.19. Streaming

Use the streaming API to read or write portions of large entries in linear packets. There is no limit to the size of entries that can be streamed to or from the client. First, one should open the stream handle choosing an appropriate mode:

qdb_stream_t stream;
error = qdb_stream_open(handle, alias, qdb_stream_mode_append, &stream);
if (error)
{
    fprintf(stderr, "qdb_stream_open failed!\n");
    return error;
}

Then, you can stream in (write) as much data as you wish:

// const void * content; // possibly large amount of data
error = qdb_stream_write(stream, content, length_to_write);
if (error)
{
    fprintf(stderr, "qdb_stream_write failed!\n");
    break;
}

To get the current size of the stream, in bytes, there is qdb_stream_size():

qdb_stream_size_t size;
error = qdb_stream_size(stream, &size);
if (error)
{
    fprintf(stderr, "qdb_stream_size failed!\n");
    break;
}

6.5.20. Logging

It can be useful for debugging and information purposes to obtain all logs. The C API provides access to the internal log system through a callback which is called each time the API has to log something.

Warning

Improper usage of the logging API can seriously affect the performance and the reliability of the quasardb API. Make sure your logging callback is as simple as possible.

The thread and context in which the callback is called is undefined and the developer should not assume anything about the memory layout. However, calls to the callback are not concurrent: the user only has to take care of thread safety in the context of its application. In other words, calls are serialized.

Logging is asynchronous, however buffers are flushed when qdb_close() is successfully called.

The callback profile is the following:

typedef void (*qdb_log_callback)( //
    qdb_log_level_t log_level,    // qdb log level
    const unsigned long * date,   // [years, months, day, hours, minute, seconds] (valid only in the context of the callback)
    unsigned long pid,            // process id
    unsigned long tid,            // thread id
    const char * message_buffer,  // message buffer (valid only in the context of the callback)
    size_t message_size);         // message buffer size

The parameters passed to the callback are:

  • log_level: a qdb_log_level_t describing the log_level. The possible values are: qdb_log_detailed, qdb_log_debug, qdb_log_info, qdb_log_warning, qdb_log_error and qdb_log_panic.
  • date: an array of six unsigned longs describing the timestamp of the log message. They are ordered as such: year, month, day, hours, minutes, seconds. The time is in 24h format.
  • pid: the process id of the log message.
  • tid: the thread id of the log message.
  • message_buffer: a null-terminated buffer that is valid only in the context of the callback.
  • message_size: the size of the buffer, in bytes.

Here is a callback example:

void my_log_callback(qdb_log_level_t log_level,
    const unsigned long * date,
    unsigned long pid,
    unsigned long tid,
    const char * message_buffer,
    size_t message_size)
{
    // will print to the console the log message, e.g.
    // 12/31/2013-23:12:01    debug (   12: 1234): here is the message
    // note that you don't have to use all provided information, only use what you need!
    printf("%02lu/%02lu/%04lu-%02lu:%02lu:%02lu %8s (%5lu:%5lu): %.*s\n",
        date[1],
        date[2],
        date[0],
        date[3],
        date[4],
        date[5],
        get_log_level_as_string(log_level),
        pid,
        tid,
        (int)message_size,
        message_buffer);
}

Setting the callback is done with qdb_log_add_callback():

qdb_log_callback_id cid = 0;
error = qdb_log_add_callback(my_log_callback, &cid);

If you later wish to unregister the callback:

error = qdb_log_remove_callback(cid);

You may pass a null pointer as callback identifier to qdb_log_add_callback(), but then you will lose the possibility to unregister it.

// Giving no callback id prevents you from removing the callback in the future if the need be.
error = qdb_log_add_callback(my_log_callback, NULL);

Warning

Multiple calls to qdb_log_add_callback() will result in several callbacks being registered. Registering the same callback multiple times results in undefined behaviour.

6.5.21. Reference

General

const char* qdb_version(void)

Returns a null-terminated string describing the API version.

Return
A static, null-terminated string describing the API version. The buffer is API managed and should not be freed or written to by the caller.

const char* qdb_build(void)

Returns a null-terminated string describing the exact API build.

Return
A static, null-terminated string describing the exact API build. The buffer is API managed and should not be freed or written to by the caller.

qdb_error_t qdb_open(qdb_handle_t * handle, qdb_protocol_t proto)

Creates a qdb_handle_t. No connection will be established.

Return
A qdb_error_t code indicating success or failure.
See
qdb_connect, qdb_open_tcp, qdb_protocol_t
Parameters
  • handle: A pointer to a qdb_handle_t that will be ready to connect to a cluster.
  • proto: The protocol to use.

qdb_handle_t qdb_open_tcp(void)

Creates a TCP/IP qdb_handle_t. No connection will be established.

Return
An initialized qdb_handle_t, ready to connect, in case of success, NULL in case of failure.
See
qdb_connect, qdb_open

qdb_error_t qdb_connect(qdb_handle_t handle, const char * uri)

Binds the client instance to a quasardb cluster and connect to at least one node within.

Quasardb URI are in the form qdb://<address>:<port> where <address> is either an IPv4 or IPv6 (surrounded with square brackets), or a domain name. It is recommended to specify multiple addresses should the designated node be unavailable.

URI examples:

  • qdb://myserver.org:2836 - Connects to myserver.org on the port 2836
  • qdb://127.0.0.1:2836 - Connects to the local IPv4 loopback on the port 2836
  • qdb://myserver1.org:2836,myserver2.org:2836 - Connects to myserver1.org or myserver2.org on the port 2836
  • qdb://[::1]:2836 - Connects to the local IPv6 loopback on the port 2836

Return
A qdb_error_t code indicating success or failure.
See
qdb_open, qdb_open_tcp
Attention
Make sure all the addresses in the URI belong to the same cluster
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • uri: A pointer to a null-terminated UTF-8 string representing the URI of the quasardb cluster to connect to.

qdb_error_t qdb_close(qdb_handle_t handle)

Closes the handle previously opened with qdb_open or qdb_open_tcp.

This results in terminating all connections and releasing all internal buffers, including buffers which may have been allocated as or a result of batch operations or get operations.

Return
A qdb_error_t code indicating success or failure.
Attention
API-allocated buffers may be released by this call. For example, the buffer allocated by qdb_blob_get may be released by this call.
Parameters

qdb_error_t qdb_copy_alloc_buffer(qdb_handle_t handle, const void * source_buffer, qdb_size_t source_buffer_size, const void ** dest_buffer)

Creates a clone of a buffer using API’s high-performance memory allocator.

The allocated buffer has to be released later with qdb_release.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • source_buffer: A pointer to a buffer to clone
  • source_buffer_size: The size of the buffer to clone
  • dest_buffer: A pointer to a a pointer of an API-allocated buffer whose content will be a copy of the source buffer

void qdb_release(qdb_handle_t handle, const void * buffer)

Releases an API-allocated buffer.

Failure to properly call this function may result in excessive memory usage. Most operations that return a content (e.g. batch operations, qdb_blob_get, qdb_blob_get_and_update, qdb_blob_compare_and_swap...) will allocate a buffer for the content and will not release the allocated buffer until you either call this function or close the handle.

The function will be able to release any kind of buffer allocated by a quasardb API call, whether it’s a single buffer, an array or an array of buffers.

Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • buffer: A pointer to an API-allocated buffer to release. The behavior for non API buffers is undefined.

qdb_error_t qdb_remove(qdb_handle_t handle, const char * alias)

Removes an entry from the cluster, regardless of its type.

This call will remove the entry, whether it is a blob, integer, deque, stream or hset. It will properly untag the entry. If the entry spawns on multiple entries or nodes (deques, hsets and streams) all blocks will be properly removed.

The call is ACID, regardless of the type of the entry and a transaction will be created if need be.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.

qdb_error_t qdb_expires_at(qdb_handle_t handle, const char * alias, qdb_time_t expiry_time)

Sets the absolute expiration time of an entry, if the type supports expiration.

Blobs and integers can have an expiration time and will be automatically removed by the cluster when they expire.

The absolute expiration time is the Unix epoch, that is, the number of milliseconds since 1 January 1970, 00:00::00 UTC. To use a relative expiration time (that is expiration relative to the time of the call), use qdb_expires_from_now.

To remove the expiration time of an entry, specify the value qdb_never_expires as expiry_time parameter.

Values in the past are refused, but the cluster will have a certain tolerance to account for clock skews.

Return
A qdb_error_t code indicating success or failure.
Attention
It is an error to specify an expiration in the past, although the cluster has a certain tolerance to account for clock synchronization
See
qdb_expires_from_now
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • expiry_time: The new, absolute UTC expiration time.

qdb_error_t qdb_expires_from_now(qdb_handle_t handle, const char * alias, qdb_time_t expiry_delta)

Sets the expiration time of an entry, relative to the current time of the client, if the type supports expiration.

Blobs and integers can have an expiration time and will automatically be removed by the cluster when they expire.

The expiration is relative to the current time of the machine.

To remove the expiration time of an entry or to use an absolute expiration time use qdb_expires_at.

Return
A qdb_error_t code indicating success or failure.
See
qdb_expires_at
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • expiry_delta: The number of milliseconds, relative to the current time, after which the entry should expire.

qdb_error_t qdb_get_expiry_time(qdb_handle_t handle, const char * alias, qdb_time_t * expiry_time)

Retrieves the absolute expiration time of the given entry.

The returned expiration time is the Unix epoch, UTC.

Return
A qdb_error_t code indicating success or failure.
See
qdb_expires_from_now
See
qdb_expires_at
See
qdb_get_metadata
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • expiry_time: A pointer to an expiry time which will be set to the expiration of the entry if the call is successful.

qdb_error_t qdb_get_location(qdb_handle_t handle, const char * alias, qdb_remote_node_t * location)

Returns the primary node of an entry.

The exact location of an entry should be assumed random and users should not bother about its location as the API will transparently locate the best node for the requested operation.

This function is intended for higher level APIs that need to optimize transfers and potentially push computation close to the data.

This function allocates memory for the null terminated address string call qdb_release on the location structure to release memory.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release_buffer
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • location: A pointer to a qdb_remote_node_t structure that will receive the address of the primary node of the entry if successful

qdb_error_t qdb_get_type(qdb_handle_t handle, const char * alias, qdb_entry_type_t * entry_type)

Gets the type of an entry, if it exists.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_metadata
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • entry_type: A pointer to a qdb_entry_type_t that will receive the type of the entry if successful.

qdb_error_t qdb_get_metadata(qdb_handle_t handle, const char * alias, qdb_entry_metadata_t * entry_metadata)

Gets the meta-information about an entry, if it exists.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • entry_metadata: A pointer to a qdb_entry_metadata_t that will receive the metadata of the entry if successful.

qdb_error_t qdb_purge_all(qdb_handle_t handle, int timeout_ms)

Removes irremediably all data from all the nodes of the cluster.

This function is useful when quasardb is used as a cache and is not the golden source.

This call is not atomic: if the command cannot be dispatched on the whole cluster, it will be dispatched on as many nodes as possible and the function will return with a qdb_e_ok code.

By default cluster does not allow this operation and the function returns a qdb_e_operation_disabled error.

Return
A qdb_error_t code indicating success or failure.
Attention
Use this function at your own risk. This function causes irremediable data loss.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • timeout_ms: A timeout value, in milliseconds.

qdb_error_t qdb_trim_all(qdb_handle_t handle, int timeout_ms)

Trims all data on all the nodes of the cluster.

quasardb uses Multi-Version Concurrency Control (MVCC) as a foundation of its transaction engine. It will automatically clean up old versions as entries are accessed.

This call is not atomic: if the command cannot be dispatched on the whole cluster, it will be dispatched on as many nodes as possible and the function will return with a qdb_e_ok code.

Entries that are not accessed may not be cleaned up, resulting in increasing disk usage.

This function will request each nodes to trim all entries, release unused memory and compact files on disk. Because this operation is I/O and CPU intensive, it is not recommended to run it when the cluster is heavily used.

Return
A qdb_error_t code indicating success or failure.
Attention
This function impacts the performance of the cluster.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • timeout_ms: A timeout value, in milliseconds.

const char* qdb_error(qdb_error_t error)

Translates an error code into an English error message.

Return
A static, null-terminated string describing the error. The buffer is API managed and should not be freed or written to by the caller.
Parameters
  • error: The qdb_error_t code outputted by another function

qdb_error_t qdb_option_set_timeout(qdb_handle_t handle, int timeout_ms)

Sets the timeout of all network operations.

Return
A qdb_error_t code indicating success or failure.
Remark
The lower the timeout, the higher the risk of having timeout errors.
Parameters
  • handle: The qdb_handle_t that was initialized with qdb_open or qdb_open_tcp
  • timeout_ms: The timeout of network operation, in milliseconds.

qdb_error_t qdb_option_set_max_cardinality(qdb_handle_t handle, qdb_uint_t max_cardinality)

Sets the maximum allowed cardinality of a quasardb query. The default value is 100‘003. The minimum allowed values is 1,000.

Return
A qdb_error_t code indicating success or failure.
Remark
Improper usage of this function may cause a denial of service on the client.
Parameters
  • handle: The qdb_handle_t that was initialized with qdb_open or qdb_open_tcp
  • max_cardinality: The maximum cardinality of a query.

qdb_error_t qdb_option_set_compression(qdb_handle_t handle, qdb_compression_t comp_level)

Set the compression level for all future messages emitted by the specified handle. Regardless of this parameter, the API will be able to read whatever compression the server uses.

Return
A qdb_error_t code indicating success or failure.
See
qdb_compression_t
Remark
For better performance, consider disabling compression if your data is already compressed.
Parameters
  • handle: The handle on which to set the compression level
  • comp_level: The compression level to use

qdb_error_t qdb_tag_iterator_copy(const qdb_const_tag_iterator_t * original, qdb_const_tag_iterator_t * copy)

Clones a previously initialized tag iterator.

Copies the state of the original iterator to a new iterator. Both iterators can afterward be independently operated. The cloned iterator will have to be closed with qdb_tag_iterator_close.

See
qdb_tag_iterator_begin, qdb_tag_iterator_close

qdb_never_expires

An arbitrary time value representing the “no expiration” time value.

See
qdb_time_t

qdb_preserve_expiration

An arbitrary time value representing the “preserve existing expiration” time value.

See
qdb_time_t

enum client::qdb_limits

An enumeration of API limits.

Values:

qdb_l_alias_max_length = 1024

The maximum allowed length for aliases.

enum client::qdb_protocol

An enumeration of allowed network protocols.

See
qdb_open

Values:

qdb_p_tcp = 0

Uses TCP/IP to communicate with the cluster. This is currently the only supported network protocol.

enum client::qdb_entry_type

A enumeration representing possible entries type.

Values:

qdb_entry_uninitialized = -1

Uninitialized value.

qdb_entry_blob = 0

A binary large object (blob)

qdb_entry_integer = 1

A signed 64-bit integer.

qdb_entry_hset = 2

A distributed hash set.

qdb_entry_tag = 3

A tag.

qdb_entry_deque = 4

A distributed double-entry queue (deque)

qdb_entry_stream = 5

A distributed binary stream.

qdb_entry_ts = 6

A distributed time series.

enum client::qdb_compression

An enumeration of compression parameters.

See
qdb_option_set_compression

Values:

qdb_comp_none = 0

No compression.

qdb_comp_fast = 1

Maximum compression speed, potentially minimum compression ratio. This is currently the default.

qdb_comp_best = 2

Maximum compression ratio, potentially minimum compression speed. This is currently not implemented.

typedef qdb_time_t

A cross-platform type that represents a time value.

See
qdb_expires_at
Remark
qdb_time_t MUST be 64-bit large. The API will probably not link otherwise.

typedef qdb_size_t

An alias for size_t.

typedef qdb_int_t

A cross-platform type that represents a signed 64-bit integer.

typedef qdb_limits_t

A type alias for enum qdb_limits.

typedef qdb_protocol_t

A type alias for enum qdb_protocol.

See
qdb_open

typedef qdb_handle_t

An opaque handle to internal API-allocated structures needed for maintaining connection to a cluster.

typedef qdb_entry_type_t

A type alias for enum qdb_entry_type.

typedef qdb_compression_t

A type alias for enum qdb_compression.

See
qdb_option_set_compression

struct qdb_timespec_t
#include <client.h>

A structure representing an elapsed time since epoch (cross-platform equivalent of timespec structure)

struct qdb_remote_node_t
#include <client.h>

A structure representing the address of a quasardb node.

struct qdb_id_t
#include <client.h>

A cluster-wide unique identifier.

struct qdb_entry_metadata_t
#include <client.h>

A structure representing the metadata of an entry in the database.

Error codes

enum error::qdb_err_origin

The error origin.

Values:

qdb_e_origin_system_remote = (int) 0xf0000000
qdb_e_origin_system_local = (int) 0xe0000000
qdb_e_origin_connection = (int) 0xd0000000
qdb_e_origin_input = (int) 0xc0000000
qdb_e_origin_operation = (int) 0xb0000000
qdb_e_origin_protocol = (int) 0xa0000000
enum error::qdb_err_severity

An error severity level.

Values:

qdb_e_severity_unrecoverable = 0x03000000
qdb_e_severity_error = 0x02000000
qdb_e_severity_warning = 0x01000000
qdb_e_severity_info = 0x00000000
enum error::qdb_err

An error code indicating success or failure.

Values:

qdb_e_ok = 0
qdb_e_uninitialized = qdb_e_origin_input | qdb_e_severity_unrecoverable | 0xFFFF
qdb_e_alias_not_found = qdb_e_origin_operation | qdb_e_severity_warning | 0x0008
qdb_e_alias_already_exists = qdb_e_origin_operation | qdb_e_severity_warning | 0x0009
qdb_e_out_of_bounds = qdb_e_origin_input | qdb_e_severity_warning | 0x0019
qdb_e_skipped = qdb_e_origin_operation | qdb_e_severity_warning | 0x0021
qdb_e_incompatible_type = qdb_e_origin_operation | qdb_e_severity_warning | 0x0022
qdb_e_container_empty = qdb_e_origin_operation | qdb_e_severity_warning | 0x0023
qdb_e_container_full = qdb_e_origin_operation | qdb_e_severity_warning | 0x0024
qdb_e_element_not_found = qdb_e_origin_operation | qdb_e_severity_info | 0x0025
qdb_e_element_already_exists = qdb_e_origin_operation | qdb_e_severity_info | 0x0026
qdb_e_overflow = qdb_e_origin_operation | qdb_e_severity_warning | 0x0027
qdb_e_underflow = qdb_e_origin_operation | qdb_e_severity_warning | 0x0028
qdb_e_tag_already_set = qdb_e_origin_operation | qdb_e_severity_info | 0x0029
qdb_e_tag_not_set = qdb_e_origin_operation | qdb_e_severity_info | 0x002a
qdb_e_timeout = qdb_e_origin_connection | qdb_e_severity_error | 0x000a
qdb_e_connection_refused = qdb_e_origin_connection | qdb_e_severity_unrecoverable | 0x000e
qdb_e_connection_reset = qdb_e_origin_connection | qdb_e_severity_error | 0x000f
qdb_e_unstable_cluster = qdb_e_origin_connection | qdb_e_severity_error | 0x0012
qdb_e_try_again = qdb_e_origin_connection | qdb_e_severity_error | 0x0017
qdb_e_conflict = qdb_e_origin_operation | qdb_e_severity_error | 0x001a
qdb_e_not_connected = qdb_e_origin_connection | qdb_e_severity_error | 0x001b
qdb_e_resource_locked = qdb_e_origin_operation | qdb_e_severity_error | 0x002d
qdb_e_system_remote = qdb_e_origin_system_remote | qdb_e_severity_unrecoverable | 0x0001
qdb_e_system_local = qdb_e_origin_system_local | qdb_e_severity_unrecoverable | 0x0001
qdb_e_internal_remote = qdb_e_origin_system_remote | qdb_e_severity_unrecoverable | 0x0002
qdb_e_internal_local = qdb_e_origin_system_local | qdb_e_severity_unrecoverable | 0x0002
qdb_e_no_memory_remote = qdb_e_origin_system_remote | qdb_e_severity_unrecoverable | 0x0003
qdb_e_no_memory_local = qdb_e_origin_system_local | qdb_e_severity_unrecoverable | 0x0003
qdb_e_invalid_protocol = qdb_e_origin_protocol | qdb_e_severity_unrecoverable | 0x0004
qdb_e_host_not_found = qdb_e_origin_connection | qdb_e_severity_error | 0x0005
qdb_e_buffer_too_small = qdb_e_origin_input | qdb_e_severity_warning | 0x000b
qdb_e_not_implemented = qdb_e_origin_system_remote | qdb_e_severity_unrecoverable | 0x0011
qdb_e_invalid_version = qdb_e_origin_protocol | qdb_e_severity_unrecoverable | 0x0016
qdb_e_invalid_argument = qdb_e_origin_input | qdb_e_severity_error | 0x0018
qdb_e_invalid_handle = qdb_e_origin_input | qdb_e_severity_error | 0x001c
qdb_e_reserved_alias = qdb_e_origin_input | qdb_e_severity_error | 0x001d
qdb_e_unmatched_content = qdb_e_origin_operation | qdb_e_severity_info | 0x001e
qdb_e_invalid_iterator = qdb_e_origin_input | qdb_e_severity_error | 0x001f
qdb_e_entry_too_large = qdb_e_origin_input | qdb_e_severity_error | 0x002b
qdb_e_transaction_partial_failure = qdb_e_origin_operation | qdb_e_severity_error | 0x002c
qdb_e_operation_disabled = qdb_e_origin_operation | qdb_e_severity_error | 0x002e
qdb_e_operation_not_permitted = qdb_e_origin_operation | qdb_e_severity_error | 0x002f
qdb_e_iterator_end = qdb_e_origin_operation | qdb_e_severity_info | 0x0030
qdb_e_invalid_reply = qdb_e_origin_protocol | qdb_e_severity_unrecoverable | 0x0031
qdb_e_ok_created = qdb_e_origin_operation | qdb_e_severity_info | 0x0032
qdb_e_no_space_left = qdb_e_origin_system_remote | qdb_e_severity_unrecoverable | 0x0033
qdb_e_quota_exceeded = qdb_e_origin_system_remote | qdb_e_severity_error | 0x0034
qdb_e_alias_too_long = qdb_e_origin_input | qdb_e_severity_error | 0x0035
qdb_e_clock_skew = qdb_e_origin_system_remote | qdb_e_severity_error | 0x0036
qdb_e_access_denied = qdb_e_origin_operation | qdb_e_severity_error | 0x0037
qdb_e_login_failed = qdb_e_origin_system_remote | qdb_e_severity_error | 0x0038
qdb_e_column_not_found = qdb_e_origin_operation | qdb_e_severity_warning | 0x0039
qdb_e_query_too_complex = qdb_e_origin_operation | qdb_e_severity_error | 0x0040
qdb_e_invalid_crypto_key = qdb_e_origin_input | qdb_e_severity_error | 0x0041
typedef enum qdb_err_origin qdb_error_origin_t

The error origin.

typedef enum qdb_err_severity qdb_error_severity_t

An error severity level.

typedef enum qdb_err qdb_error_t

An error code indicating success or failure.

typedef qdb_error_t qdb_status_t

An alias for qdb_error_t.

QDB_ERROR_ORIGIN(x)

Extracts the origin out of a qdb_error_t.

QDB_ERROR_SEVERITY(x)

Extracts the severity out of a qdb_error_t.

QDB_SUCCESS(x)

True if and only if the qdb_error_t indicates a success.

QDB_FAILURE(x)

True if and only if the qdb_error_t indicates a failure.

Batches

qdb_error_t qdb_init_operations(qdb_operation_t * operations, size_t operation_count)

Initializes an array of qdb_operation_t.

Use this function to make sure all the fields of the operation structure are properly initialized to their default values.

After this function has been called, the user must then set the required parameter for each operation.

Return
A qdb_error_t code indicating success or failure.
See
qdb_operation_t
Parameters
  • operations: A pointer to an array of operations
  • operation_count: The number of elements in the array of operations

qdb_size_t qdb_run_batch(qdb_handle_t handle, qdb_operation_t * operations, size_t operation_count)

Runs the operations in batch.

When operations are run in batch the order of execution is optimized for speed and each operation is run independently.

Running operations is batch is generally the best way to achieve a very high level of performance, especially for bulk loading of data. That’s because batches minimize network communication and organize the order of execution for maximum throughput.

If one or several operations within the batch fail, the rest of the batch isn’t affected.

If one or several operations within the batch is ill-formed, the whole batch will be aborted. An ill formed operation is for example an operation missing a parameter.

Each operation will result a result according to its type.

After a batch has been run (successful or not), the user must call qdb_release on the operations pointer to release all API-allocated buffers.

For an ordered, transactional “all or nothing” behavior use qdb_run_transaction.

Return
The number of successful operations in the batch.
See
qdb_operation_t, qdb_run_transaction, qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • operations: A pointer to a correctly constructed array of operations
  • operation_count: The number of elements in the array of operations

qdb_error_t qdb_run_transaction(qdb_handle_t handle, qdb_operation_t * operations, size_t operation_count, size_t * failed_index)

Runs the operations in a single transaction.

Operations that run in a transaction will be executed ordered to preserve the logic of the transaction and if an error occurred the previously executed operations will be rolled back.

The operation is committed if and only if all operations have been successful.

The result of the transaction is not visible by other clients until it has been committed.

After a transaction has been run (successful or not), the user must call qdb_release on operations to release all API-allocated buffers.

Use transactions when integrity and order is paramount. For maximum performances consider using batches (qdb_run_batch).

Return
A qdb_error_t code indicating success or failure.
See
qdb_operation_t, qdb_run_batch, qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • operations: A pointer to a correctly constructed array of operations
  • operation_count: The number of elements in the array of operations
  • failed_index: A pointer to the index of the first failed operation

enum batch::qdb_operation_type

An enumeration of possible operation type.

Operations are used by batches and transactions.

Values:

qdb_op_uninitialized = -1

Unitialized value.

qdb_op_blob_get = 0

A blob get operation.

qdb_op_blob_put = 1

A blob put operation.

qdb_op_blob_update = 2

A blob update operation.

qdb_op_blob_cas = 4

A blob compare and swap operation.

qdb_op_blob_get_and_update = 5

A blob get and update.

qdb_op_has_tag = 8

Tag existence test operation.

qdb_op_int_put = 9

An integer put operation.

qdb_op_int_update = 10

An integer update operation.

qdb_op_int_get = 11

An integer get operation.

qdb_op_int_add = 12

An integer increase/decrease operation.

qdb_op_get_entry_type = 13

Entry type check.

struct int_put_update_t
#include <batch.h>

The required parameters for an integer operation within a batch.

struct blob_put_update_t
#include <batch.h>

The required parameters for a blob put or update operations within a batch.

struct qdb_operation_t
#include <batch.h>

A single operation containing all parameters to execute the operation in a batch or in a transaction.

You should initialize operations before usage with the qdb_init_operations function.

Blobs

qdb_error_t qdb_blob_get_noalloc(qdb_handle_t handle, const char * alias, void * content, qdb_size_t * content_length)

Retrieves an entry’s content from the quasardb server. The caller is responsible for allocating and freeing the provided buffer.

If the entry does not exist, the function will fail and return qdb_e_alias_not_found.

If the buffer is not large enough to hold the data, the function will fail and return qdb_e_buffer_too_small. content_length will nevertheless be updated with entry size so that the caller may resize its buffer and try again.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to a user-allocated buffer that will receive the entry’s content.
  • content_length: A pointer to a qdb_size_t initialized with the length of the destination buffer, in bytes. It will be updated with the length of the retrieved content, even if the buffer is not large enough to hold all the data.

qdb_error_t qdb_blob_get(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length)

Retrieves an entry’s content from the quasardb server.

If the entry does not exist, the function will fail and return qdb_e_alias_not_found.

The function will allocate a buffer large enough to hold the entry’s content. This buffer must be released by the caller with a call to qdb_release().

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to a pointer that will be set to a function-allocated buffer holding the entry’s content.
  • content_length: A pointer to a qdb_size_t that will be set to the content’s size, in bytes.

qdb_error_t qdb_reserved_blob_get(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length, qdb_size_t offset)

Retrieves a part of an entry’s content from the quasardb server.

If the entry does not exist, the function will fail and return qdb_e_alias_not_found.

The function will allocate a buffer large enough to hold the entry’s content. This buffer must be released by the caller with a call to qdb_release().

The returned content will be a subset of the entry’s data in the range [offset, offset + *content_length).

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to a pointer that will be set to a function-allocated buffer holding the entry’s content.
  • content_length: A pointer to a qdb_size_t that holds the length of the requested content and that will be set to the returned content’s size, in bytes. If content length is equal to zero or is greater than entry’s length minus offset, then all the content from offset until the end will be returned.
  • offset: Offset from which to get content, in bytes.

qdb_error_t qdb_blob_get_and_remove(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length)

Atomically gets an entry from the quasardb server and removes it.

If the entry does not exist, the function will fail and return qdb_e_alias_not_found.

The function will allocate a buffer large enough to hold the entry’s content. This buffer must be released by the caller with a call to qdb_release().

If the buffer is not large enough to hold the data, the function will fail and return qdb_e_buffer_too_small. content_length will nevertheless be updated with entry size so that the caller may resize its buffer and try again.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to a pointer that will be set to a function-allocated buffer holding the entry’s content.
  • content_length: A pointer to a qdb_size_t that will be set to the content’s size, in bytes.

qdb_error_t qdb_blob_put(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length, qdb_time_t expiry_time)

Creates a new entry and sets its content to the provided blob.

If the entry already exists the function will fail and will return qdb_e_alias_already_exists.

You can specify an expiry or use qdb_never_expires if you don’t want the entry to expire.

There is no software-defined limit to the size of blobs. To operate on entries that do not fit in RAM, consider using streams.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to the buffer with the blob content
  • content_length: The length of the buffer, in bytes
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.

qdb_error_t qdb_blob_update(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length, qdb_time_t expiry_time)

Creates or updates an entry and sets its content to the provided blob.

If the entry already exists, the function will modify the entry.

You can specify an expiry or use qdb_never_expires if you don’t want the entry to expire.

There is no software-defined limit to the size of blobs. To operate on entries that do not fit in RAM, consider using streams.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to the buffer with the blob content
  • content_length: The length of the buffer, in bytes
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.

qdb_error_t qdb_reserved_blob_merge(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length, qdb_size_t offset, int truncate, qdb_time_t expiry_time)

This function is reserved for internal use and its usage is discouraged.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • content: A pointer to the content to merge
  • content_length: The length of the buffer, in bytes
  • offset: Offset at which merge content
  • truncate: 1 - the entry will be truncated at the end of the new buffer. 0 - the original content will be preserved.
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.

qdb_error_t qdb_blob_get_and_update(qdb_handle_t handle, const char * alias, const void * update_content, qdb_size_t update_content_length, qdb_time_t expiry_time, const void ** get_content, qdb_size_t * get_content_length)

Atomically gets and updates (in this order) the entry on the quasardb server.

The entry must already exist.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • update_content: A pointer to the buffer with the new blob content
  • update_content_length: The length of the buffer, in bytes
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.
  • get_content: A pointer to a pointer to an API-allocated buffer holding the entry content, before the update.
  • get_content_length: A pointer to a qdb_size_t that will be set to the content’s size, in bytes.

qdb_error_t qdb_blob_compare_and_swap(qdb_handle_t handle, const char * alias, const void * new_value, qdb_size_t new_value_length, const void * comparand, qdb_size_t comparand_length, qdb_time_t expiry_time, const void ** original_value, qdb_size_t * original_value_length)

Atomically compares the entry with comparand and updates it to new_value if, and only if, they match.

The function returns the original value of the entry in case of a mismatch. When it matches, no content is returned.

The entry must already exist.

Update will occur if and only if the content of the entry matches bit for bit the content of the comparand buffer.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • new_value: A pointer to a buffer that represents the entry’s content to be updated to the server in case of match.
  • new_value_length: The length of the buffer, in bytes
  • comparand: A pointer to a buffer that represents the entry’s content to be compared to.
  • comparand_length: The length of the buffer, in bytes
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.
  • original_value: A pointer to a pointer that will be set to a function-allocated buffer holding the entry’s original content, before the update, if any.
  • original_value_length: A pointer to a qdb_size_t that will be set to the content’s size, in bytes.

qdb_error_t qdb_blob_remove_if(qdb_handle_t handle, const char * alias, const void * comparand, qdb_size_t comparand_length)

Atomically removes the entry on the server if the content matches.

The entry must already exist.

Removal will occur if and only if the content of the entry matches bit for bit the content of the comparand buffer.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • comparand: A pointer to a buffer to use a comparand
  • comparand_length: The length of the buffer, in bytes

qdb_error_t qdb_blob_scan(qdb_handle_t handle, const void * pattern, qdb_size_t pattern_length, qdb_int_t max_count, const char *** aliases, size_t * alias_count)

Retrieves all blobs that have content matching the specified pattern.

The complexity of this function is linear in the number of entries.

Warning
This function is experimental.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • pattern: A pointer to the pattern buffer to search for
  • pattern_length: The length of the pattern buffer, in bytes
  • max_count: An integer limiting the number of results returned by the function
  • aliases: A pointer to an array of null-terminated UTF-8 string that will list the aliases of the entries matching the requested pattern.
  • alias_count: A pointer to an integer that will receive the number of returned aliases.

qdb_error_t qdb_blob_scan_regex(qdb_handle_t handle, const char * pattern, qdb_int_t max_count, const char *** aliases, size_t * alias_count)

Retrieves all blobs that have content matching the specified regular expression (regex)

The complexity of this function is linear in the number of entries.

Warning
This function is experimental.

Return
A qdb_error_t code indicating success or failure.
See
http://ecma-international.org/ecma-262/5.1/#sec-15.10
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • pattern: A pointer to a null-terminated UTF-8 string representing the regular expression to search for. The regex syntax is defined by ECMA-262 grammar.
  • max_count: An integer limiting the number of results returned by the function
  • aliases: A pointer to an array of null-terminated UTF-8 string that will list the aliases of the entries matching the requested pattern.
  • alias_count: A pointer to an integer that will receive the number of returned aliases.

Cluster and nodes

qdb_error_t qdb_node_status(qdb_handle_t handle, const char * uri, const char ** content, qdb_size_t * content_length)

Returns the status of a node.

The API will request the node for its status and allocate a buffer of the appropriate size, which will later have to be released using qdb_release.

The status is JSON object and contains current information of the node state, as described in the documentation.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • uri: A pointer to a null-terminated UTF-8 string representing the URI of node for which the status is requested.
  • content: A pointer to the pointer of an API-allocated buffer holding the node status.
  • content_length: A pointer to an integer representing the size of the API-allocated buffer.

qdb_error_t qdb_node_config(qdb_handle_t handle, const char * uri, const char ** content, qdb_size_t * content_length)

Returns the configuration of a node.

The API will request the node for its configuration and allocate a buffer of the appropriate size, which will later have to be released using qdb_release.

The configuration is JSON object, as described in the documentation.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • uri: A pointer to a null-terminated UTF-8 string representing the URI of the node for which the configuration is requested.
  • content: A pointer to the pointer of an API-allocated buffer holding the node configuration.
  • content_length: A pointer to an integer representing the size of the API-allocated buffer.

qdb_error_t qdb_node_topology(qdb_handle_t handle, const char * uri, const char ** content, qdb_size_t * content_length)

Returns the topology of a node.

The API will request the node for its topology and allocate a buffer of the appropriate size, which will later have to be released using qdb_release.

The topology is JSON object containing the node address, and the addresses of its successor and predecessor.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • uri: A pointer to a null-terminated UTF-8 string representing the URI of node for which the topology is requested.
  • content: A pointer to the pointer of an API-allocated buffer holding the node topology.
  • content_length: A pointer to an integer representing the size of the API-allocated buffer.

qdb_error_t qdb_node_stop(qdb_handle_t handle, const char * uri, const char * reason)

Requests the node to gracefully stop.

Use this function to remotely stop a node, the supplied reason will be displayed in the logs of the remote node.

By default cluster do not allow this operation and the function will return a qdb_e_operation_disabled error.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • uri: A pointer to a null-terminated UTF-8 string representing the URI of node to be stopped.
  • reason: A pointer to a null-terminated UTF-8 string of the reason for the stop.

Deques

qdb_error_t qdb_deque_size(qdb_handle_t handle, const char * alias, qdb_size_t * size)

Returns the number of elements in a deque.

A double ended queue is transparently distributed accross the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

It is an error to call this function on a non existing deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • size: A pointer to an integer that will receive the size of the deque.

qdb_error_t qdb_deque_get_at(qdb_handle_t handle, const char * alias, qdb_int_t index, const void ** content, qdb_size_t * content_length)

Returns the element at the designated index.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

The index is zero-based starting at the first element (front) of the deque.

It is an error to call this function on a non existing deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • index: The zero-based index to the element of the deque
  • content: A pointer to a pointer to a buffer that will be API-allocated to receive the result of the operation, if successful
  • content_length: A pointer to the size of the API-allocated buffer

qdb_error_t qdb_deque_set_at(qdb_handle_t handle, const char * alias, qdb_int_t index, const void * content, qdb_size_t content_length)

Updates element at the designated index.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

There is no arbitrary limit to the size of an element within a deque.

The index is zero-based starting at the first element (front) of the deque.

It is an error to call this function on a non existing deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • index: The zero-based index to the element of the deque
  • content: A to a pointer to a buffer with the new content
  • content_length: The size of the buffer

qdb_error_t qdb_deque_push_front(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length)

Atomically appends an element to the front of the deque.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

There is no arbitrary limit to the size of an element within a deque.

Calling this function on a non-existing deque will create the deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • content: A to a pointer to a buffer with the new entry content
  • content_length: The size of the buffer

qdb_error_t qdb_deque_push_back(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length)

Atomically appends an element to the end of the deque.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

There is no arbitrary limit to the size of an element within a deque.

Calling this function on a non-existing deque will create the deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • content: A to a pointer to a buffer with the new entry content
  • content_length: The size of the buffer

qdb_error_t qdb_deque_pop_front(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length)

Atomically removes the element at the front of the deque and return its content.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

Removing the last element of the deque will not remove the entry but leave an empty deque.

It is an error to call this function on a non existing or empty deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • content: A pointer to a pointer to a buffer that will be API-allocated to receive the content of the first element, if successful
  • content_length: A pointer to the size of the API-allocated buffer

qdb_error_t qdb_deque_pop_back(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length)

Atomically remove the element at the end of the deque and return its content.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

Removing the last element of the deque will not remove the entry but leave an empty deque.

It is an error to call this function on a non existing or emtpy deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • content: A pointer to a pointer to a buffer that will be API-allocated to receive the content of the last element, if successful
  • content_length: A pointer to the size of the API-allocated buffer

qdb_error_t qdb_deque_front(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length)

Returns the content of the first element in the deque.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

It is an error to call this function on a non existing or empty deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • content: A pointer to a pointer to a buffer that will be API-allocated to receive the content of the first element, if successful
  • content_length: A pointer to the size of the API-allocated buffer

qdb_error_t qdb_deque_back(qdb_handle_t handle, const char * alias, const void ** content, qdb_size_t * content_length)

Returns the content of the last element in the deque.

A double ended queue is transparently distributed across the nodes and supports efficient insertion at the beginning and the end of the deque. Random access to the elements of the deque is also supported. Deques have no limit to the number of elements they may hold.

It is an error to call this function on a non existing or empty deque.

The complexity of this function is constant.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the deque.
  • content: A pointer to a pointer to a buffer that will be API-allocated to receive the content of the last element, if successful
  • content_length: A pointer to the size of the API-allocated buffer

Hash sets

qdb_error_t qdb_hset_insert(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length)

Inserts an element into the distributed hash set of the specified name.

A distributed hash set is transparently distributed over the nodes of the cluster. It does not have any limit on the number of entries.

If the set does not exist, it will be created.

If the entry is already present in the hset, the function will return qdb_e_element_already_exists.

Return
A qdb_error_t code indicating success or failure.
See
qdb_hset_erase, qdb_hset_contains
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the hset.
  • content: A pointer to a buffer holding the content to insert into the set.
  • content_length: The length of the buffer to insert into the set

qdb_error_t qdb_hset_erase(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length)

Removes an element from the distributed hash set.

A distributed hash set is transparently distributed over the nodes of the cluster. It does not have any limit on the number of entries.

The content must match bit for bit the inserted content to be considered equal.

It is an error to attempt to remove an element from a non-existing set.

If you remove the last element from the set, the set will be empty but not removed from the database.

If the entry is not present in the hset, the function will return qdb_e_element_not_found.

Return
A qdb_error_t code indicating success or failure.
See
qdb_hset_insert, qdb_hset_contains
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the hset.
  • content: A pointer to a buffer holding the content to remove from the set.
  • content_length: The length of the buffer to remove from the set

qdb_error_t qdb_hset_contains(qdb_handle_t handle, const char * alias, const void * content, qdb_size_t content_length)

Tests for the existence of an element in the distributed hash set.

A distributed hash set is transparently distributed over the nodes of the cluster. It does not have any limit on the number of entries.

The content must match bit for bit the inserted content to be considered equal.

It is an error to attempt to look for an element in a non-existing set.

If the entry is not present in the hset, the function will return qdb_e_element_not_found.

Return
A qdb_error_t code indicating success or failure.
See
qdb_hset_insert, qdb_hset_contains
Warning
This function is experimental.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the hset.
  • content: A pointer to a buffer holding the content to search for in the set.
  • content_length: The length of the buffer to remove from the set

Integers

qdb_error_t qdb_int_put(qdb_handle_t handle, const char * alias, qdb_int_t integer, qdb_time_t expiry_time)

Creates a new signed 64-bit integer.

Atomically creates an entry of the given alias and sets it to a cross-platform signed 64-bit integer. If the entry already exists, the function returns an error.

You can specify an expiry or use qdb_never_expires if you don’t want the entry to expire.

If you want to create or update an entry use qdb_int_update.

The value will be correctly translated independently of the endianness of the client’s platform.

Return
A qdb_error_t code indicating success or failure.
See
qdb_int_update, qdb_int_get, qdb_int_add
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • integer: The value to which the integer must be set.
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.

qdb_error_t qdb_int_update(qdb_handle_t handle, const char * alias, qdb_int_t integer, qdb_time_t expiry_time)

Creates or updates a signed 64-bit integer.

Atomically updates an entry of the given alias to the provided value. If the entry doesn’t exist, it will be created. If the entry is not an integer, the function will return qdb_e_incompatible_type.

You can specify an expiry time or use qdb_never_expires if you don’t want the entry to expire.

Return
A qdb_error_t code indicating success or failure.
See
qdb_int_put, qdb_int_get, qdb_int_add
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • integer: The value to which the integer must be set.
  • expiry_time: An optional absolute expiry time expressed in UTC UNIX epoch.

qdb_error_t qdb_int_get(qdb_handle_t handle, const char * alias, qdb_int_t * integer)

Retrieves the value of a signed 64-bit integer.

Atomically retrieves the value of an existing 64-bit integer.

If the entry is not an integer, the function will return qdb_e_incompatible_type.

Return
A qdb_error_t code indicating success or failure.
See
qdb_int_put, qdb_int_update, qdb_int_add
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • integer: A pointer to an integer that will receive the current value of the entry, if successful.

qdb_error_t qdb_int_add(qdb_handle_t handle, const char * alias, qdb_int_t addend, qdb_int_t * result)

Atomically increases or decreases a signed 64-bit integer.

The specified entry will be atomically increased (or decreased) according to the given addend value:

  • To increase the value, specify a positive addend
  • To decrease the value, specify a negative addend

The function return the result of the operation.

The entry must already exist. If the entry is not an integer, the function will return qdb_e_incompatible_type.

Return
A qdb_error_t code indicating success or failure.
See
qdb_int_put, qdb_int_update, qdb_int_get
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry.
  • addend: The value to add to the existing value.
  • result: A pointer to an integer that will receive the current value of the entry, if successful.

Iterators

qdb_error_t qdb_iterator_begin(qdb_handle_t handle, qdb_const_iterator_t * iterator)

Creates an iterator that points to the “first” entry of the cluster.

This function enables you to iterate on all the entries of a cluster. Keep in mind that there is no guarantee regarding the order of entries.

The iteration occurs at a fixed point in time, operations occurring after the iterator has been created will not be visible.

Call qdb_iterator_next to go to the next available entry, if any.

When iteration completes the function will return qdb_e_iterator_end and the user must call qdb_iterator_close to release client-allocated resources for the iteration.

Iteration does not allocate any resource on the server.

Whole cluster iteration is intended for some very specific use case. It is greatly advised to use tags to work on subgroup of entries.

Return
A qdb_error_t code indicating success or failure.
See
qdb_iterator_next, qdb_iterator_previous, qdb_iterator_close
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • iterator: A pointer to an uninitialized iterator structure that will be set to the first entry if successful

qdb_error_t qdb_iterator_rbegin(qdb_handle_t handle, qdb_const_iterator_t * iterator)

Creates an iterator that points to the “last” entry of the cluster.

This function enables you to iterate on all the entries of a cluster. Keep in mind that there is no guarantee regarding the order of entries.

This works exactly like qdb_iterator_begin, excepts it starts at the “end” of the cluster.

Call qdb_iterator_previous to go to the previous available entry, if any.

See qdb_iterator_begin for more information.

Return
A qdb_error_t code indicating success or failure.
See
qdb_iterator_begin, qdb_iterator_next, qdb_iterator_previous, qdb_iterator_close
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • iterator: A pointer to an uninitialized iterator structure that will be set to the last entry if successful

qdb_error_t qdb_iterator_next(qdb_const_iterator_t * iterator)

Advances an iterator to the next entry, if any.

Updates the iterator to point to the next available entry in the cluster. Although each entry is returned only once, the order in which entries are returned is undefined. If there is no following entry or it is otherwise unavailable, the function will return qdb_e_iterator_end.

See
qdb_iterator_begin
Parameters
  • iterator: A pointer to a previously initialized iterator.

qdb_error_t qdb_iterator_previous(qdb_const_iterator_t * iterator)

Advances an iterator to the previous entry, if any.

Updates the iterator to point to the previous available entry in the cluster. Although each entry is returned only once, the order in which entries are returned is undefined. If there is no previous entry or it is otherwise unavailable, the function will return qdb_e_iterator_end.

See
qdb_iterator_begin
Parameters
  • iterator: A pointer to a previously initialized iterator.

qdb_error_t qdb_iterator_close(qdb_const_iterator_t * iterator)

Closes a previously initialized iterator and releases all associated resources.

See
qdb_iterator_rbegin, qdb_iterator_begin
Parameters
  • iterator: A pointer to a previously initialized iterator.

qdb_error_t qdb_iterator_copy(const qdb_const_iterator_t * original, qdb_const_iterator_t * copy)

Clones a previously initialized iterator.

Copies the state of the original iterator to a new iterator. Both iterators can afterward be independently operated. The cloned iterator will have to be closed with qdb_iterator_close.

See
qdb_iterator_rbegin, qdb_iterator_begin, qdb_iterator_close

struct qdb_const_iterator_t
#include <iterator.h>

A read-only iterator on quasardb entries.

Log

qdb_error_t qdb_log_add_callback(qdb_log_callback cb, qdb_log_callback_id * callback_id)

Adds a callback that will receive internal API log messages. This can be used to incorporate internal API statuses in your log.

Return
A qdb_error_t code indicating success or failure.
See
qdb_log_callback, qdb_log_remove_callback
Parameters
  • cb: A callback of type qdb_log_callback. The callback will be called every time the API emits a log message
  • callback_id: A pointer to an unique callback identifier that can be used to remove the callback

qdb_error_t qdb_log_remove_callback(qdb_log_callback_id callback_id)

Removes a previously added log callback.

Return
A qdb_error_t code indicating success or failure.
See
qdb_log_callback, qdb_log_add_callback
Parameters
  • callback_id: The identifier set by qdb_log_add_callback that will determine which callback to remove

enum log::qdb_log_level

An enumeration of log level.

See
qdb_log_callback

Values:

qdb_log_detailed = 100

Log everything. Very verbose.

qdb_log_debug = 200

Log debug level messages and below.

qdb_log_info = 300

Log information level messages and below.

qdb_log_warning = 400

Log warning level messages and below.

qdb_log_error = 500

Log error level messages and below.

qdb_log_panic = 600

Log panic level messages and below. Very terse.

typedef qdb_log_level_t

A type alias for enum qdb_log_level.

See
qdb_open

typedef qdb_log_callback_id

An unique callback identifier returned by qdb_log_add_callback.

See
qdb_log_add_callback, qdb_log_remove_callback

typedef qdb_log_callback

A typedef representing a log callback.

See
qdb_log_add_callback, qdb_log_remove_callback

Prefix

qdb_error_t qdb_prefix_get(qdb_handle_t handle, const char * prefix, qdb_int_t max_count, const char *** results, size_t * result_count)

Retrieves the list of all entries matching the provided prefix.

A prefix-based search will enable you to find all entries matching a provided prefix.

This function returns the list of aliases. It’s up to the user to query the content associated with every entry, if needed.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • prefix: A pointer to a null-terminated UTF-8 string representing the desired prefix
  • max_count: An integer limiting the number of results returned by the function
  • results: A pointer to a list of results
  • result_count: A pointer to an integer giving the results count

qdb_error_t qdb_prefix_count(qdb_handle_t handle, const char * prefix, qdb_uint_t * result_count)

Retrieves the count of all entries matching the provided prefix.

A prefix-based count counts all entries matching a provided prefix.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • prefix: A pointer to a null-terminated UTF-8 string representing the desired prefix
  • result_count: A pointer to an integer giving the results count

Queries

qdb_error_t qdb_query(qdb_handle_t handle, const char * query, const char *** aliases, size_t * alias_count)

Retrieves all entries’ aliases that match the specified query.

For the complete grammar, please refer to the documentation.

Queries are transactional.

The complexity of this function is dependent on the complexity of the query.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • query: A pointer to a null-terminated UTF-8 string representing the query to perform.
  • aliases: A pointer to an array of null-terminated UTF-8 string that will list the aliases of the entries matching the query.
  • alias_count: A pointer to an integer that will receive the number of returned aliases.

Streams

qdb_error_t qdb_stream_open(qdb_handle_t handle, const char * alias, qdb_stream_mode_t mode, qdb_stream_t * stream)

Opens a stream in the specified mode.

Streams are distributed over the nodes of the cluster and have no limit in size.

After the stream is opened, the cursor is positioned at the beginning of the stream.

The caller must release API-allocated resources with qdb_stream_close when the handle is no longer required.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_close
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the stream to open.
  • mode: The mode in which the stream has to be open, read or read/write
  • stream: A pointer to a stream handle that will be initialized if the function is successful

qdb_error_t qdb_stream_close(qdb_stream_t stream)

Closes a previously opened stream.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters

qdb_error_t qdb_stream_read(qdb_stream_t stream, void * content, size_t * content_length)

Reads data from the stream.

Stream are distributed over the nodes of the cluster and have no limit in size.

The function will read at most content_length bytes from the stream and update the user-provided buffer accordingly.

The cursor will be positioned just after the last byte read.

If no data is available, content_length will be set to zero and no bytes will be read.

The user-provided buffer must be large enough to receive content_length bytes

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters
  • stream: A stream handle previously initialized with qdb_stream_open
  • content: A pointer to a user-allocated buffer that will receive the bytes read from the stream
  • content_length: A pointer to an integer set by the caller to the desired amount of bytes to read from the stream. After the function complete, it will be updated by the number of bytes actually read from the stream.

qdb_error_t qdb_stream_write(qdb_stream_t stream, const void * content, size_t content_length)

Writes data to the stream.

Stream are distributed over the nodes of the cluster and have no limit in size.

The function will write exactly the number of bytes specified by the user to the stream and position the cursor at the end of the written bytes.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters
  • stream: A stream handle previously initialized with qdb_stream_open
  • content: A pointer to a buffer with the content to add to the stream
  • content_length: The size of the buffer, in bytes

qdb_error_t qdb_stream_size(qdb_stream_t stream, qdb_stream_size_t * size)

Retrieves the total number of bytes written in a stream.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters
  • stream: A stream handle previously initialized with qdb_stream_open
  • size: A pointer to an integer that will receive the size of the stream, in bytes

qdb_error_t qdb_stream_getpos(qdb_stream_t stream, qdb_stream_size_t * position)

Retrieves the current position of the cursor within the stream.

The cursor is zero-based relative to the beginning of the stream.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters
  • stream: A stream handle previously initialized with qdb_stream_open
  • position: A pointer to an integer that will receive the position of the cursor relative to the beginning of the stream.

qdb_error_t qdb_stream_setpos(qdb_stream_t stream, qdb_stream_size_t position)

Sets the position of the cursor in the stream.

The cursor is zero-based relative to the beginning of the stream. The cursor may not point beyond the end of the stream.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters
  • stream: A stream handle previously initialized with qdb_stream_open
  • position: An integer specifying the new cursor value.

qdb_error_t qdb_stream_truncate(qdb_stream_t stream, qdb_stream_size_t position)

Truncates the stream at the specified position.

The position is zero-based relative to the beginning of the stream. The position may not point beyond the end of the stream.

Return
A qdb_error_t code indicating success or failure.
See
qdb_stream_open
Parameters
  • stream: A stream handle previously initialized with qdb_stream_open
  • position: An integer specifying the index at which the stream must be truncated.

enum stream::qdb_stream_mode_t

The possible modes in which a stream may be opened.

Values:

qdb_stream_mode_read = 0

Opens the stream in read only mode.

qdb_stream_mode_append = 1

Opens the stream in read and write mode Only one client at a time may open a stream for writing

typedef qdb_stream_size_t

A cross platform integer representing a stream size or position.

typedef qdb_stream_t

An opaque stream handle.

Suffix

qdb_error_t qdb_suffix_get(qdb_handle_t handle, const char * suffix, qdb_int_t max_count, const char *** results, size_t * result_count)

Retrieves the list of all entries matching the provided suffix.

A suffix-based search will enable you to find all entries matching a provided suffix.

This function returns the list of aliases. It’s up to the user to query the content associated with every entry, if needed.

Return
A qdb_error_t code indicating success or failure.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • suffix: A pointer to a null-terminated UTF-8 string representing the desired suffix
  • max_count: An integer limiting the number of results returned by the function
  • results: A pointer to a list of results
  • result_count: A pointer to an integer giving the results count

qdb_error_t qdb_suffix_count(qdb_handle_t handle, const char * suffix, qdb_uint_t * result_count)

Retrieves the count of all entries matching the provided suffix.

A suffix-based count counts all entries matching a provided suffix.

Return
A qdb_error_t code indicating success or failure.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • suffix: A pointer to a null-terminated UTF-8 string representing the desired suffix
  • result_count: A pointer to an integer giving the results count

Tags

qdb_error_t qdb_attach_tag(qdb_handle_t handle, const char * alias, const char * tag)

Adds a tag to an entry.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The entry must exist.

The tag may or may not exist.

Consider using qdb_attach_tags if you are adding several tags to the same entry.

Return
A qdb_error_t code indicating success or failure.
See
qdb_attach_tags, qdb_has_tag, qdb_detach_tag, qdb_get_tagged, qdb_get_tags
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry to which the tag must be added.
  • tag: A pointer to a null-terminated UTF-8 string representing the tag to add to the entry

qdb_error_t qdb_attach_tags(qdb_handle_t handle, const char * alias, const char *const * tags, size_t tag_count)

Adds a collection of tags to a single entry.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The function will ignore existing tags.

The entry must exist.

The tag may or may not exist.

Consider using qdb_attach_tag if you are adding a single tag.

Return
A qdb_error_t code indicating success or failure.
See
qdb_attach_tag, qdb_has_tag, qdb_detach_tags, qdb_get_tagged, qdb_get_tags
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry to which the tags must be added.
  • tags: A pointer to an array of null-terminated UTF-8 strings representing the tags to add to the entry
  • tag_count: The count of tags to add to the entry.

qdb_error_t qdb_has_tag(qdb_handle_t handle, const char * alias, const char * tag)

Tests if an entry has the request tag.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The entry must exist.

If you need to test several entries and/or several tags, consider using a batch for maximum performance.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_tagged, qdb_get_tags, qdb_run_batch
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry to which the tag must be tested.
  • tag: A pointer to a null-terminated UTF-8 string representing the tag for which presence must be tested

qdb_error_t qdb_detach_tag(qdb_handle_t handle, const char * alias, const char * tag)

Removes a tag from an entry.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The entry must exist.

The tag must exist.

Consider using qdb_detach_tags if you are removing several tags at once.

Return
A qdb_error_t code indicating success or failure.
See
qdb_detach_tags, qdb_get_tagged, qdb_get_tags
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry to which the tag must be remove.
  • tag: A pointer to a null-terminated UTF-8 string representing the tag to remove

qdb_error_t qdb_detach_tags(qdb_handle_t handle, const char * alias, const char *const * tags, size_t tag_count)

Removes a collection of tags from a single entry.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The entry must exist.

The tags must exist.

Consider using qdb_detach_tag if you are removing a single tag.

Return
A qdb_error_t code indicating success or failure.
See
qdb_detach_tag, qdb_get_tagged, qdb_get_tags
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry to which the tags must be removed.
  • tags: A pointer to an array of null-terminated UTF-8 strings representing the tags to remove.
  • tag_count: The count of tags to remove to the entry.

qdb_error_t qdb_get_tagged(qdb_handle_t handle, const char * tag, const char *** aliases, size_t * alias_count)

Retrieves all entries that have the specified tag.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The tag must exist.

The complexity of this function is constant.

Consider using qdb_tag_iterator_begin if you expect the number of entries to be very large.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_tags, qdb_tag_iterator_begin, qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • tag: A pointer to a null-terminated UTF-8 string representing the tag for which to search entries.
  • aliases: A pointer to an array of null-terminated UTF-8 string that will list the aliases of the entries having the requested tag.
  • alias_count: A pointer to an integer that will receive the number of returned aliases.

qdb_error_t qdb_get_tagged_count(qdb_handle_t handle, const char * tag, qdb_uint_t * count)

Computes the approximate count of all entries matching the specified tag, up to the configured max cardinality.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_tags, qdb_get_tagged, qdb_option_set_max_cardinality
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • tag: A pointer to a null-terminated UTF-8 string representing the tag for which to search entries.
  • count: A pointer to an integer that will receive the count of tags

qdb_error_t qdb_get_tags(qdb_handle_t handle, const char * alias, const char *** tags, size_t * tag_count)

Retrieves all the tags of an entry.

Tagging an entry enables you to search for entries based on their tags. Tags scale across nodes.

The entry must exist.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_tagged, qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the entry to which the tag must be added.
  • tags: A pointer to an array of null-terminated UTF-8 string that will list the tags of the entry
  • tag_count: A pointer to an integer that will receive the number of returned tags.

qdb_error_t qdb_tag_iterator_begin(qdb_handle_t handle, const char * tag, qdb_const_tag_iterator_t * iterator)

Creates an iterator that will point to the first entry having the the specified tag.

The order in which iteration occurs is unspecified, but entries matching a tag will never appear twice.

Only forward iteration is currently supported.

Once iteration terminates, the caller is responsible for releasing API-allocated resources with qdb_tag_iterator_close

If you expect the number of entries to be very small, you might consider using qdb_get_tagged.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_tagged, qdb_tag_iterator_next, qdb_tag_iterator_close
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • tag: A pointer to a null-terminated UTF-8 string representing the tag on which iteration is requested
  • iterator: A pointer to an uninitialized qdb_const_tag_iterator_t

qdb_error_t qdb_tag_iterator_next(qdb_const_tag_iterator_t * iterator)

Advance a previously initialized iterator to the next entry.

The order in which iteration occurs is unspecified, but entries matching a tag will never appear twice.

Only forward iteration is currently supported.

Once iteration terminates, the caller is responsible for releasing API-allocated resources with qdb_tag_iterator_close

If you expect the number of entries to be very small, you might consider using qdb_get_tagged.

Return
A qdb_error_t code indicating success or failure.
See
qdb_get_tagged, qdb_tag_iterator_begin, qdb_tag_iterator_close
Parameters

qdb_error_t qdb_tag_iterator_close(qdb_const_tag_iterator_t * iterator)

Releases all API-allocated resources during a previous iteration.

Once iteration terminates, the caller is responsible for releasing API-allocated resources with qdb_tag_iterator_close

Return
A qdb_error_t code indicating success or failure.
See
qdb_tag_iterator_begin
Parameters

struct qdb_const_tag_iterator_t
#include <tag.h>

An iterator to iterate on the entries matching a certain tag.

Time series

enum ts::qdb_ts_aggregation_type

Types of aggregations that can be computed on a time series.

Values:

qdb_agg_first = 0

The first (earliest) data point.

qdb_agg_last = 1

The last (latest) data point.

qdb_agg_min = 2

The data point with the smallest value.

qdb_agg_max = 3

The data point with the largest value.

qdb_agg_arithmetic_mean = 4

The arithmetic mean (average).

qdb_agg_harmonic_mean = 5

The harmonic mean.

qdb_agg_geometric_mean = 6

The geometric mean.

qdb_agg_quadratic_mean = 7

The quadratic mean (root mean squaer).

qdb_agg_count = 8

The number of data points.

qdb_agg_sum = 9

The sum of values.

qdb_agg_sum_of_squares = 10

The sum of squares of values.

qdb_agg_spread = 11

The difference between the maximum value and the minimum value.

qdb_agg_sample_variance = 12

The sample variance.

qdb_agg_sample_stddev = 13

The sample standard deviation.

qdb_agg_population_variance = 14

The population variance.

qdb_agg_population_stddev = 15

The population standard deviation.

qdb_agg_abs_min = 16

The value with the smallest absolute value.

qdb_agg_abs_max = 17

The value with the largest absolute value.

qdb_agg_product = 18

The product.

qdb_agg_skewness = 19

The skewness (shape parameter).

qdb_agg_kurtosis = 20

The kurtosis (shape parameter).

enum ts::qdb_ts_column_type

Types of time series columns.

Values:

qdb_ts_column_uninitialized = -1
qdb_ts_column_double = 0

Column of numeric values.

qdb_ts_column_blob = 1

Column of binary data.

typedef enum qdb_ts_aggregation_type qdb_ts_aggregation_type_t

Types of aggregations that can be computed on a time series.

typedef struct qdb_ts_double_aggregation qdb_ts_double_aggregation_t

Aggregation input and result for columns of numeric values.

typedef struct qdb_ts_blob_aggregation qdb_ts_blob_aggregation_t

Aggregation input and result for columns of blobs.

typedef enum qdb_ts_column_type qdb_ts_column_type_t

Types of time series columns.

typedef struct qdb_ts_column_info qdb_ts_column_info_t

Description of a time series column.

qdb_error_t qdb_ts_create(qdb_handle_t handle, const char * alias, const qdb_ts_column_info_t * columns, qdb_size_t column_count)

Creates a time series.

Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • columns: A pointer to an array of column descriptions that are to be added to the time series.
  • column_count: The number of columns to add.

qdb_error_t qdb_ts_list_columns(qdb_handle_t handle, const char * alias, qdb_ts_column_info_t ** columns, qdb_size_t * column_count)

Returns all the columns of a time series.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is still under development. Performance and compatibility are not guaranteed.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • columns: A pointer to an array that will contain descriptions of columns present in the time series.
  • column_count: A pointer to an integer that will receive the number of columns.

qdb_error_t qdb_ts_double_insert(qdb_handle_t handle, const char * alias, const char * column, const qdb_ts_double_point * values, qdb_size_t count)

Inserts points in a time series.

Time series are distributed across the cluster and support efficient insertion anywhere within the time series as well as efficient lookup based on time.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is still under development. Performance and compatibility are not guaranteed.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • column: A pointer to a null-terminated UTF-8 string representing the name of the column to work on.
  • values: A pointer to an array of data points to be inserted.
  • count: The number of data points to insert.

qdb_error_t qdb_ts_double_get_ranges(qdb_handle_t handle, const char * alias, const char * column, const qdb_ts_range_t * ranges, qdb_size_t range_count, qdb_ts_double_point ** points, qdb_size_t * point_count)

Retrieves doubles in the specified range of the time series column.

It is an error to call this function on a non existing time-series.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is still under development. Performance and compatibility are not guaranteed.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • column: A pointer to a null-terminated UTF-8 string representing the name of the column to work on.
  • ranges: A pointer to an array of ranges (intervals) for which data should be retrieved.
  • range_count: The number of ranges.
  • points: A pointer to an array that will contain data points from all given ranges.
  • point_count: A pointer to an integer that will receive the number of returned points.

qdb_error_t qdb_ts_double_aggregate(qdb_handle_t handle, const char * alias, const char * column, qdb_ts_double_aggregation_t * aggregations, qdb_size_t aggregation_count)

Aggregate a sub-part of the double column of the time series.

It is an error to call this function on a non existing time-series.

Return
A qdb_error_t code indicating success or failure.
See
qdb_ts_aggregation_type_t
Warning
This function is still under development. Performance and compatibility are not guaranteed.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • column: A pointer to a null-terminated UTF-8 string representing the name of the column to work on.
  • aggregations: A pointer to an array of structures representing the aggregations to compute and their results.
  • aggregation_count: The number of elements in the aggregations array.

qdb_error_t qdb_ts_blob_aggregate(qdb_handle_t handle, const char * alias, const char * column, qdb_ts_blob_aggregation_t * aggregations, qdb_size_t aggregation_count)

Aggregate a sub-part of a blob column of the time series.

It is an error to call this function on a non existing time-series.

Return
A qdb_error_t code indicating success or failure.
See
qdb_ts_aggregation_type_t
See
qdb_release
Warning
This function is still under development. Performance and compatibility are not guaranteed.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • column: A pointer to a null-terminated UTF-8 string representing the name of the column to work on.
  • aggregations: A pointer to an array of structures representing the aggregations to compute and their results.
  • aggregation_count: The number of elements in the aggregations array.

qdb_error_t qdb_ts_blob_insert(qdb_handle_t handle, const char * alias, const char * column, const qdb_ts_blob_point * values, qdb_size_t count)

Inserts blob in a time series column.

It is an error to call this function on a non existing time-series.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is still under development. Performance and compatibility are not guaranteed.
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • column: A pointer to a null-terminated UTF-8 string representing the name of the column to work on.
  • values: A pointer to an array of data points to be inserted.
  • count: The number of data points to insert.

qdb_error_t qdb_ts_blob_get_ranges(qdb_handle_t handle, const char * alias, const char * column, const qdb_ts_range_t * ranges, qdb_size_t range_count, qdb_ts_blob_point ** points, qdb_size_t * point_count)

Retrieves blobs in the specified range of the time series column.

It is an error to call this function on a non existing time-series.

Return
A qdb_error_t code indicating success or failure.
Warning
This function is still under development. Performance and compatibility are not guaranteed.
See
qdb_release
Parameters
  • handle: A valid handle previously initialized by qdb_open or qdb_open_tcp.
  • alias: A pointer to a null-terminated UTF-8 string representing the alias of the time series.
  • column: A pointer to a null-terminated UTF-8 string representing the name of the column to work on.
  • ranges: A pointer to an array of ranges (intervals) for which data should be retrieved.
  • range_count: The number of ranges.
  • points: A pointer to an array that will contain data points from all given ranges.
  • point_count: A pointer to an integer that will receive the number of returned points.

struct qdb_ts_double_point
#include <ts.h>

A timestamped data with a numeric value.

struct qdb_ts_blob_point
#include <ts.h>

A timestamped data with a binary content.

struct qdb_ts_range_t
#include <ts.h>

Time interval.

struct qdb_ts_double_aggregation
#include <ts.h>

Aggregation input and result for columns of numeric values.

struct qdb_ts_blob_aggregation
#include <ts.h>

Aggregation input and result for columns of blobs.

struct qdb_ts_column_info
#include <ts.h>

Description of a time series column.