Struct PntosKeyValueStore

Struct Documentation

struct PntosKeyValueStore

A key-value store implemented with a string-pair key. Each value can be looked up by an associated key (string). Values can be a variety of different types, depending on which typed function is called. For example, to store a string value “foo” in the key-value store under the key “k1”, one would write:

store->set_str(store, "k1", "foo");
At this point, the key-value store would have recorded the value into its internal data storage. Later a user could call
store->get_str(store, "k1");
To retrieve the value from the store.

In general, a PntosKeyValueStore is generated by a PntosRegistry and not directly by other code. The PntosRegistry will return key/value stores on demand, utilizing the data backing store chosen by the plugin to store data (either ephemerally in memory or permanently in persistent storage). In general, it is only valid to call the getters/setters on a PntosKeyValueStore during a batch operation. See PntosRegistry for more information.

Public Members

PntosManagedMemory *memory
PntosStringArray *(*get_key_array)(struct PntosKeyValueStore *self)

Get the array of keys which currently exist in this store. Returns NULL if no keys are available.

bool (*has_key)(struct PntosKeyValueStore *self, char *key)

Returns whether or not a given key exists in the store.

PntosKeyValueStoreType (*get_type)(struct PntosKeyValueStore *self, char *key)

If the key exists in the store, returns the type corresponding to the setter which set the value in the store. The type information is returned as a PntosKeyValueStoreType enum. Returns PNTOS_KV_STORE_KEY_DNE if key does not exist. Some implementations may choose not to implement this function (leaving the function as a null pointer), so always check if this function exists before using it.

UNSTABLE: This feature is unstable and is not yet considered part of the stable pntOS API. Usage of this feature is highly discouraged in non-experimental code, and its definition may change at any time.

PntosString *(*get_str)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key as a string. Returns NULL if the key is not available. The return is guaranteed to not be NULL if called with a valid key, which can be checked with has_key.

PntosStringArray *(*get_str_array)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key parsed into an array of strings. Returns NULL if the key is not available. The return is guaranteed to not be NULL if called with a valid key, which can be checked with has_key.

int64_t (*get_int)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key as a 64-bit integer. If it is not known whether key exists, has_key should be used to determine the existence of the key before this function is called (as this function does not return NULL). This function will attempt to return INT64_MAX if the key does not exist, however users should not rely on this behavior to determine if a key is available.

bool (*get_bool)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key as a boolean. If it is not known whether key exists, has_key should be used to determine the existence of the key before this function is called. This function will attempt to return false if the key does not exist, however users should not rely on this behavior to determine if a key is available.

double (*get_double)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key as a double. If the key is not available, returns a NaN value.

PntosDoubleArray *(*get_double_array)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key parsed into an array of doubles. Returns NULL if the key is not available. The return is guaranteed to not be NULL if called with a valid key, which can be checked with has_key.

PntosMessage *(*get_message)(struct PntosKeyValueStore *self, char *key)

Get the value stored at key as a pointer to a PntosMessage. Returns NULL if the key is not available or if the value of the stored PntosMessage pointer is NULL.

void (*set_str)(struct PntosKeyValueStore *self, char *key, char *value)

Set the given key to the provided value.

void (*set_str_array)(struct PntosKeyValueStore *self, char *key, char **values, size_t num_values)

Set the given key to the provided value. num_values must be greater than zero. values is an array of \0 terminated strings. The length of the values array is given by num_values. num_values must be greater than zero.

void (*set_int)(struct PntosKeyValueStore *self, char *key, int64_t value)

Set the given key to the provided value.

void (*set_bool)(struct PntosKeyValueStore *self, char *key, bool value)

Set the given key to the provided value.

void (*set_double)(struct PntosKeyValueStore *self, char *key, double value)

Set the given key to the provided value.

void (*set_double_array)(struct PntosKeyValueStore *self, char *key, double *values, size_t num_values)

Set the given key to the provided array of doubles values. num_values must be greater than zero. The length of the values array is given by num_values.

void (*set_message)(struct PntosKeyValueStore *self, char *key, PntosMessage *message)

Set the given key to the provided value. A reference to the given message will be held until set_message is called again with the same key or the program ends. set_message can be called with a NULL message to release the reference to the message previously stored in the given key.

bool (*remove_key)(struct PntosKeyValueStore *self, char *key)

Remove the given key from the registry. Returns true if key is successfully removed, and false otherwise. Keys may fail to be removed if the key does not currently exist, or the backend is unable to remove the key.

PntosKeyValueStoreDataFormat data_format

The data format that is used by the set_raw and get_raw methods.

void (*set_raw)(struct PntosKeyValueStore *self, char *key, unsigned char *bytes, size_t num_bytes)

Set the given key to the provided value. bytes must be formatted to conform to the definition of a value in data_format.

If key is NULL, then the contents of bytes must include both keys and values and must be formatted to conform to data_format. bytes will then be used to set the corresponding keys and values in the group passed to PntosRegistry.batch_start.

num_bytes is the length in bytes of bytes.

PntosByteArray *(*get_raw)(struct PntosKeyValueStore *self, char *key)

Get the value for the given key as an array of bytes. The format of PntosByteArray.data will conform to the definition of a value in data_format. Returns NULL if the given key is not available. The return is guaranteed to not be NULL if called with a valid key, which can be checked with has_key.

