2 * Copyright (C) 2007 Andre Noll <maan@systemlinux.org>
4 * Licensed under the GPL v2. For licencing details see COPYING.
7 /** \file osl_core.h Object storage layer details, not visible to users. */
14 /** Internal representation of a column of an osl table. */
16 /** The memory mapping of this comumn (only used for mapped columns). */
17 struct osl_object data_map
;
18 /** The root of the rbtree (only used for columns with rbtrees). */
19 struct rb_root rbtree
;
20 /** The index in the array of rb nodes (only used for columns with rbtrees). */
22 /** Index for volatile_objects of struct osl_row. */
23 unsigned volatile_num
;
25 * Starting point of the data for this column within the index
26 * (only used for mapped columns).
28 uint16_t index_offset
;
30 * The hash value of the name of this column.
32 * This is only used for mapped and disk storage columns).
34 HASH_TYPE name_hash
[HASH_SIZE
];
37 /** Internal representation of an osl table */
39 /** Pointer to the table description */
40 const struct osl_table_description
*desc
;
41 /** The size of the index header of this table. */
42 uint16_t index_header_size
;
43 /** Contains the mapping of the table's index file */
44 struct osl_object index_map
;
45 /** Total number of rows, including invalid rows. */
47 /** Keeps track of the number of invalid rows in the table. */
48 uint32_t num_invalid_rows
;
49 /** Number of columns of type \p OSL_MAPPED_STORAGE. */
50 unsigned num_mapped_columns
;
51 /** Number of columns of type \p OSL_NO_STORAGE. */
52 unsigned num_volatile_columns
;
53 /** Number of columns of type \p OSL_DISK_STORAGE. */
54 unsigned num_disk_storage_columns
;
55 /** Number of columns with associated rbtree. */
58 * The number of the column that determines the name of the disk
61 unsigned disk_storage_name_column
;
62 /** The number of bytes of an index entry of a row. */
63 unsigned row_index_size
;
64 /** Pointer to the internal representation of the columns. */
65 struct osl_column
*columns
;
68 /** Internal representation of a row of an osl table */
73 * It is only used if there is at least one mapped column.
76 /** Array of size \a num_volatile_columns. */
77 struct osl_object
*volatile_objects
;
80 int read_table_desc(struct osl_object
*map
, struct osl_table_description
*desc
);
81 int init_table_structure(const struct osl_table_description
*desc
,
82 struct osl_table
**table_ptr
);
83 int row_is_invalid(struct osl_table
*t
, uint32_t row_num
);
84 int get_mapped_object(const struct osl_table
*t
, unsigned col_num
,
85 uint32_t row_num
, struct osl_object
*obj
);
86 int para_truncate(const char *filename
, off_t size
);
87 int unmap_table(struct osl_table
*t
, enum osl_close_flags flags
);
88 int init_rbtrees(struct osl_table
*t
);
91 * Flags to be specified for map_table().
95 enum map_table_flags
{
97 * Check whether the entries in the table index match the entries in
98 * the table desctiption.
100 MAP_TBL_FL_VERIFY_INDEX
= 1,
101 /** Do not complain even if the dirty flag is set. */
102 MAP_TBL_FL_IGNORE_DIRTY
= 2,
103 /** Use read-only mappings. */
104 MAP_TBL_FL_MAP_RDONLY
= 4
107 int map_table(struct osl_table
*t
, enum map_table_flags flags
);
108 void clear_rbtrees(struct osl_table
*t
);
109 int mark_row_invalid(struct osl_table
*t
, uint32_t row_num
);
113 * Get the description of a column by column number
115 * \param d Pointer to the table description.
116 * \param col_num The number of the column to get the desctiption for.
118 * \return The table description.
120 * \sa struct osl_column_description.
122 _static_inline_
struct osl_column_description
*get_column_description(
123 const struct osl_table_description
*d
, unsigned col_num
)
125 return &d
->column_descriptions
[col_num
];
129 * Format of the header of the index file of an osl table.
131 * Bytes 16-31 are currently unused.
133 * \sa enum index_column_desc_offsets, HASH_SIZE, osl_table_flags.
135 enum index_header_offsets
{
136 /** Bytes 0-8: PARASLASH. */
138 /** Byte 9: Dirty flag (nonzero if table is mapped). */
140 /** Byte 10: osl table version number. */
142 /** Byte 11: Table flags.*/
143 IDX_TABLE_FLAGS
= 11,
144 /** Byte 12,13: Number of columns. */
146 /** Byte 14,15 Size of the index header. */
147 IDX_HEADER_SIZE
= 14,
148 /** Column descriptions start here. */
149 IDX_COLUMN_DESCRIPTIONS
= 32
153 * Format of the column description in the index header.
155 * \sa index_header_offsets.
157 enum index_column_desc_offsets
{
158 /** Bytes 0,1: Storage_type. */
159 IDX_CD_STORAGE_TYPE
= 0,
160 /** Bytes 2,3: Storage_flags. */
161 IDX_CD_STORAGE_FLAGS
= 2,
162 /** Bytes 4 - 7: Data_size (only used for fixed size columns). */
163 IDX_CD_DATA_SIZE
= 4,
164 /** Bytes 8 - ... Name of the column. */
168 /** Magic string contained in the header of the index file of each osl table. */
169 #define PARA_MAGIC "PARASLASH"
172 * The minimal number of bytes for a column in the index header.
174 * The column name starts at byte IDX_CD_NAME and must at least contain one
175 * character, plus the terminating NULL byte.
177 #define MIN_IDX_COLUMN_DESCRIPTION_SIZE (IDX_CD_NAME + 2)
180 * Get the number of bytes used for a column in the index header.
182 * \param name The name of the column.
184 * The amount of space used for a column in the index header of a table depends
185 * on the (length of the) name of the column.
187 * \return The total number of bytes needed to store one column of this name.
189 _static_inline_
size_t index_column_description_size(const char *name
)
191 return MIN_IDX_COLUMN_DESCRIPTION_SIZE
+ strlen(name
) - 1;
194 #define CURRENT_TABLE_VERSION 1
195 #define MIN_TABLE_VERSION 1
196 #define MAX_TABLE_VERSION 1
197 /** An index header must be at least that many bytes long. */
198 #define MIN_INDEX_HEADER_SIZE(num_cols) (MIN_IDX_COLUMN_DESCRIPTION_SIZE \
199 * num_cols + IDX_COLUMN_DESCRIPTIONS)
202 * Get the number of rows from the size of the memory mapping.
204 * \param t Pointer to an open table.
206 * \return The number of rows, including invalid rows.
208 _static_inline_
unsigned table_num_rows(const struct osl_table
*t
)
210 return (t
->index_map
.size
- t
->index_header_size
)
215 * Get the path of the index file from a table description.
217 * \param d The table description.
219 * \return The full path of the index file. Result must be freed by
222 _static_inline_
char *index_filename(const struct osl_table_description
*d
)
224 return make_message("%s/%s/index", d
->dir
, d
->name
);
228 * Get the path of storage of a column.
230 * \param t Pointer to an initialized table.
231 * \param col_num The number of the column to get the path for.
233 * \return The full path of the mapped data file (mapped storage) or the
234 * data directory (disk storage). Result must be freed by the caller.
236 * \sa osl_storage_type.
238 _static_inline_
char *column_filename(const struct osl_table
*t
, unsigned col_num
)
240 char asc
[2 * HASH_SIZE
+ 1];
241 hash_to_asc(t
->columns
[col_num
].name_hash
, asc
);
242 return make_message("%s/%s/%s", t
->desc
->dir
, t
->desc
->name
, asc
);
246 * Get the start of an index entry
248 * \param t Pointer to a table which has been mapped.
249 * \param row_num The number of the row whose index entry should be retrieved.
250 * \param row_index Result pointer.
252 * \return Positive on success, \p -E_INDEX_CORRUPTION otherwise.
254 * \sa get_cell_index().
256 _static_inline_
int get_row_index(const struct osl_table
*t
, uint32_t row_num
,
259 uint32_t index_offset
;
260 index_offset
= t
->index_header_size
+ t
->row_index_size
* row_num
;
261 if (index_offset
+ 8 > t
->index_map
.size
) {
263 return -E_INDEX_CORRUPTION
;
265 *row_index
= (char *)(t
->index_map
.data
) + index_offset
;
270 * Get the index entry of a row/column pair.
272 * \param t Pointer to a table which has been mapped.
273 * \param row_num The number of the row whose index entry should be retrieved.
274 * \param col_num The number of the column whose index entry should be retrieved.
275 * \param cell_index Result pointer.
277 * \return Positive on success, \p -E_INDEX_CORRUPTION otherwise.
279 * \sa get_row_index().
281 _static_inline_
int get_cell_index(const struct osl_table
*t
, uint32_t row_num
,
282 uint32_t col_num
, char **cell_index
)
284 int ret
= get_row_index(t
, row_num
, cell_index
);
287 *cell_index
+= t
->columns
[col_num
].index_offset
;
292 * Change an index entry of a column after object was added.
294 * \param row_index Pointer to the index of the row to update.
295 * \param col Pointer to the column.
296 * \param map_size The new size of the data file.
297 * \param object_size The size of the object just appended to the data file.
299 * This is called right after an object was appended to the data file for a
302 * \sa get_row_index().
304 _static_inline_
void update_cell_index(char *row_index
, struct osl_column
*col
,
305 uint32_t map_size
, uint32_t object_size
)
307 write_u32(row_index
+ col
->index_offset
, map_size
- object_size
- 1);
308 write_u32(row_index
+ col
->index_offset
+ 4, object_size
+ 1);
312 * Get the full path of a disk storage object
314 * \param t Pointer to an initialized table.
315 * \param col_num The number of the column the disk storage object belongs to.
316 * \param ds_name The disk storage name of the object.
318 * \return Pointer to the full path which must be freed by the caller.
320 * \sa column_filename(), disk_storage_name_of_row().
322 _static_inline_
char *disk_storage_path(const struct osl_table
*t
,
323 unsigned col_num
, const char *ds_name
)
325 char *dirname
= column_filename(t
, col_num
);
326 char *filename
= make_message("%s/%s", dirname
, ds_name
);
332 * Get the column description of the next column of a given type.
334 * \param type the desired storage type.
335 * \param col_num the column to start the search.
336 * \param t the osl table.
337 * \param cd result is returned here.
339 * \return On success, \a cd contains the column description of the next column
340 * of type \a type, and the number of that column is returned. Otherwise, \a
341 * cd is set to \p NULL and the function returns t->num_columns + 1.
343 * \sa FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN, FOR_EACH_RBTREE_COLUMN,
344 * FOR_EACH_DISK_STORAGE_COLUMN, FOR_EACH_VOLATILE_COLUMN, osl_storage_type.
346 _static_inline_
int next_column_of_type(enum osl_storage_type type
, int col_num
,
347 const struct osl_table
*t
,
348 const struct osl_column_description
**cd
)
351 while (col_num
< t
->desc
->num_columns
) {
352 *cd
= get_column_description(t
->desc
, col_num
);
353 if ((*cd
)->storage_type
== type
)
361 * Find the next column with an associated rbtree.
363 * \param col_num The column to start the search.
364 * \param t The osl table.
365 * \param cd Result is returned here.
367 * \return On success, \a cd contains the column description of the next column
368 * with associated rbtree, and the number of that column is returned.
369 * Otherwise, \a cd is set to \p NULL and the function returns t->num_columns +
372 * \sa FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN, FOR_EACH_RBTREE_COLUMN,
373 * FOR_EACH_DISK_STORAGE_COLUMN, FOR_EACH_VOLATILE_COLUMN, osl_storage_flags.
375 _static_inline_
int next_rbtree_column(int col_num
, const struct osl_table
*t
,
376 const struct osl_column_description
**cd
)
379 while (col_num
< t
->desc
->num_columns
) {
380 *cd
= get_column_description(t
->desc
, col_num
);
381 if ((*cd
)->storage_flags
& OSL_RBTREE
)
389 /* quite some dirty hacks */
391 /** Round up size of struct osl_row to multiple of 8 */
392 #define RB_NODES_OFFSET ((sizeof(struct osl_row) + 7) / 8 * 8)
395 * Allocate a new osl row.
397 * \param num_rbtrees The number of rbtrees for this row.
399 * \return A pointer to a zeroed-out area suitable for holding an osl row
400 * with \a num_rbtrees rbtree columns.
402 _static_inline_
struct osl_row
*allocate_row(unsigned num_rbtrees
)
404 size_t s
= RB_NODES_OFFSET
+ num_rbtrees
* sizeof(struct rb_node
);
405 return para_calloc(s
);
409 * Compute the pointer to a rbtree node embedded in a osl row.
411 * \param row The row to extract the rbtree pointer from.
412 * \param rbtree_num The number of the rbtree node to extract.
414 * \return A pointer to the \a rbtree_num th node contained in \a row.
416 _static_inline_
struct rb_node
*get_rb_node_pointer(const struct osl_row
*row
, uint32_t rbtree_num
)
418 return ((struct rb_node
*)(((char *)row
) + RB_NODES_OFFSET
)) + rbtree_num
;
422 * Get a pointer to the struct containing the given rbtree node.
424 * \param node Pointer to the rbtree node.
425 * \param rbtree_num Number of \a node in the array of rbtree nodes.
427 * \return A pointer to the row containing \a node.
429 _static_inline_
struct osl_row
*get_row_pointer(const struct rb_node
*node
,
433 return (struct osl_row
*)(((char *)node
) - RB_NODES_OFFSET
);
437 * Compute a cryptographic hash of an osl object.
439 * \param obj the Object to compute the hash value from.
440 * \param hash Result is returned here.
442 static inline void hash_object(const struct osl_object
*obj
, HASH_TYPE
*hash
)
444 return hash_function(obj
->data
, obj
->size
, hash
);
448 * Get the relative path of an object, given the hash value.
450 * \param t Pointer to an initialized osl table.
451 * \param hash An arbitrary hash value.
453 * This function is typically called with \a hash being the hash of the object
454 * stored in the disk storage name column of a row. If the OSL_LARGE_TABLE
455 * flag is set, the first two hex digits get separated with a slash from the
458 * \return The relative path for all disk storage objects corresponding to \a
461 * \sa struct osl_table:disk_storage_name_column.
463 static inline char *disk_storage_name_of_hash(const struct osl_table
*t
, HASH_TYPE
*hash
)
465 char asc
[2 * HASH_SIZE
+ 2];
467 hash_to_asc(hash
, asc
);
468 if (t
->desc
->flags
& OSL_LARGE_TABLE
)
469 return make_message("%.2s/%s", asc
, asc
+ 2);
470 return para_strdup(asc
);
474 * A wrapper for rename(2).
476 * \param old_path The source path.
477 * \param new_path The destination path.
479 * \return positive in success, \p -E_RENAME on errors.
483 static inline int para_rename(const char *old_path
, const char *new_path
)
485 if (rename(old_path
, new_path
) < 0)
491 * Iterate over each column of an initialized table.
493 * \param col A pointer to a struct osl_column.
494 * \param desc Pointer to the table description.
495 * \param cd Pointer to struct osl_column_description.
497 * On each iteration, \a col will point to the next column of the table and \a
498 * cd will point to the column description of this column.
500 * \sa struct osl_column FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE,
501 * FOR_EACH_MAPPED_COLUMN, FOR_EACH_DISK_STORAGE_COLUMN,
502 * FOR_EACH_VOLATILE_COLUMN.
504 #define FOR_EACH_COLUMN(col, desc, cd) \
505 for (col = 0; col < (desc)->num_columns && \
506 (cd = get_column_description(desc, col)); col++)
509 * Iterate over each column with associated rbtree.
511 * \param col Same meaning as in FOR_EACH_COLUMN().
512 * \param table Same meaning as in FOR_EACH_COLUMN().
513 * \param cd Same meaning as in FOR_EACH_COLUMN().
515 * \sa osl_storage_flags::OSL_RBTREE, FOR_EACH_COLUMN, FOR_EACH_COLUMN_OF_TYPE,
516 * FOR_EACH_MAPPED_COLUMN, FOR_EACH_DISK_STORAGE_COLUMN,
517 * FOR_EACH_VOLATILE_COLUMN.
519 #define FOR_EACH_RBTREE_COLUMN(col, table, cd) \
520 for (col = next_rbtree_column(0, table, &cd); \
521 col < table->desc->num_columns; \
522 col = next_rbtree_column(++col, table, &cd))
525 * Iterate over each column of given storage type.
527 * \param type The osl_storage_type to iterate over.
528 * \param col Same meaning as in FOR_EACH_COLUMN().
529 * \param table Same meaning as in FOR_EACH_COLUMN().
530 * \param cd Same meaning as in FOR_EACH_COLUMN().
532 * \sa osl_storage_type, FOR_EACH_COLUMN, FOR_EACH_RBTREE_COLUMN,
533 * FOR_EACH_MAPPED_COLUMN, FOR_EACH_DISK_STORAGE_COLUMN,
534 * FOR_EACH_VOLATILE_COLUMN.
536 #define FOR_EACH_COLUMN_OF_TYPE(type, col, table, cd) \
537 for (col = next_column_of_type(type, 0, table, &cd); \
538 col < table->desc->num_columns; \
539 col = next_column_of_type(type, ++col, table, &cd))
542 * Iterate over each mapped column.
544 * \param col Same meaning as in FOR_EACH_COLUMN().
545 * \param table Same meaning as in FOR_EACH_COLUMN().
546 * \param cd Same meaning as in FOR_EACH_COLUMN().
548 * Just like FOR_EACH_COLUMN(), but skip columns which are
549 * not of type \p OSL_MAPPED_STORAGE.
551 * \sa osl_storage_flags::OSL_MAPPED_STORAGE, FOR_EACH_COLUMN,
552 * FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE,
553 * FOR_EACH_DISK_STORAGE_COLUMN, FOR_EACH_VOLATILE_COLUMN.
555 #define FOR_EACH_MAPPED_COLUMN(col, table, cd) \
556 FOR_EACH_COLUMN_OF_TYPE(OSL_MAPPED_STORAGE, col, table, cd)
559 * Iterate over each disk storage column.
561 * \param col Same meaning as in FOR_EACH_COLUMN().
562 * \param table Same meaning as in FOR_EACH_COLUMN().
563 * \param cd Same meaning as in FOR_EACH_COLUMN().
565 * Just like FOR_EACH_COLUMN(), but skip columns which are
566 * not of type \p OSL_DISK_STORAGE.
568 * \sa osl_storage_flags::OSL_DISK_STORAGE, FOR_EACH_COLUMN,
569 * FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN,
570 * FOR_EACH_VOLATILE_COLUMN.
572 #define FOR_EACH_DISK_STORAGE_COLUMN(col, table, cd) \
573 FOR_EACH_COLUMN_OF_TYPE(OSL_DISK_STORAGE, col, table, cd)
576 * Iterate over each volatile column.
578 * \param col Same meaning as in FOR_EACH_COLUMN().
579 * \param table Same meaning as in FOR_EACH_COLUMN().
580 * \param cd Same meaning as in FOR_EACH_COLUMN().
582 * Just like FOR_EACH_COLUMN(), but skip columns which are
583 * not of type \p OSL_NO_STORAGE.
585 * \sa osl_storage_flags::OSL_NO_STORAGE, FOR_EACH_COLUMN,
586 * FOR_EACH_RBTREE_COLUMN, FOR_EACH_COLUMN_OF_TYPE, FOR_EACH_MAPPED_COLUMN,
587 * FOR_EACH_DISK_STORAGE_COLUMN.
589 #define FOR_EACH_VOLATILE_COLUMN(col, table, cd) \
590 FOR_EACH_COLUMN_OF_TYPE(OSL_NO_STORAGE, col, table, cd)