OpenMPI  0.1.1
opal_value_array.h
1 /*
2  * Copyright (c) 2004-2007 The Trustees of Indiana University and Indiana
3  * University Research and Technology
4  * Corporation. All rights reserved.
5  * Copyright (c) 2004-2006 The University of Tennessee and The University
6  * of Tennessee Research Foundation. All rights
7  * reserved.
8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
9  * University of Stuttgart. All rights reserved.
10  * Copyright (c) 2004-2005 The Regents of the University of California.
11  * All rights reserved.
12  * $COPYRIGHT$
13  *
14  * Additional copyrights may follow
15  *
16  * $HEADER$
17  */
18 
19 #ifndef OPAL_VALUE_ARRAY_H
20 #define OPAL_VALUE_ARRAY_H
21 
22 #include "opal_config.h"
23 
24 #include <string.h>
25 
26 #include "opal/class/opal_object.h"
27 #if OPAL_ENABLE_DEBUG
28 #include "opal/util/output.h"
29 #endif
30 #include "opal/constants.h"
31 
32 BEGIN_C_DECLS
33 
34 /*
35  * @file Array of elements maintained by value.
36  */
37 
39 {
40  opal_object_t super;
41  unsigned char* array_items;
42  size_t array_item_sizeof;
43  size_t array_size;
44  size_t array_alloc_size;
45 };
47 
49 
50 /**
51  * Initialize the array to hold items by value. This routine must
52  * be called prior to using the array.
53  *
54  * @param array The array to initialize (IN).
55  * @param item_size The sizeof each array element (IN).
56  * @return OPAL error code
57  *
58  * Note that there is no corresponding "finalize" function -- use
59  * OBJ_DESTRUCT (for stack arrays) or OBJ_RELEASE (for heap arrays) to
60  * delete it.
61  */
62 
63 static inline int opal_value_array_init(opal_value_array_t *array, size_t item_sizeof)
64 {
65  array->array_item_sizeof = item_sizeof;
66  array->array_alloc_size = 1;
67  array->array_size = 0;
68  array->array_items = (unsigned char*)realloc(array->array_items, item_sizeof * array->array_alloc_size);
69  return (NULL != array->array_items) ? OPAL_SUCCESS : OPAL_ERR_OUT_OF_RESOURCE;
70 }
71 
72 
73 /**
74  * Reserve space in the array for new elements, but do not change the size.
75  *
76  * @param array The input array (IN).
77  * @param size The anticipated size of the array (IN).
78  * @return OPAL error code.
79  */
80 
81 static inline int opal_value_array_reserve(opal_value_array_t* array, size_t size)
82 {
83  if(size > array->array_alloc_size) {
84  array->array_items = (unsigned char*)realloc(array->array_items, array->array_item_sizeof * size);
85  if(NULL == array->array_items) {
86  array->array_size = 0;
87  array->array_alloc_size = 0;
88  return OPAL_ERR_OUT_OF_RESOURCE;
89  }
90  array->array_alloc_size = size;
91  }
92  return OPAL_SUCCESS;
93 }
94 
95 
96 
97 /**
98  * Retreives the number of elements in the array.
99  *
100  * @param array The input array (IN).
101  * @return The number of elements currently in use.
102  */
103 
104 static inline size_t opal_value_array_get_size(opal_value_array_t* array)
105 {
106  return array->array_size;
107 }
108 
109 
110 /**
111  * Set the number of elements in the array.
112  *
113  * @param array The input array (IN).
114  * @param size The new array size.
115  *
116  * @return OPAL error code.
117  *
118  * Note that resizing the array to a smaller size may not change
119  * the underlying memory allocated by the array. However, setting
120  * the size larger than the current allocation will grow it. In either
121  * case, if the routine is successful, opal_value_array_get_size() will
122  * return the new size.
123  */
124 
125 OPAL_DECLSPEC int opal_value_array_set_size(opal_value_array_t* array, size_t size);
126 
127 
128 /**
129  * Macro to retrieve an item from the array by value.
130  *
131  * @param array The input array (IN).
132  * @param item_type The C datatype of the array item (IN).
133  * @param item_index The array index (IN).
134  *
135  * @returns item The requested item.
136  *
137  * Note that this does not change the size of the array - this macro is
138  * strictly for performance - the user assumes the responsibility of
139  * ensuring the array index is valid (0 <= item index < array size).
140  */
141 
142 #define OPAL_VALUE_ARRAY_GET_ITEM(array, item_type, item_index) \
143  ((item_type*)((array)->array_items))[item_index]
144 
145 /**
146  * Retrieve an item from the array by reference.
147  *
148  * @param array The input array (IN).
149  * @param item_index The array index (IN).
150  *
151  * @return ptr Pointer to the requested item.
152  *
153  * Note that if the specified item_index is larger than the current
154  * array size, the array is grown to satisfy the request.
155  */
156 
157 static inline void* opal_value_array_get_item(opal_value_array_t *array, size_t item_index)
158 {
159  if(item_index >= array->array_size && opal_value_array_set_size(array, item_index+1) != OPAL_SUCCESS)
160  return NULL;
161  return array->array_items + (item_index * array->array_item_sizeof);
162 }
163 
164 /**
165  * Macro to set an array element by value.
166  *
167  * @param array The input array (IN).
168  * @param item_type The C datatype of the array item (IN).
169  * @param item_index The array index (IN).
170  * @param item_value The new value for the specified index (IN).
171  *
172  * Note that this does not change the size of the array - this macro is
173  * strictly for performance - the user assumes the responsibility of
174  * ensuring the array index is valid (0 <= item index < array size).
175  *
176  * It is safe to free the item after returning from this call; it is
177  * copied into the array by value.
178  */
179 
180 #define OPAL_VALUE_ARRAY_SET_ITEM(array, item_type, item_index, item_value) \
181  (((item_type*)((array)->array_items))[item_index] = item_value)
182 
183 /**
184  * Set an array element by value.
185  *
186  * @param array The input array (IN).
187  * @param item_index The array index (IN).
188  * @param item_value A pointer to the item, which is copied into
189  * the array.
190  *
191  * @return OPAL error code.
192  *
193  * It is safe to free the item after returning from this call; it is
194  * copied into the array by value.
195  */
196 
197 static inline int opal_value_array_set_item(opal_value_array_t *array, size_t item_index, const void* item)
198 {
199  int rc;
200  if(item_index >= array->array_size &&
201  (rc = opal_value_array_set_size(array, item_index+1)) != OPAL_SUCCESS)
202  return rc;
203  memcpy(array->array_items + (item_index * array->array_item_sizeof), item, array->array_item_sizeof);
204  return OPAL_SUCCESS;
205 }
206 
207 
208 /**
209  * Appends an item to the end of the array.
210  *
211  * @param array The input array (IN).
212  * @param item A pointer to the item to append, which is copied
213  * into the array.
214  *
215  * @return OPAL error code
216  *
217  * This will grow the array if it is not large enough to contain the
218  * item. It is safe to free the item after returning from this call;
219  * it is copied by value into the array.
220  */
221 
222 static inline int opal_value_array_append_item(opal_value_array_t *array, const void *item)
223 {
224  return opal_value_array_set_item(array, array->array_size, item);
225 }
226 
227 
228 /**
229  * Remove a specific item from the array.
230  *
231  * @param array The input array (IN).
232  * @param item_index The index to remove, which must be less than
233  * the current array size (IN).
234  *
235  * @return OPAL error code.
236  *
237  * All elements following this index are shifted down.
238  */
239 
240 static inline int opal_value_array_remove_item(opal_value_array_t *array, size_t item_index)
241 {
242 #if OPAL_ENABLE_DEBUG
243  if (item_index >= array->array_size) {
244  opal_output(0, "opal_value_array_remove_item: invalid index %lu\n", (unsigned long)item_index);
245  return OPAL_ERR_BAD_PARAM;
246  }
247 #endif
248  memmove(array->array_items+(array->array_item_sizeof * item_index),
249  array->array_items+(array->array_item_sizeof * (item_index+1)),
250  array->array_item_sizeof * (array->array_size - item_index - 1));
251  array->array_size--;
252  return OPAL_SUCCESS;
253 }
254 
255 /**
256  * Get the base pointer of the underlying array.
257  *
258  * @param array The input array (IN).
259  * @param array_type The C datatype of the array (IN).
260  *
261  * @returns ptr Pointer to the actual array.
262  *
263  * This function is helpful when you need to iterate through an
264  * entire array; simply get the base value of the array and use native
265  * C to iterate through it manually. This can have better performance
266  * than looping over OPAL_VALUE_ARRAY_GET_ITEM() and
267  * OPAL_VALUE_ARRAY_SET_ITEM() because it will [potentially] reduce the
268  * number of pointer dereferences.
269  */
270 
271 #define OPAL_VALUE_ARRAY_GET_BASE(array, item_type) \
272  ((item_type*) ((array)->array_items))
273 
274 END_C_DECLS
275 
276 #endif
277 
OPAL output stream facility.
OPAL_DECLSPEC void opal_output(int output_id, const char *format,...) __opal_attribute_format__(__printf__
Main function to send output to a stream.
Base object.
Definition: opal_object.h:182
Definition: opal_value_array.h:38
A simple C-language object-oriented system with single inheritance and ownership-based memory managem...
#define OBJ_CLASS_DECLARATION(NAME)
Declaration for class descriptor.
Definition: opal_object.h:236