00001 #ifndef KAL_EHEAP_H_
00002 #define KAL_EHEAP_H_
00003
00010 #include "qos_debug.h"
00011 #include "qos_memory.h"
00012
00014 #define kal_define_eheap(key_type, value_type) \
00015 typedef struct kal_eheap_iterator_##key_type ##_##value_type ##_t { \
00016 int pos; \
00017 } kal_eheap_iterator_##key_type ##_##value_type ##_t; \
00018 typedef struct kal_eheap_node_##key_type ##_##value_type ##_t { \
00019 key_type key; \
00020 value_type value; \
00021 kal_eheap_iterator_##key_type ##_##value_type ##_t *p_iterator; \
00022 } kal_eheap_node_##key_type ##_##value_type ##_t; \
00023 typedef struct kal_eheap_##key_type ##_##value_type ##_t { \
00024 kal_eheap_node_t(key_type, value_type) *elems; \
00025 int num_elems; \
00026 int max_num_elems; \
00027 } kal_eheap_##key_type ##_##value_type ##_t
00028
00029 #ifndef kal_eheap_key_lt
00030 # define kal_eheap_key_lt(a, b) ((a) < (b))
00031 #endif
00032
00034 #define kal_eheap_node_t(key_type, value_type) \
00035 struct kal_eheap_node_##key_type ##_##value_type ##_t
00036
00038 #define kal_eheap_t(key_type, value_type) \
00039 kal_eheap_##key_type ##_##value_type ##_t
00040
00042 #define kal_eheap_iterator_t(key_type, value_type) \
00043 kal_eheap_iterator_##key_type ##_##value_type ##_t
00044
00050 #define kal_eheap_init(self, N) ({ \
00051 qos_rv __rv = QOS_OK; \
00052 do { \
00053 (self)->elems = qos_malloc(sizeof((self)->elems[0]) << N); \
00054 if ((self)->elems == NULL) { \
00055 __rv = QOS_E_NO_MEMORY; \
00056 break; \
00057 } \
00058 (self)->max_num_elems = 1 << N; \
00059 (self)->num_elems = 0; \
00060 } while (0); \
00061 __rv; \
00062 })
00063
00064 #define kal_eheap_cleanup(self) ({ \
00065 qos_rv __rv = QOS_OK; \
00066 do { \
00067 qos_free((self)->elems); \
00068 (self)->num_elems = (self)->max_num_elems = 0; \
00069 } while (0); \
00070 __rv; \
00071 })
00072
00074 #define kal_eheap_nodecpy(self, dst_pos, src_pos) \
00075 do { \
00076 (self)->elems[(dst_pos) - 1] = (self)->elems[(src_pos) - 1]; \
00077 if ((self)->elems[(dst_pos) - 1].p_iterator) \
00078 (self)->elems[(dst_pos) - 1].p_iterator->pos = (dst_pos); \
00079 } while (0)
00080
00086 #define kal_eheap_push_down(self, param_pos, param_key) ({ \
00087 int _pd_pos = (param_pos); \
00088 do { \
00089 int _pd_pos_child; \
00090 typeof((self)->elems[0].key) _pd_key = (param_key); \
00091
00092 _pd_pos_child = _pd_pos * 2; \
00093 while ( \
00094 ((_pd_pos_child <= (self)->num_elems) && kal_eheap_key_lt((self)->elems[_pd_pos_child - 1].key, _pd_key)) \
00095 || ((_pd_pos_child + 1 <= (self)->num_elems) && kal_eheap_key_lt((self)->elems[_pd_pos_child].key, _pd_key)) \
00096 ) { \
00097 if ((_pd_pos_child + 1 <= (self)->num_elems) && kal_eheap_key_lt((self)->elems[_pd_pos_child].key, (self)->elems[_pd_pos_child - 1].key)) \
00098 _pd_pos_child++; \
00099 kal_eheap_nodecpy((self), _pd_pos, _pd_pos_child); \
00100 _pd_pos = _pd_pos_child; \
00101 _pd_pos_child = _pd_pos * 2; \
00102
00103 } \
00104 } while (0); \
00105 _pd_pos; \
00106 })
00107
00113 #define kal_eheap_push_up(self, param_pos, param_key) ({ \
00114 int _pu_pos = (param_pos); \
00115 do { \
00116 int _pu_pos_fath = _pu_pos / 2; \
00117
00118 while ((_pu_pos != 1) && kal_eheap_key_lt((param_key), (self)->elems[_pu_pos_fath - 1].key)) { \
00119 kal_eheap_nodecpy((self), _pu_pos, _pu_pos_fath); \
00120 _pu_pos = _pu_pos_fath; \
00121 _pu_pos_fath = _pu_pos / 2; \
00122
00123 } \
00124 } while (0); \
00125 _pu_pos; \
00126 })
00127
00132 #define kal_eheap_add(self, _key, _value, _p_it) ({ \
00133 qos_rv __rv = QOS_OK; \
00134 typeof((self)->elems[0].p_iterator) _a_p_it = (_p_it); \
00135 do { \
00136 int _a_pos = (self)->num_elems + 1; \
00137 if (_a_pos == (self)->max_num_elems + 1) { \
00138 __rv = QOS_E_FULL; \
00139 break; \
00140 } \
00141 (self)->num_elems++; \
00142 _a_pos = kal_eheap_push_up((self), _a_pos, (_key)); \
00143 (self)->elems[_a_pos - 1].key = (_key); \
00144 (self)->elems[_a_pos - 1].value = (_value); \
00145 if (_a_p_it) { \
00146 (self)->elems[_a_pos - 1].p_iterator = _a_p_it; \
00147 _a_p_it->pos = _a_pos; \
00148 } else { \
00149 (self)->elems[_a_pos - 1].p_iterator = NULL; \
00150 } \
00151 } while (0); \
00152 __rv; \
00153 })
00154
00156 #define kal_eheap_get_min(self, p_key, p_value) ({ \
00157 qos_rv __gm_rv = QOS_OK; \
00158 do { \
00159 if ((self)->num_elems == 0) { \
00160 __gm_rv = QOS_E_EMPTY; \
00161 break; \
00162 } \
00163 *(p_key) = (self)->elems[0].key; \
00164 *(p_value) = (self)->elems[0].value; \
00165 } while (0); \
00166 __gm_rv; \
00167 })
00168
00175 #define kal_eheap_del_min(self) ({ \
00176 qos_rv __dm_rv = QOS_OK; \
00177 int _dm_pos = 1; \
00178 int _dm_key; \
00179 do { \
00180 if ((self)->num_elems == 0) { \
00181 __dm_rv = QOS_E_EMPTY; \
00182 break; \
00183 } \
00184 if ((self)->elems[0].p_iterator) \
00185 (self)->elems[0].p_iterator->pos = 0; \
00186 _dm_key = (self)->elems[(self)->num_elems - 1].key; \
00187 (self)->num_elems--; \
00188
00189 _dm_pos = kal_eheap_push_down((self), _dm_pos, _dm_key); \
00190
00191 \
00192 kal_eheap_nodecpy((self), _dm_pos, (self)->num_elems + 1); \
00193 } while (0); \
00194 __dm_rv; \
00195 })
00196
00204 #define kal_eheap_del(self, p_it) ({ \
00205 qos_rv __rv = QOS_OK; \
00206 int _d_pos = (p_it)->pos, _d_pos2; \
00207 typeof((self)->elems[0].key) _d_key; \
00208 do { \
00209 if ((self)->num_elems == 0) { \
00210 __rv = QOS_E_EMPTY; \
00211 break; \
00212 } \
00213 if (_d_pos == 0) { \
00214 __rv = QOS_E_INVALID_PARAM; \
00215 break; \
00216 } \
00217 (p_it)->pos = 0; \
00218 _d_key = (self)->elems[(self)->num_elems - 1].key; \
00219 (self)->num_elems--; \
00220 if ((self)->num_elems == 0 || (self)->num_elems + 1 == _d_pos) \
00221 break; \
00222 _d_pos2 = kal_eheap_push_down((self), _d_pos, _d_key); \
00223 if (_d_pos2 == _d_pos) \
00224 _d_pos2 = kal_eheap_push_up((self), _d_pos, _d_key); \
00225 \
00226 kal_eheap_nodecpy((self), _d_pos2, (self)->num_elems + 1); \
00227 } while (0); \
00228 __rv; \
00229 })
00230
00232 #define kal_eheap_size(self) (self)->num_elems
00233
00240 #define kal_eheap_iterator_valid(p_it) ((p_it)->pos != 0)
00241
00243 #define kal_eheap_iterator_init(p_it) \
00244 do { \
00245 (p_it)->pos = 0; \
00246 } while (0)
00247
00248 #define kal_eheap_begin(self, p_it) \
00249 do { \
00250 (p_it)->pos = 0; \
00251 } while (0)
00252
00253 #define kal_eheap_has_next(self, p_it) \
00254 ((p_it)->pos < (self)->num_elems)
00255
00256 #define kal_eheap_next(self, p_it, p_key, p_val) ({ \
00257 typeof(&(self)->elems[0].key) _p_key = (p_key); \
00258 typeof(&(self)->elems[0].value) _p_val = (p_val); \
00259 qos_rv __rv = QOS_OK; \
00260 do { \
00261 if ((p_it)->pos < (self)->num_elems) { \
00262 (p_it)->pos++; \
00263 if (_p_key) \
00264 *(_p_key) = (self)->elems[(p_it)->pos - 1].key; \
00265 if (_p_val) \
00266 *(_p_val) = (self)->elems[(p_it)->pos - 1].value; \
00267 } else { \
00268 __rv = QOS_E_EMPTY; \
00269 break; \
00270 } \
00271 } while (0); \
00272 __rv; \
00273 })
00274
00275 #endif