--- /dev/null
+VERBATIM_C(«
+/*
+ * Copyright (C) 2007-2009 Andre Noll <maan@tuebingen.mpg.de>
+ *
+ * Licensed under the GPL v2. For licencing details see COPYING.
+ */
+
+/* User interface for the object storage layer. */
+
+#include <sys/mman.h>
+#include <inttypes.h>
+
+/* Export all declarations in this file. */
+#pragma GCC visibility push(default)
+»)
+
+DECLARE_COMPOUND(
+ «struct osl_object»,
+ «Describes an object of the object storage layer.»,
+ «»,
+ «
+ «void *data», «Pointer to the data of the object.»,
+ «size_t size», «The object's size.»
+ »
+)
+
+DECLARE_ENUM(
+ «osl_table_flags»,
+ «Flags that change the internal handling of osl tables.»,
+ «»,
+ «
+ «OSL_LARGE_TABLE = 1»,
+ «This table will have many rows.»
+ »
+)
+
+DECLARE_ENUM(
+ «osl_storage_type»,
+ «The three different types of storage for an osl column.»,
+ «»,
+ «
+ «OSL_MAPPED_STORAGE»,
+ «All data for this column is stored in one file which gets mmapped
+ by osl_open_table(). This is suitable for columns that do not hold
+ much data.»,
+
+ «OSL_DISK_STORAGE»,
+ «Each entry is stored on disk and is loaded on demand by
+ open_disk_object(). This is the preferable storage type for large
+ objects that need not be in memory all the time.»,
+
+ «OSL_NO_STORAGE»,
+ «Objects for columns of this type are volatile: They are only stored
+ in memory and are discarded when the table is closed.»
+ »
+)
+
+DECLARE_ENUM(
+ «osl_storage_flags»,
+ «Additional per-column flags.»,
+ «»,
+ «
+ «OSL_RBTREE = 1»,
+ «Build an rbtree for this column. This is only possible if the storage
+ type of the column is either OSL_MAPPED_STORAGE or OSL_NO_STORAGE. In
+ order to lookup objects in the table by using osl_get_row(), the
+ lookup column must have an associated rbtree.
+
+ See also: osl_storage_type, osl_get_row()»,
+
+ «OSL_FIXED_SIZE = 2»,
+ «The data for this column will have constant size.»,
+
+ «OSL_UNIQUE = 4»,
+ «All values are different. Must be set if OSL_RBTREE is set.»,
+
+ «OSL_DONT_FREE = 8»,
+ «Do not free the data for this column (OSL_NO_STORAGE).»
+ »
+)
+
+STATEMENT(
+ «struct osl_table»,
+ «Opaque osl table structure.»
+)
+
+STATEMENT(
+ «struct osl_row»,
+ «Opaque osl row structure.»
+)
+
+STATEMENT(
+ «typedef int osl_compare_func(const struct osl_object *obj1, const struct osl_object *obj2)»,
+ «Comparator for rbtree nodes.»,
+ «To build an rbtree, a compare function for the objects must be
+ provided. This function takes pointers to the two objects to be
+ compared. It must return -1, zero, or 1, if the first argument is
+ considered to be respectively less than, equal to, or greater than
+ the second. If two members compare as equal, their order in the rbtree
+ is undefined.»
+)
+
+STATEMENT(
+ «typedef int osl_rbtree_loop_func(struct osl_row *row, void *data)»,
+ «Loop callback function.»,
+ «The osl_rbreee_loop functions take a function pointer of this
+ type. For each node in the rbtree, the given function is called.
+
+ See also: osl_rbtree_loop(), osl_rbtree_loop_reverse().»
+)
+
+DECLARE_COMPOUND(
+ «struct osl_column_description»,
+ «Describes one column of an osl table.»,
+ «», «
+ «uint16_t storage_type»,
+ «One of the three possible types of storage. See also:
+ osl_storage_type.»,
+
+ «uint16_t storage_flags»,
+ «Specifies further properties of the column. See also:
+ osl_storage_flags.»,
+
+ «char *name»,
+ «The column name determines the name of the directory where all
+ data for this column will be stored. Its hash is stored in the table
+ header. This field is ignored if the storage type is NO_STORAGE.»,
+
+ «osl_compare_func *compare_function»,
+ «For columns with an associated rbtree, this must point to a function
+ that compares the values of two objects, either a built-in function
+ or a function defined by the application may be supplied. This field
+ is ignored if the column does not have an associated rbtree.
+
+ See also: osl_storage_flags, osl_compare_func»,
+
+ «uint32_t data_size»,
+ «If the OSL_FIXED_SIZE flag is set for this column, this value
+ describes the number of bytes of each object of this column. It is
+ ignored, if OSL_FIXED_SIZE is not set.»
+ »
+)
+
+DECLARE_COMPOUND(
+ «struct osl_table_description»,
+ «Describes one osl table.»,
+ «A pointer to the table description is passed to osl_create_table()
+ and osl_open_table(). The osl library calls which operate on an
+ open table refer to the fields of the table description through this
+ pointer. Hence the table description must not be modified or freed
+ before the table is closed.»,
+
+ «
+ «const char *dir»,
+ «The directory which contains all files of this table. This may be
+ either relative to the cwd or an absolute path.»,
+
+ «const char *name»,
+ «The table name. A subdirectory of dir called name is created at
+ table creation time. It must be a valid name for a subdirectory.
+ In particular, no slashes are allowed in the name.»,
+
+ «uint16_t num_columns»,
+ «The number of columns of this table.»,
+
+ «uint8_t flags»,
+ «Further table-wide information, see osl_table_flags.»,
+
+ «struct osl_column_description *column_descriptions»,
+ «The array describing the individual columns of the table.»
+ »
+)
+
+DECLARE_ENUM(
+ «osl_close_flags»,
+ «Flags to be passed to osl_close_table().»,
+ «»,
+ «
+ «OSL_MARK_CLEAN = 1»,
+ «The table header contains a "dirty" flag which indicates whether the
+ table is currently held open by another process. The OSL_MARK_CLEAN
+ flag instructs libosl to clear the dirty flag when the table is
+ closed.»,
+
+ «OSL_FREE_VOLATILE = 2»,
+ «If the table contains columns of type OSL_NO_STORAGE and this flag
+ is passed to osl_close_table(), free(3) is called for each object of
+ each column of type OSL_NO_STORAGE.»
+ »
+)
+
+DECLARE_FUNCTION(
+ «osl_create_table»,
+ «Create a new osl table.»,
+ «»,
+ «
+ «const struct osl_table_description *desc»,
+ «Pointer to the table description»
+ »,
+ «»,
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_open_table»,
+ «Open an osl table.»,
+ «An osl table must be opened before its data can be accessed.»,
+ «
+ «const struct osl_table_description *desc»,
+ «Describes the table to be opened»,
+
+ «struct osl_table **result»,
+ «Contains a pointer to the open table on success.»
+ »,
+ «The table description given by desc should coincide with the
+ description used at creation time.»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_close_table»,
+ «Close an osl table.»,
+ «»,
+ «
+ «struct osl_table *t»,
+ «Pointer to the table to be closed.»,
+
+ «enum osl_close_flags flags»,
+ «Options for what should be cleaned up.»
+ »,
+ «If osl_open_table() succeeds, the resulting table pointer must
+ later be passed to this function in order to flush all changes to
+ the file system and to free the resources that were allocated by
+ osl_open_table().»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_get_row»,
+ «Get the row that contains the given object.»,
+ «»,
+ «
+ «const struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «unsigned col_num»,
+ «The number of the column to be searched»,
+
+ «const struct osl_object *obj»,
+ «The object to be looked up»,
+
+ «struct osl_row **result»,
+ «Points to the row containing the given object»
+ »,
+ «Lookup the given object and return the row containing it. The column
+ specified by col_num must have an associated rbtree.»,
+
+ «int»,
+ «Standard. The result pointer is set to NULL if and only if the
+ function returns negative.»
+)
+
+DECLARE_FUNCTION(
+ «osl_get_object»,
+ «Retrieve an object identified by row and column.»,
+ «»,
+ «
+ «const struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «const struct osl_row *row»,
+ «Pointer to the row»,
+
+ «unsigned col_num»,
+ «The column number»,
+
+ «struct osl_object *object»,
+ «The result pointer»
+ »,
+ «The column determined by col_num must be of type OSL_MAPPED_STORAGE
+ or OSL_NO_STORAGE, i.e. no disk storage objects may be retrieved by
+ this function.
+
+ See also: osl_storage_type, osl_open_disk_object().»,
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_open_disk_object»,
+ «Retrieve an object of type OSL_DISK_STORAGE by row and column.»,
+ «For columns of type OSL_DISK_STORAGE this function must be
+ used to retrieve one of its containing objects. Afterwards,
+ osl_close_disk_object() must be called in order to deallocate the
+ resources.»,
+
+ «
+ «const struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «const struct osl_row *r»,
+ «Pointer to the row containing the object»,
+
+ «unsigned col_num»,
+ «The column number»,
+
+ «struct osl_object *obj»,
+ «Points to the result upon successful return»
+ »,
+ «See also: osl_get_object(), osl_storage_type,
+ osl_close_disk_object().»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_close_disk_object»,
+ «Free resources allocated during osl_open_disk_object().», «
+ », «
+ «struct osl_object *obj»,
+ «Pointer to the object previously returned by open_disk_object()»
+ »,
+ «»,
+ «int», «The return value of the underlying call to munmap(2)»
+)
+
+DECLARE_FUNCTION(
+ «osl_add_and_get_row»,
+ «Add a new row to an osl table and retrieve this row.»,
+ «»,
+ «
+ «struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «struct osl_object *objects»,
+ «Array of objects to be added»,
+
+ «struct osl_row **row»,
+ «Result pointer»
+ »,
+ «The objects parameter must point to an array containing one object
+ per column. The order of the objects in the array is given by the
+ table description of the table. Several sanity checks are performed
+ during object insertion and the function returns without modifying the
+ table if any of these tests fail. In fact, it is atomic in the sense
+ that it either succeeds or leaves the table unchanged (i.e. either
+ all or none of the objects are added to the table).
+
+ See also: struct osl_table_description, osl_compare_func,
+ osl_add_row().»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_add_row»,
+ «Add a new row to an osl table.»,
+ «»,
+ «
+ «struct osl_table *t»,
+ «Same meaning as osl_add_and_get_row()»,
+
+ «struct osl_object *objects»,
+ «Same meaning as osl_add_and_get_row()»
+ »,
+ «This is equivalent to calling osl_add_and_get_row(t, objects,
+ NULL);»,
+
+ «int»,
+ «The return value of the underlying call to osl_add_and_get_row()»
+)
+
+DECLARE_FUNCTION(
+ «osl_del_row»,
+ «Delete a row from an osl table.»,
+ «»,
+ «
+ «struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «struct osl_row *row»,
+ «Pointer to the row to delete»
+ »,
+ «This removes all disk storage objects, removes all rbtree nodes,
+ and frees all volatile objects belonging to the given row. For mapped
+ columns, the data is merely marked invalid and may be pruned from
+ time to time by oslfsck(1).»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_rbtree_loop»,
+ «Loop over all nodes in an rbtree.»,
+ «»,
+ «
+ «const struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «unsigned col_num»,
+ «The column to use for iterating over the elements»,
+
+ «void *private_data»,
+ «Pointer that gets passed to the callback function»,
+
+ «osl_rbtree_loop_func *func»,
+ «This callback is called for each node in the rbtree.»
+ »,
+ «This function does an in-order walk of the rbtree associated with
+ col_num. It is an error if the OSL_RBTREE flag is not set for this
+ column. For each node in the rbtree, the given function func is called
+ with two pointers as arguments: The first osl_row* argument points
+ to the row that contains the object corresponding to the rbtree node
+ currently traversed, and the private_data pointer is passed verbatim as
+ the second argument. The loop terminates either if the callback returns
+ a negative value, or if all nodes of the tree have been visited.»,
+
+ «int»,
+ «Standard. If the termination of the loop was caused by the callback
+ returning a negative value, -E_OSL_LOOP is returned. This is the only
+ possible error.»
+)
+
+DECLARE_FUNCTION(
+ «osl_rbtree_loop_reverse»,
+ «Loop over all nodes in an rbtree in reverse order.»,
+ «This function is identical to osl_rbtree_loop(), the only difference
+ is that the tree is walked in reverse order.»,
+ «
+ «const struct osl_table *t»,
+ «See osl_rbtree_loop()»,
+
+ «unsigned col_num»,
+ «See osl_rbtree_loop()»,
+
+ «void *private_data»,
+ «See osl_rbtree_loop()»,
+
+ «osl_rbtree_loop_func *func»,
+ «See osl_rbtree_loop()»
+ »,
+ «See also: osl_rbtree_loop().»,
+ «int»,
+ «The same return value as osl_rbtree_loop()»
+)
+
+DECLARE_FUNCTION(
+ «osl_update_object»,
+ «Change an object of an osl table.»,
+ «»,
+ «
+ «struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «const struct osl_row *r»,
+ «Pointer to the row containing the object to be updated»,
+
+ «unsigned col_num»,
+ «Number of the column containing the object to be updated»,
+
+ «struct osl_object *obj»,
+ «Pointer to the replacement object»
+ »,
+ «This function gets rid of all references to the old object. This
+ includes removal of the rbtree node in case there is an rbtree
+ associated with col_num. It then inserts obj into the table and the
+ rbtree if necessary.»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_get_num_rows»,
+ «Get the number of rows of the given table.»,
+ «»,
+ «
+ «const struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «unsigned *num_rows»,
+ «Result is returned here»
+ »,
+ «The number of rows returned excludes any invalid rows.»,
+
+ «int»,
+ «Positive on success, -E_OSL_BAD_TABLE if t is NULL»
+)
+
+DECLARE_FUNCTION(
+ «osl_rbtree_first_row»,
+ «Get the row corresponding to the smallest rbtree node of a column.»,
+ «»,
+ «
+ «const struct osl_table *t»,
+ «An open table»,
+
+ «unsigned col_num»,
+ «The number of the rbtree column»,
+
+ «struct osl_row **result»,
+ «A pointer to the first row is returned here»
+ »,
+ «The rbtree node of the smallest object (with respect to the
+ corresponding compare function) is selected and the row containing
+ this object is returned. It is an error if col_num refers to a column
+ without an associated rbtree.
+
+ See also: osl_get_nth_row(), osl_rbtree_last_row().»,
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_rbtree_last_row»,
+ «Get the row corresponding to the greatest rbtree node of a column.»,
+ «This function works just like osl_rbtree_first_row(), the only
+ difference is that the row containing the greatest rather than the
+ smallest object is returned.»,
+
+ «
+ «const struct osl_table *t»,
+ «See osl_rbtree_first_row()»,
+
+ «unsigned col_num»,
+ «See osl_rbtree_first_row()»,
+
+ «struct osl_row **result»,
+ «See osl_rbtree_first_row()»
+ »,
+ «See also: osl_get_nth_row(), osl_rbtree_first_row()»,
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_get_nth_row»,
+ «Get the row with n-th greatest value.»,
+ «»,
+ «
+ «const struct osl_table *t»,
+ «Pointer to an open osl table»,
+
+ «unsigned col_num»,
+ «The column number»,
+
+ «unsigned n»,
+ «The rank of the desired row»,
+
+ «struct osl_row **result»,
+ «Row is returned here»
+ »,
+ «Retrieve the n-th order statistic with respect to the compare
+ function of the rbtree column col_num. In other words, get the row
+ with n-th greatest value in column col_num. It is an error if col_num
+ is not a rbtree column, or if n is larger than the number of rows in
+ the table.»,
+
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_get_rank»,
+ «Get the rank of a row.»,
+ «The rank is, by definition, the position of the row in the linear
+ order determined by an in-order tree walk of the rbtree associated
+ with given column number.»,
+
+ «
+ «const struct osl_table *t»,
+ «An open osl table»,
+
+ «struct osl_row *r»,
+ «The row to get the rank of»,
+
+ «unsigned col_num»,
+ «The number of an rbtree column»,
+
+ «unsigned *rank»,
+ «Result pointer»
+ »,
+ «See also: osl_get_nth_row().»,
+ «int»,
+ «Standard»
+)
+
+DECLARE_FUNCTION(
+ «osl_strerror»,
+ «Get a string describing the error code passed in the argument.»,
+ «»,
+ «
+ «int num»,
+ «The error code»
+ »,
+ «This works just like strerror(3). The given number must be an osl
+ error code. The result must not be freed by the caller.»,
+
+ «const char *»,
+ «The error text corresponding to an osl error code»
+)
+
+VERBATIM_C(«
+#pragma GCC visibility pop
+»)