![]() |
|
|||
0001 /* 0002 * Copyright (C) 2012 Red Hat, Inc. 0003 * 0004 * This file is released under the GPL. 0005 */ 0006 #ifndef _LINUX_DM_ARRAY_H 0007 #define _LINUX_DM_ARRAY_H 0008 0009 #include "dm-btree.h" 0010 0011 /*----------------------------------------------------------------*/ 0012 0013 /* 0014 * The dm-array is a persistent version of an array. It packs the data 0015 * more efficiently than a btree which will result in less disk space use, 0016 * and a performance boost. The element get and set operations are still 0017 * O(ln(n)), but with a much smaller constant. 0018 * 0019 * The value type structure is reused from the btree type to support proper 0020 * reference counting of values. 0021 * 0022 * The arrays implicitly know their length, and bounds are checked for 0023 * lookups and updated. It doesn't store this in an accessible place 0024 * because it would waste a whole metadata block. Make sure you store the 0025 * size along with the array root in your encompassing data. 0026 * 0027 * Array entries are indexed via an unsigned integer starting from zero. 0028 * Arrays are not sparse; if you resize an array to have 'n' entries then 0029 * 'n - 1' will be the last valid index. 0030 * 0031 * Typical use: 0032 * 0033 * a) initialise a dm_array_info structure. This describes the array 0034 * values and ties it into a specific transaction manager. It holds no 0035 * instance data; the same info can be used for many similar arrays if 0036 * you wish. 0037 * 0038 * b) Get yourself a root. The root is the index of a block of data on the 0039 * disk that holds a particular instance of an array. You may have a 0040 * pre existing root in your metadata that you wish to use, or you may 0041 * want to create a brand new, empty array with dm_array_empty(). 0042 * 0043 * Like the other data structures in this library, dm_array objects are 0044 * immutable between transactions. Update functions will return you the 0045 * root for a _new_ array. If you've incremented the old root, via 0046 * dm_tm_inc(), before calling the update function you may continue to use 0047 * it in parallel with the new root. 0048 * 0049 * c) resize an array with dm_array_resize(). 0050 * 0051 * d) Get a value from the array with dm_array_get_value(). 0052 * 0053 * e) Set a value in the array with dm_array_set_value(). 0054 * 0055 * f) Walk an array of values in index order with dm_array_walk(). More 0056 * efficient than making many calls to dm_array_get_value(). 0057 * 0058 * g) Destroy the array with dm_array_del(). This tells the transaction 0059 * manager that you're no longer using this data structure so it can 0060 * recycle it's blocks. (dm_array_dec() would be a better name for it, 0061 * but del is in keeping with dm_btree_del()). 0062 */ 0063 0064 /* 0065 * Describes an array. Don't initialise this structure yourself, use the 0066 * init function below. 0067 */ 0068 struct dm_array_info { 0069 struct dm_transaction_manager *tm; 0070 struct dm_btree_value_type value_type; 0071 struct dm_btree_info btree_info; 0072 }; 0073 0074 /* 0075 * Sets up a dm_array_info structure. You don't need to do anything with 0076 * this structure when you finish using it. 0077 * 0078 * info - the structure being filled in. 0079 * tm - the transaction manager that should supervise this structure. 0080 * vt - describes the leaf values. 0081 */ 0082 void dm_array_info_init(struct dm_array_info *info, 0083 struct dm_transaction_manager *tm, 0084 struct dm_btree_value_type *vt); 0085 0086 /* 0087 * Create an empty, zero length array. 0088 * 0089 * info - describes the array 0090 * root - on success this will be filled out with the root block 0091 */ 0092 int dm_array_empty(struct dm_array_info *info, dm_block_t *root); 0093 0094 /* 0095 * Resizes the array. 0096 * 0097 * info - describes the array 0098 * root - the root block of the array on disk 0099 * old_size - the caller is responsible for remembering the size of 0100 * the array 0101 * new_size - can be bigger or smaller than old_size 0102 * value - if we're growing the array the new entries will have this value 0103 * new_root - on success, points to the new root block 0104 * 0105 * If growing the inc function for 'value' will be called the appropriate 0106 * number of times. So if the caller is holding a reference they may want 0107 * to drop it. 0108 */ 0109 int dm_array_resize(struct dm_array_info *info, dm_block_t root, 0110 uint32_t old_size, uint32_t new_size, 0111 const void *value, dm_block_t *new_root) 0112 __dm_written_to_disk(value); 0113 0114 /* 0115 * Creates a new array populated with values provided by a callback 0116 * function. This is more efficient than creating an empty array, 0117 * resizing, and then setting values since that process incurs a lot of 0118 * copying. 0119 * 0120 * Assumes 32bit values for now since it's only used by the cache hint 0121 * array. 0122 * 0123 * info - describes the array 0124 * root - the root block of the array on disk 0125 * size - the number of entries in the array 0126 * fn - the callback 0127 * context - passed to the callback 0128 */ 0129 typedef int (*value_fn)(uint32_t index, void *value_le, void *context); 0130 int dm_array_new(struct dm_array_info *info, dm_block_t *root, 0131 uint32_t size, value_fn fn, void *context); 0132 0133 /* 0134 * Frees a whole array. The value_type's decrement operation will be called 0135 * for all values in the array 0136 */ 0137 int dm_array_del(struct dm_array_info *info, dm_block_t root); 0138 0139 /* 0140 * Lookup a value in the array 0141 * 0142 * info - describes the array 0143 * root - root block of the array 0144 * index - array index 0145 * value - the value to be read. Will be in on-disk format of course. 0146 * 0147 * -ENODATA will be returned if the index is out of bounds. 0148 */ 0149 int dm_array_get_value(struct dm_array_info *info, dm_block_t root, 0150 uint32_t index, void *value); 0151 0152 /* 0153 * Set an entry in the array. 0154 * 0155 * info - describes the array 0156 * root - root block of the array 0157 * index - array index 0158 * value - value to be written to disk. Make sure you confirm the value is 0159 * in on-disk format with__dm_bless_for_disk() before calling. 0160 * new_root - the new root block 0161 * 0162 * The old value being overwritten will be decremented, the new value 0163 * incremented. 0164 * 0165 * -ENODATA will be returned if the index is out of bounds. 0166 */ 0167 int dm_array_set_value(struct dm_array_info *info, dm_block_t root, 0168 uint32_t index, const void *value, dm_block_t *new_root) 0169 __dm_written_to_disk(value); 0170 0171 /* 0172 * Walk through all the entries in an array. 0173 * 0174 * info - describes the array 0175 * root - root block of the array 0176 * fn - called back for every element 0177 * context - passed to the callback 0178 */ 0179 int dm_array_walk(struct dm_array_info *info, dm_block_t root, 0180 int (*fn)(void *context, uint64_t key, void *leaf), 0181 void *context); 0182 0183 /*----------------------------------------------------------------*/ 0184 0185 /* 0186 * Cursor api. 0187 * 0188 * This lets you iterate through all the entries in an array efficiently 0189 * (it will preload metadata). 0190 * 0191 * I'm using a cursor, rather than a walk function with a callback because 0192 * the cache target needs to iterate both the mapping and hint arrays in 0193 * unison. 0194 */ 0195 struct dm_array_cursor { 0196 struct dm_array_info *info; 0197 struct dm_btree_cursor cursor; 0198 0199 struct dm_block *block; 0200 struct array_block *ab; 0201 unsigned index; 0202 }; 0203 0204 int dm_array_cursor_begin(struct dm_array_info *info, 0205 dm_block_t root, struct dm_array_cursor *c); 0206 void dm_array_cursor_end(struct dm_array_cursor *c); 0207 0208 uint32_t dm_array_cursor_index(struct dm_array_cursor *c); 0209 int dm_array_cursor_next(struct dm_array_cursor *c); 0210 int dm_array_cursor_skip(struct dm_array_cursor *c, uint32_t count); 0211 0212 /* 0213 * value_le is only valid while the cursor points at the current value. 0214 */ 0215 void dm_array_cursor_get_value(struct dm_array_cursor *c, void **value_le); 0216 0217 /*----------------------------------------------------------------*/ 0218 0219 #endif /* _LINUX_DM_ARRAY_H */
[ Source navigation ] | [ Diff markup ] | [ Identifier search ] | [ general search ] |
This page was automatically generated by the 2.1.0 LXR engine. The LXR team |
![]() ![]() |