Simple data structures / objects in plain C Snapshot
|
00001 /* Copyright (c) Michael Moser (2011) . 3-clause BSD License applies */ 00002 00003 #ifndef _V_HEAP_H_ 00004 #define _V_HEAP_H_ 00005 00006 #ifdef __cplusplus 00007 extern "C" { 00008 #endif 00009 00010 #include <cutils/base.h> 00011 00012 00013 typedef int (*HEAP_compare) (void *lhs, void *rhs, size_t elmsize); 00014 00015 /** 00016 * @defgroup HEAP 00017 * @brief Heap data structure; all elements in the heap must be of the same size. 00018 * A heap data structure is an ordered tree where the root node contains the smallest value. 00019 * The smallest element in the whole heap is alway the top element. 00020 * This heap is implemented by an array. 00021 * @{ 00022 */ 00023 typedef struct 00024 { 00025 size_t elmcount; 00026 size_t elmmaxcount; 00027 size_t elmsize; 00028 00029 unsigned char *buffer; 00030 00031 HEAP_compare compare_func; 00032 00033 } 00034 HEAP; 00035 00036 00037 /* 00038 * @brief construct a heap object. 00039 * @param ctx (in) allocator interface. (if null we are using the default allocator) 00040 * @param heap (in) the object 00041 * @param elmcount (in) maximum number of elements kept in this heap. 00042 * @param elmsize (in) size of one element kept in this heap. 00043 * @param grow_at (in) 00044 * @param compare_func (in) compares two entries in the heap - used to establish heap property. 00045 */ 00046 M_INLINE int HEAP_init( HEAP *heap, size_t elmcount, size_t elmsize, HEAP_compare compare_func) 00047 { 00048 00049 heap->elmsize = elmsize; 00050 heap->elmcount = 0; 00051 heap->elmmaxcount = elmcount; 00052 heap->compare_func = compare_func; 00053 00054 heap->buffer = (unsigned char *) malloc( elmcount * elmsize ); 00055 if (!heap->buffer) { 00056 return -1; 00057 } 00058 00059 return 0; 00060 } 00061 00062 00063 00064 /** 00065 * @brief free all memory used by the heap (object destructor). 00066 * @heap heap (in) the object. 00067 */ 00068 M_INLINE void HEAP_free( HEAP *heap ) 00069 { 00070 if (heap->buffer) { 00071 free(heap->buffer); 00072 heap->buffer = 0; 00073 heap->elmcount = 0; 00074 heap->elmmaxcount = 0; 00075 heap->elmsize = 0; 00076 } 00077 } 00078 00079 M_INLINE size_t HEAP_size( HEAP *heap) 00080 { 00081 return heap->elmcount; 00082 } 00083 00084 M_INLINE size_t HEAP_maxsize( HEAP *heap) 00085 { 00086 return heap->elmmaxcount; 00087 } 00088 00089 M_INLINE size_t HEAP_elmsize( HEAP *heap) 00090 { 00091 return heap->elmsize; 00092 } 00093 00094 /** 00095 * @brief returns pointer to the top element of the heap. 00096 * @param heap (in) the object 00097 * @return pointer to the top element of the heap or 0 if heap is empty. 00098 */ 00099 M_INLINE void *HEAP_top( HEAP *heap) 00100 { 00101 if (heap->elmcount == 0) { 00102 return 0; 00103 } 00104 return heap->buffer; 00105 } 00106 00107 00108 M_INLINE void *HEAP_get_at( HEAP *heap, int index) 00109 { 00110 if (heap->elmcount == 0) { 00111 return 0; 00112 } 00113 if (index > (int) heap->elmcount || index < 0) { 00114 return 0; 00115 } 00116 00117 return heap->buffer + index * heap->elmsize; 00118 } 00119 00120 00121 /** 00122 * @brief remove the top element from the heap 00123 * @param heap (in) the object 00124 */ 00125 int HEAP_pop( HEAP *heap); 00126 00127 /** 00128 * @brief insert a new element into the heap 00129 * @param heap (in) the object 00130 * @param element (in) data of object to be inserted into heap 00131 * @param elmsize (in) size of data area for element pointer. 00132 */ 00133 int HEAP_push( HEAP *heap, void *element, size_t elmsize ); 00134 00135 /** 00136 * @brief check consistency of heap object. 00137 */ 00138 int HEAP_check( HEAP *heap ); 00139 00140 00141 typedef int (*HEAP_VISITOR) (int index, void *elm, size_t elmsize, void *context); 00142 00143 00144 00145 void HEAP_foreach_sorted( HEAP *heap, HEAP_VISITOR eval, void *context); 00146 00147 00148 M_INLINE void HEAP_foreach( HEAP *heap, HEAP_VISITOR eval, void *context) 00149 { 00150 size_t i; 00151 size_t sz = heap->elmcount; 00152 size_t elmsz = heap->elmsize; 00153 uint8_t *pos; 00154 00155 for(pos = heap->buffer, i = 0; i < sz; i++, pos += elmsz) { 00156 eval( i, pos, elmsz, context ); 00157 } 00158 } 00159 00160 M_INLINE int HEAP_findif( HEAP *heap, HEAP_VISITOR eval, void *context, int32_t *retval) 00161 { 00162 size_t i; 00163 size_t sz = heap->elmcount; 00164 size_t elmsz = heap->elmsize; 00165 int32_t ret; 00166 uint8_t *pos; 00167 00168 if (!retval) { 00169 *retval = 0; 00170 } 00171 00172 for(i = 0, pos = heap->buffer; i < sz; i++, pos += elmsz) { 00173 if ( (ret = eval( i, pos, elmsz, context )) != 0) { 00174 if (retval) { 00175 *retval = ret; 00176 } 00177 return i; 00178 } 00179 } 00180 return -1; 00181 } 00182 00183 /** 00184 * @} 00185 */ 00186 00187 #ifdef __cplusplus 00188 } 00189 #endif 00190 00191 #endif 00192