2 * Copyright (C) 2007-2008 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file osl.h User interface for the object storage layer. */
11 /** Export all declarations in this file. */
12 #pragma GCC visibility push(default)
14 /** Describes an object of the object storage layer (osl) */
16 /** Pointer to the data of the object. */
18 /** The object's size. */
22 /** Flags that change the internal handling of osl tables. */
23 enum osl_table_flags {
24 /** This table will have many rows. */
28 /** The three different types of storage for an osl column */
29 enum osl_storage_type {
31 * All data for this column is stored in one file which gets mmapped by
32 * osl_open_table(). This is suitable for columns that do not hold much
37 * Each entry is stored on disk and is loaded on demand by
38 * open_disk_object(). This is the preferable storage type for large
39 * objects that need not be in memory all the time.
43 * Objects for columns of this type are volatile: They are only stored
44 * in memory and are discarded once the table gets closed.
50 * Additional per-column flags
52 enum osl_storage_flags {
54 * Build an rbtree for this column. This is only possible if the
55 * storage type of the column is either \a OSL_MAPPED_STORAGE or \a
56 * OSL_NO_STORAGE. In order to lookup objects in the table by using \a
57 * osl_get_row(), the lookup column must have an associated rbtree.
59 * \sa osl_storage_type, osl_get_row()
62 /** The data for this column will have constant size. */
64 /** All values of this column will be different. */
66 /** Do not free the data for this column (\p OSL_NO_STORAGE). */
70 /** Opaque osl table structure. */
72 /** Opaque osl row structure. */
76 * In order to build up an rbtree a compare function for the objects must be
77 * specified. Such a function always takes pointers to the two objects to be
78 * compared. It must return -1, zero, or 1, if the first argument is considered
79 * to be respectively less than, equal to, or greater than the second. If two
80 * members compare as equal, their order in the sorted array is undefined.
82 typedef int osl_compare_func(const struct osl_object *obj1,
83 const struct osl_object *obj2);
86 * The osl_rbreee_loop functions take a function pointer of this type. For each
87 * node in the rbtree, the given function is called.
89 * \sa osl_rbtree_loop(), osl_rbtree_loop_reverse().
91 typedef int osl_rbtree_loop_func(struct osl_row *row, void *data);
94 * Describes one column of a osl table.
96 struct osl_column_description {
97 /** One of the tree possible types of storage */
98 enum osl_storage_type storage_type;
99 /** Specifies further properties of the column */
100 enum osl_storage_flags storage_flags;
102 * The column name determines the name of the directory where all data
103 * for this column will be stored. Its hash is stored in the table
104 * header. This field is ignored if the storage type is \a NO_STORAGE
108 * For columns with an associated rbtree, this must point to a function
109 * that compares the values of two objects, either a built-in function
110 * or a function defined by the application may be supplied. This
111 * field is ignored if the column does not have an associated rbtree.
113 * \sa osl_storage_flags, osl_compare_func
115 osl_compare_func *compare_function;
117 * If the \a OSL_FIXED_SIZE flag is set for this column, this value
118 * determines the fixed size of all objects of this column. It is
119 * ignored, if \a OSL_FIXED_SIZE is not set.
125 * Describes one osl table.
127 struct osl_table_description {
128 /** The directory which contains all files of this table. */
131 * The table name. A subdirectory of \a dir called \a name is created
132 * at table creation time. It must be a valid name for a subdirectory.
133 * In particular, no slashes are allowed for \a name.
136 /** The number of columns of this table. */
137 uint16_t num_columns;
138 /** Further table-wide information. */
139 enum osl_table_flags flags;
140 /** The array describing the individual columns of the table. */
141 struct osl_column_description *column_descriptions;
144 /** Flags to be passed to \a osl_close_table(). */
145 enum osl_close_flags {
147 * The table header contains a "dirty" flag which specifies whether
148 * the table is currently open by another process. This flag specifies
149 * that the dirty flag should be cleared before closing the table.
153 * If the table contains columns of type \a OSL_NO_STORAGE and this
154 * flag is passed to osl_close_table(), free(3) is called for each
155 * object of each column of type \a OSL_NO_STORAGE.
157 OSL_FREE_VOLATILE = 2
161 * Create a new osl table.
163 * \param desc Pointer to the table description.
167 int osl_create_table(const struct osl_table_description *desc);
172 * Each osl table must be opened before its data can be accessed.
174 * \param table_desc Describes the table to be opened.
175 * \param result Contains a pointer to the open table on success.
177 * The table description given by \a desc should coincide with the
178 * description used at creation time.
182 int osl_open_table(const struct osl_table_description *desc,
183 struct osl_table **result);
186 * Close an osl table.
188 * \param t Pointer to the table to be closed.
189 * \param flags Options for what should be cleaned up.
191 * If osl_open_table() succeeds, the resulting table pointer must later be
192 * passed to this function in order to flush all changes to the file system and
193 * to free the resources that were allocated by osl_open_table().
197 * \sa osl_open_table(), unmap_table().
199 int osl_close_table(struct osl_table *t, enum osl_close_flags flags);
202 * Get the row that contains the given object.
204 * \param t Pointer to an open osl table.
205 * \param col_num The number of the column to be searched.
206 * \param obj The object to be looked up.
207 * \param result Points to the row containing \a obj.
209 * Lookup \a obj in \a t and return the row containing \a obj. The column
210 * specified by \a col_num must have an associated rbtree.
214 * \sa osl_storage_flags
216 int osl_get_row(const struct osl_table *t, unsigned col_num,
217 const struct osl_object *obj, struct osl_row **result);
220 * Retrieve an object identified by row and column
222 * \param t Pointer to an open osl table.
223 * \param r Pointer to the row.
224 * \param col_num The column number.
225 * \param object The result pointer.
227 * The column determined by \a col_num must be of type \p OSL_MAPPED_STORAGE
228 * or \p OSL_NO_STORAGE, i.e. no disk storage objects may be retrieved by this
233 * \sa osl_storage_type, osl_open_disk_object().
235 int osl_get_object(const struct osl_table *t, const struct osl_row *row,
236 unsigned col_num, struct osl_object *object);
239 * Retrieve an object of type \p OSL_DISK_STORAGE by row and column.
241 * \param t Pointer to an open osl table.
242 * \param r Pointer to the row containing the object.
243 * \param col_num The column number.
244 * \param obj Points to the result upon successful return.
246 * For columns of type \p OSL_DISK_STORAGE, this function must be used to
247 * retrieve one of its containing objects. Afterwards, osl_close_disk_object()
248 * must be called in order to deallocate the resources.
252 * \sa osl_get_object(), osl_storage_type, osl_close_disk_object().
254 int osl_open_disk_object(const struct osl_table *t,
255 const struct osl_row *r, unsigned col_num, struct osl_object *obj);
258 * Free resources that were allocated during osl_open_disk_object().
260 * \param obj Pointer to the object previously returned by open_disk_object().
262 * \return The return value of the underlying call to munmap().
266 int osl_close_disk_object(struct osl_object *obj);
269 * Add a new row to an osl table and retrieve this row.
271 * \param t Pointer to an open osl table.
272 * \param objects Array of objects to be added.
273 * \param row Result pointer.
275 * The \a objects parameter must point to an array containing one object per
276 * column. The order of the objects in the array is given by the table
277 * description of \a table. Several sanity checks are performed during object
278 * insertion and the function returns without modifying the table if any of
279 * these tests fail. In fact, it is atomic in the sense that it either
280 * succeeds or leaves the table unchanged (i.e. either all or none of the
281 * objects are added to the table).
283 * It is considered an error if an object is added to a column with associated
284 * rbtree if this object is equal to an object already contained in that column
285 * (i.e. the compare function for the column's rbtree returns zero).
289 * \sa struct osl_table_description, osl_compare_func, osl_add_row().
291 int osl_add_and_get_row(struct osl_table *t, struct osl_object *objects,
292 struct osl_row **row);
296 * Add a new row to an osl table.
298 * \param t Same meaning as osl_add_and_get_row().
299 * \param objects Same meaning as osl_add_and_get_row().
301 * \return The return value of the underlying call to osl_add_and_get_row().
303 * This is equivalent to osl_add_and_get_row(t, objects, NULL).
305 int osl_add_row(struct osl_table *t, struct osl_object *objects);
308 * Delete a row from an osl table.
310 * \param t Pointer to an open osl table.
311 * \param row Pointer to the row to delete.
313 * This removes all disk storage objects, removes all rbtree nodes, and frees
314 * all volatile objects belonging to the given row. For mapped columns, the
315 * data is merely marked invalid and may be pruned from time to time by
320 int osl_del_row(struct osl_table *t, struct osl_row *row);
323 * Loop over all nodes in an rbtree.
325 * \param t Pointer to an open osl table.
326 * \param col_num The column to use for iterating over the elements.
327 * \param private_data Pointer that gets passed to \a func.
328 * \param func The function to be called for each node in the rbtree.
330 * This function does an in-order walk of the rbtree associated with \a
331 * col_num. It is an error if the \p OSL_RBTREE flag is not set for this
332 * column. For each node in the rbtree, the given function \a func is called
333 * with two pointers as arguments: The first osl_row* argument points to the
334 * row that contains the object corresponding to the rbtree node currently
335 * traversed, and the \a private_data pointer is passed verbatim to \a func as the
336 * second argument. The loop terminates either if \a func returns a negative
337 * value, or if all nodes of the tree have been visited.
340 * \return Standard. If the termination of the loop was caused by \a func
341 * returning a negative value, \p -E_OSL_LOOP is returned.
343 * \sa osl_storage_flags, osl_rbtree_loop_reverse(), osl_compare_func.
345 int osl_rbtree_loop(const struct osl_table *t, unsigned col_num,
346 void *private_data, osl_rbtree_loop_func *func);
349 * Loop over all nodes in an rbtree in reverse order.
351 * \param t Identical meaning as in \p osl_rbtree_loop().
352 * \param col_num Identical meaning as in \p osl_rbtree_loop().
353 * \param private_data Identical meaning as in \p osl_rbtree_loop().
354 * \param func Identical meaning as in \p osl_rbtree_loop().
356 * This function is identical to \p osl_rbtree_loop(), the only difference
357 * is that the tree is walked in reverse order.
359 * \return The same return value as \p osl_rbtree_loop().
361 * \sa osl_rbtree_loop().
363 int osl_rbtree_loop_reverse(const struct osl_table *t, unsigned col_num,
364 void *private_data, osl_rbtree_loop_func *func);
367 * Change an object in an osl table.
369 * \param t Pointer to an open osl table.
370 * \param r Pointer to the row containing the object to be updated.
371 * \param col_num Number of the column containing the object to be updated.
372 * \param obj Pointer to the replacement object.
374 * This function gets rid of all references to the old object. This includes
375 * removal of the rbtree node in case there is an rbtree associated with \a
376 * col_num. It then inserts \a obj into the table and the rbtree if necessary.
378 * If the \p OSL_RBTREE flag is set for \a col_num, you \b MUST call this
379 * function in order to change the contents of an object, even for volatile or
380 * mapped columns of constant size (which may be updated directly if \p
381 * OSL_RBTREE is not set). Otherwise the rbtree might become corrupted.
385 int osl_update_object(struct osl_table *t, const struct osl_row *r,
386 unsigned col_num, struct osl_object *obj);
389 * Get the number of rows of the given table.
391 * \param t Pointer to an open osl table.
392 * \param num_rows Result is returned here.
394 * The number of rows returned via \a num_rows excluding any invalid rows.
396 * \return Positive on success, \p -E_OSL_BAD_TABLE if \a t is \p NULL.
398 int osl_get_num_rows(const struct osl_table *t, unsigned *num_rows);
402 * Get the row corresponding to the smallest rbtree node of a column.
404 * \param t An open rbtree table.
405 * \param col_num The number of the rbtree column.
406 * \param result A pointer to the first row is returned here.
408 * The rbtree node of the smallest object (with respect to the corresponding
409 * compare function) is selected and the row containing this object is
410 * returned. It is an error if \a col_num refers to a column without an
415 * \sa osl_get_nth_row(), osl_rbtree_last_row().
417 int osl_rbtree_first_row(const struct osl_table *t, unsigned col_num,
418 struct osl_row **result);
421 * Get the row corresponding to the greatest rbtree node of a column.
423 * \param t The same meaning as in \p osl_rbtree_first_row().
424 * \param col_num The same meaning as in \p osl_rbtree_first_row().
425 * \param result The same meaning as in \p osl_rbtree_first_row().
427 * This function works just like osl_rbtree_first_row(), the only difference
428 * is that the row containing the greatest rather than the smallest object is
433 * \sa osl_get_nth_row(), osl_rbtree_first_row().
435 int osl_rbtree_last_row(const struct osl_table *t, unsigned col_num,
436 struct osl_row **result);
439 * Get the row with n-th greatest value.
441 * \param t Pointer to an open osl table.
442 * \param col_num The column number.
443 * \param n The rank of the desired row.
444 * \param result Row is returned here.
446 * Retrieve the n-th order statistic with respect to the compare function
447 * of the rbtree column \a col_num. In other words, get that row with
448 * \a n th greatest value in column \a col_num. It's an error if
449 * \a col_num is not a rbtree column, or if \a n is larger than the
450 * number of rows in the table.
454 * \sa osl_storage_flags, osl_compare_func, osl_get_row(),
455 * osl_rbtree_last_row(), osl_rbtree_first_row(), osl_get_rank().
457 int osl_get_nth_row(const struct osl_table *t, unsigned col_num,
458 unsigned n, struct osl_row **result);
461 * Get the rank of a row.
463 * \param t An open osl table.
464 * \param r The row to get the rank of.
465 * \param col_num The number of an rbtree column.
466 * \param rank Result pointer.
468 * The rank is, by definition, the position of the row in the linear order
469 * determined by an in-order tree walk of the rbtree associated with column
470 * number \a col_num of \a table.
474 * \sa osl_get_nth_row().
476 int osl_get_rank(const struct osl_table *t, struct osl_row *r,
477 unsigned col_num, unsigned *rank);
480 * Compare two osl objects pointing to hash values.
482 * \param obj1 Pointer to the first hash object.
483 * \param obj2 Pointer to the second hash object.
485 * \return The values required for an osl compare function.
487 * \sa osl_compare_func, uint32_compare().
489 int osl_hash_compare(const struct osl_object *obj1,
490 const struct osl_object *obj2);
493 * Get a string describing the error code passed in the argument.
495 * \param num The error code.
497 * This works just like strerror(3). The given number must be an osl error
498 * code. The result must not be freed by the caller.
500 * \return The error text corresponding to an osl error code.
502 const char *osl_strerror(int num);
504 #pragma GCC visibility pop