2 * Copyright (c) 2005 SilverStorm Technologies. All rights reserved.
\r
3 * Copyright (c) 1996-2003 Intel Corporation. All rights reserved.
\r
5 * This software is available to you under the OpenIB.org BSD license
\r
8 * Redistribution and use in source and binary forms, with or
\r
9 * without modification, are permitted provided that the following
\r
10 * conditions are met:
\r
12 * - Redistributions of source code must retain the above
\r
13 * copyright notice, this list of conditions and the following
\r
16 * - Redistributions in binary form must reproduce the above
\r
17 * copyright notice, this list of conditions and the following
\r
18 * disclaimer in the documentation and/or other materials
\r
19 * provided with the distribution.
\r
21 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
\r
22 * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
\r
23 * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
\r
24 * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
\r
25 * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
\r
26 * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
\r
27 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
\r
36 * This file contains ivector and isvector implementations.
\r
43 #include <complib/cl_ptr_vector.h>
\r
44 #include <complib/cl_memory.h>
\r
48 cl_ptr_vector_construct(
\r
49 IN cl_ptr_vector_t* const p_vector )
\r
51 CL_ASSERT( p_vector );
\r
53 cl_memclr( p_vector, sizeof(cl_ptr_vector_t) );
\r
55 p_vector->state = CL_UNINITIALIZED;
\r
61 IN cl_ptr_vector_t* const p_vector,
\r
62 IN const size_t min_cap,
\r
63 IN const size_t grow_size )
\r
65 cl_status_t status = CL_SUCCESS;
\r
67 CL_ASSERT( p_vector );
\r
69 cl_ptr_vector_construct( p_vector );
\r
71 p_vector->grow_size = grow_size;
\r
74 * Set the state to initialized so that the call to set_size
\r
77 p_vector->state = CL_INITIALIZED;
\r
79 /* get the storage needed by the user */
\r
82 status = cl_ptr_vector_set_capacity( p_vector, min_cap );
\r
83 if( status != CL_SUCCESS )
\r
84 cl_ptr_vector_destroy( p_vector );
\r
92 cl_ptr_vector_destroy(
\r
93 IN cl_ptr_vector_t* const p_vector )
\r
95 CL_ASSERT( p_vector );
\r
96 CL_ASSERT( cl_is_state_valid( p_vector->state ) );
\r
98 /* Call the user's destructor for each element in the array. */
\r
99 if( p_vector->state == CL_INITIALIZED )
\r
101 /* Destroy the page vector. */
\r
102 if( p_vector->p_ptr_array )
\r
104 cl_free( (void*)p_vector->p_ptr_array );
\r
105 p_vector->p_ptr_array = NULL;
\r
109 p_vector->state = CL_UNINITIALIZED;
\r
115 IN const cl_ptr_vector_t* const p_vector,
\r
116 IN const size_t index,
\r
117 OUT void** const p_element )
\r
119 CL_ASSERT( p_vector );
\r
120 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
123 if( index >= p_vector->size )
\r
124 return( CL_INVALID_PARAMETER );
\r
126 *p_element = cl_ptr_vector_get( p_vector, index );
\r
127 return( CL_SUCCESS );
\r
133 IN cl_ptr_vector_t* const p_vector,
\r
134 IN const size_t index,
\r
135 IN const void* const element )
\r
137 cl_status_t status;
\r
139 CL_ASSERT( p_vector );
\r
140 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
142 /* Determine if the vector has room for this element. */
\r
143 if( index >= p_vector->size )
\r
145 /* Resize to accomodate the given index. */
\r
146 status = cl_ptr_vector_set_size( p_vector, index + 1 );
\r
148 /* Check for failure on or before the given index. */
\r
149 if( (status != CL_SUCCESS) && (p_vector->size < index) )
\r
153 /* At this point, the array is guaranteed to be big enough */
\r
154 p_vector->p_ptr_array[index] = element;
\r
156 return( CL_SUCCESS );
\r
161 cl_ptr_vector_remove(
\r
162 IN cl_ptr_vector_t* const p_vector,
\r
163 IN const size_t index )
\r
166 const void *element;
\r
168 CL_ASSERT( p_vector );
\r
169 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
170 CL_ASSERT( p_vector->size > index );
\r
172 /* Store a copy of the element to return. */
\r
173 element = p_vector->p_ptr_array[index];
\r
174 /* Shift all items above the removed item down. */
\r
175 if( index < --p_vector->size )
\r
177 for( src = index; src < p_vector->size; src++ )
\r
178 p_vector->p_ptr_array[src] = p_vector->p_ptr_array[src + 1];
\r
180 /* Clear the entry for the element just outside of the new upper bound. */
\r
181 p_vector->p_ptr_array[p_vector->size] = NULL;
\r
183 return( (void*)element );
\r
188 cl_ptr_vector_set_capacity(
\r
189 IN cl_ptr_vector_t* const p_vector,
\r
190 IN const size_t new_capacity )
\r
192 void *p_new_ptr_array;
\r
194 CL_ASSERT( p_vector );
\r
195 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
197 /* Do we have to do anything here? */
\r
198 if( new_capacity <= p_vector->capacity )
\r
201 return( CL_SUCCESS );
\r
204 /* Allocate our pointer array. */
\r
205 p_new_ptr_array = cl_zalloc( new_capacity * sizeof(void*) );
\r
206 if( !p_new_ptr_array )
\r
207 return( CL_INSUFFICIENT_MEMORY );
\r
209 if( p_vector->p_ptr_array )
\r
211 /* Copy the old pointer array into the new. */
\r
212 cl_memcpy( p_new_ptr_array, p_vector->p_ptr_array,
\r
213 p_vector->capacity * sizeof(void*) );
\r
215 /* Free the old pointer array. */
\r
216 cl_free( (void*)p_vector->p_ptr_array );
\r
219 /* Set the new array. */
\r
220 p_vector->p_ptr_array = p_new_ptr_array;
\r
222 /* Update the vector with the new capactity. */
\r
223 p_vector->capacity = new_capacity;
\r
225 return( CL_SUCCESS );
\r
230 cl_ptr_vector_set_size(
\r
231 IN cl_ptr_vector_t* const p_vector,
\r
232 IN const size_t size )
\r
234 cl_status_t status;
\r
235 size_t new_capacity;
\r
237 CL_ASSERT( p_vector );
\r
238 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
240 /* Check to see if the requested size is the same as the existing size. */
\r
241 if( size == p_vector->size )
\r
242 return( CL_SUCCESS );
\r
244 /* Determine if the vector has room for this element. */
\r
245 if( size > p_vector->capacity )
\r
247 if( !p_vector->grow_size )
\r
248 return( CL_INSUFFICIENT_MEMORY );
\r
250 /* Calculate the new capacity, taking into account the grow size. */
\r
251 new_capacity = size;
\r
252 if( size % p_vector->grow_size )
\r
254 /* Round up to nearest grow_size boundary. */
\r
255 new_capacity += p_vector->grow_size -
\r
256 (size % p_vector->grow_size);
\r
259 status = cl_ptr_vector_set_capacity( p_vector, new_capacity );
\r
260 if( status != CL_SUCCESS )
\r
264 p_vector->size = size;
\r
265 return( CL_SUCCESS );
\r
270 cl_ptr_vector_set_min_size(
\r
271 IN cl_ptr_vector_t* const p_vector,
\r
272 IN const size_t min_size )
\r
274 CL_ASSERT( p_vector );
\r
275 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
277 if( min_size > p_vector->size )
\r
279 /* We have to resize the array */
\r
280 return( cl_ptr_vector_set_size( p_vector, min_size ) );
\r
283 /* We didn't have to do anything */
\r
284 return( CL_SUCCESS );
\r
289 cl_ptr_vector_apply_func(
\r
290 IN const cl_ptr_vector_t* const p_vector,
\r
291 IN cl_pfn_ptr_vec_apply_t pfn_callback,
\r
292 IN const void* const context )
\r
296 CL_ASSERT( p_vector );
\r
297 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
298 CL_ASSERT( pfn_callback );
\r
300 for( i = 0; i < p_vector->size; i++ )
\r
301 pfn_callback( i, (void*)p_vector->p_ptr_array[i], (void*)context );
\r
306 cl_ptr_vector_find_from_start(
\r
307 IN const cl_ptr_vector_t* const p_vector,
\r
308 IN cl_pfn_ptr_vec_find_t pfn_callback,
\r
309 IN const void* const context )
\r
313 CL_ASSERT( p_vector );
\r
314 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
315 CL_ASSERT( pfn_callback );
\r
317 for( i = 0; i < p_vector->size; i++ )
\r
319 /* Invoke the callback */
\r
320 if( pfn_callback( i, (void*)p_vector->p_ptr_array[i],
\r
321 (void*)context ) == CL_SUCCESS )
\r
331 cl_ptr_vector_find_from_end(
\r
332 IN const cl_ptr_vector_t* const p_vector,
\r
333 IN cl_pfn_ptr_vec_find_t pfn_callback,
\r
334 IN const void* const context )
\r
338 CL_ASSERT( p_vector );
\r
339 CL_ASSERT( p_vector->state == CL_INITIALIZED );
\r
340 CL_ASSERT( pfn_callback );
\r
342 i = p_vector->size;
\r
346 /* Invoke the callback for the current element. */
\r
347 if( pfn_callback( i, (void*)p_vector->p_ptr_array[--i],
\r
348 (void*)context ) == CL_SUCCESS )
\r
354 return( p_vector->size );
\r