If key is NULL, then this function will return all of the keys and values in the group passed to PntosRegistry.batch_start and will be formatted to conform to keys and values as defined in data_format.

void (*batch_end)(struct PntosKeyValueStore *self)

Ends a batch operation started with a PntosRegistry.batch_start call. After calling this, the user should not use the PntosKeyValueStore they received from PntosRegistry.batch_start again without calling batch_restart on the PntosKeyValueStore.

If keys in the batch were acted upon with set_permanent turned on, and the plugin supports permanent storage, this call will save changes to permanent storage if set_permanent is true during the call to batch_end. Enacts equivalent of set_permanent(self,false) before return. If any request_notify observers have been added, they will be processed prior to this call returning.

Example: Flushing to permanent storage on batch_end

 PntosKeyValueStore* store = registry->batch_start("group");
 ...work...
 store->set_permanent(store,true) ; // if not disabled, flush on batch_end
 ...work...
 store->batch_end(store)          ; // will flush values
Example: Not flushing to permanent storage on batch_end
 PntosKeyValueStore* store = registry->batch_start("group");
 ...work...
 store->set_permanent(store,true)  ; // tag some values
 ...work...
 store->set_permanent(store,false) ; // do not flush on batch_nd
 store->batch_end(store)           ; // will not flush values
In the second example above, values set with “set” methods after the initial set_permanent call are still stored for potential saving to permanent storage.

void (*batch_restart)(struct PntosKeyValueStore *self)

Restarts a batch that was previously started with PntosRegistry.batch_start and subsequently ended with batch_end. This method is likely much more efficient than PntosRegistry.batch_start (depending on the registry implementation) as the PntosRegistry.batch_start method must find the store again given the group name.

Note

While a batch is active, access to the store may be denied to other users. Thus a user should endeavour to call batch_end as soon as possible after they are done getting/setting values in the returned PntosKeyValueStore.

bool (*request_notify)(struct PntosKeyValueStore *self, char *key, void *receiver, void (*callback)(void *receiver, char *modified_group, char **modified_keys, size_t num_modified_keys, struct PntosKeyValueStore *modified_values))

Register a callback which gets called each time a key in the store is updated. Allows plugins to respond asynchronously to parameter updates. Returns true if the notifier was successfully registered, and false if the store is unable to notify the requester. If key is null, then the callback will be invoked when any key in the batch’s group is modified. Otherwise, the callback will only be invoked when the given key is modified. The receiver argument, if non-NULL, will be passed through to the callback’s receiver parameter when the callback is invoked. The receiver argument is designed to allow the caller of request_notify to pass a context object through, such that the same context object is available when the callback is run.

The modified_keys parameter passed to the callback is an array of num_modified_keys \0 terminated strings. The modified_group and modified_keys parameters to the callback are the group and list of keys that were modified respectively. modified_values is a PntosKeyValueStore which can be interrogated for the values of the modified keys given in modified_keys.

Note

The callback must not attempt to set any values inside the PntosKeyValueStore, as the callback is likely being invoked during the processing of another operation. The callback should endeavour to store off the updated keys/values as quickly as possible and return, leaving the processing of the updates to another context or thread when possible. Calling PntosMediator within the callback may be disallowed by the controller implementation and lead to undefined behavior.

Note

This method will retain the receiver beyond the lifetime of the function call, as the purpose of that parameter is to pass it back later in the callback. However, the PntosKeyValueStore will never dereference the pointer, and thus it is safe to pass in a receiver that does not survive longer than the lifetime of the function call, as long as the callback checks for validity of the receiver before using it.

bool (*remove_notify)(struct PntosKeyValueStore *self, char *key, void *receiver, void (*callback)(void *receiver, char *modified_group, char **modified_keys, size_t num_modified_keys, struct PntosKeyValueStore *modified_values))

Removes a notification as requested by request_notify. The group, receiver, and callback must match the parameters passed to request_notify in order to successfully remove a callback.

Returns true if removal was successful and false if it was not. false will be returned if a callback did not exist for the group/receiver combination.

Note

This will remove all matching callbacks that have a matching group, receiver, and callback. If a user registers the same callback twice this will remove both.

bool (*set_permanent)(struct PntosKeyValueStore *self, bool permanent)

Configure the PntosKeyValueStore to tag values modified with “set” methods as permanently stored (as opposed to ephemerally stored in memory). Only values acted upon with “set” methods while set_permanent is ‘true’ will be tagged. Values will be flushed according to registry configuration settings or per batch_end API. Returns the value of the permanent storage configuration. Callers should check this to verify if the set was successful.

Example: Tagging specific keys to be permanently stored

 PntosKeyValueStore* store = registry->batch_start("group");
 store->set_double("key1",1234.56);  // does not tag this value as permanently stored
 store->set_permanent(store,true) ;  // start tagging set* calls as permanently stored
 store->set_double("key1",987.65) ;
 store->set_int("key2",123)       ;  // both key1 and key2 values tagged
 store->set_permanent(store,false);  // disable permanent storage
 store->set_double("key1",456.78) ;  // key1 = 456.78 is value of key1 in store
                                     // key1 = 987.65 tagged to be permanently stored
                                     // key2 = 123    tagged to be permanently stored