146 | | CRIT_DROP, /// Node is not interesting, stop recursion here in the graph |
147 | | CRIT_RECURS, /// Node is not selected, but we can recurs through it |
148 | | CRIT_SELECT, /// Node is selected, and may be recursed down |
| 152 | TOPO_CRIT_DROP, /// Node is not interesting, stop recursion here in the graph |
| 153 | TOPO_CRIT_RECURS, /// Node is not selected, but we can recurs through it |
| 154 | TOPO_CRIT_SELECT, /// Node is selected, and may be recursed down |
| 155 | }; |
| 156 | |
| 157 | enum topo_cmp_e |
| 158 | { |
| 159 | TOPO_CMP_LEFT = -1, /// left better than right |
| 160 | TOPO_CMP_EQ = 0, /// left equals right |
| 161 | TOPO_CMP_RIGHT = 1, /// right better than left |
| 162 | }; |
| 163 | |
| 164 | struct topo_select_item_s |
| 165 | { |
| 166 | const struct topo_node_s *node; |
| 167 | struct topo_metrics_s metrics; // not a pointer ! |
158 | | typedef enum topo_crit_val_e crit_func_t(struct topo_node_s *node, struct topo_metrics_s *metrics, void *priv); |
159 | | |
160 | | error_t select( |
161 | | struct topo_node_s *start, /// Start node |
162 | | crit_func_t *crit, void *crit_priv, /// Criterium function, telling whether a node is eligible |
163 | | size_t max_nodes, /// Maximal number of nodes to return |
164 | | struct topo_node_s **nodes); /// Output nodes. Table must be allocated by caller and be able to contain max_nodes |
| 176 | typedef enum topo_crit_val_e topo_crit_func_t( |
| 177 | const struct topo_select_item_s *item, |
| 178 | const void *priv); |
| 179 | |
| 180 | /** |
| 181 | Sort function |
| 182 | @param left Node/metrics to compare |
| 183 | @param right Node/metrics to compare |
| 184 | @param priv Sort private data |
| 185 | @returns comparaison result |
| 186 | */ |
| 187 | typedef enum topo_cmp_e topo_sort_func_t( |
| 188 | const struct topo_select_item_s *left, |
| 189 | const struct topo_select_item_s *right, |
| 190 | const void *priv); |
| 191 | |
| 192 | error_t topo_select( |
| 193 | const struct topo_node_s *start, /// Start node |
| 194 | topo_crit_func_t *crit, const void *crit_priv, /// Criterium function, telling whether a node is eligible |
| 195 | topo_sort_func_t *sort, const void *sort_priv, /// Sorting function, telling order of nodes |
| 196 | size_t max_items, /// Maximal number of nodes to return |
| 197 | struct topo_select_item_s *items); /// Output nodes+metrics. Table must be allocated by caller and be able to contain @tt max_items |
170 | | error_t next( |
171 | | struct topo_node_s *node, /// node of our model where we are coming from |
172 | | struct topo_port_s *input, /// input in node. May be NULL on start node |
173 | | const struct topo_addr_s *dest, /// destination address for the current address space |
174 | | struct topo_metrics_s *metrics, /// Metrics to update on the go |
175 | | struct topo_port_s **output_peer); /// Input port of the next hop |
176 | | |
177 | | error_t select_next( |
178 | | struct topo_node_s *node, /// node of our model where we are coming from |
179 | | struct topo_port_s *input, /// input in node. May be NULL on start node |
180 | | struct topo_metrics_s *metrics, /// Metrics to update on the go |
181 | | struct topo_port_s **output_peer); /// Input port of the next hop |
182 | | }}} |
183 | | |
184 | | |
185 | | = Open questions = |
186 | | |
187 | | * Are edges of graph internal to node's private data or are explicit ? |
188 | | * How to handle multiple output connexions of the same addressing type ? |
189 | | * Maybe add an "output" index with source node ? (after source node, there should be no hesitation possible) |
190 | | |
| 203 | #!c |
| 204 | /** |
| 205 | Initialize a topology node. |
| 206 | */ |
| 207 | typedef void topo_model_init_func_t(struct topo_node_s *node, const void *param); |
| 208 | |
| 209 | /** |
| 210 | Destroy a topology node. Reclaim all associated memory |
| 211 | */ |
| 212 | typedef void topo_model_cleanup_func_t(struct topo_node_s *node); |
| 213 | |
| 214 | /** |
| 215 | Compute routing and cost from this node to the next hop, routing |
| 216 | towards a given destination |
| 217 | |
| 218 | @param node Node of our model where we are coming from |
| 219 | @param input Input port in node. May be NULL on start node |
| 220 | @param dest Destination address for the current address space |
| 221 | @param metrics Metrics to update on the go |
| 222 | @param peer_input Input port of the next hop |
| 223 | */ |
| 224 | typedef error_t topo_model_journey_next_func_t( |
| 225 | const struct topo_node_s *node, |
| 226 | const struct topo_port_s *input, |
| 227 | const struct topo_addr_s *dest, |
| 228 | struct topo_metrics_s *metrics, |
| 229 | struct topo_port_s *peer_input); |
| 230 | |
| 231 | /** |
| 232 | Explore the topology graph. Each call to this function must return next |
| 233 | valid port. |
| 234 | |
| 235 | @param node Current node |
| 236 | @param input Port where we came from, exploration should not "go back" to this edge. May be NULL on recursion start |
| 237 | @param metrics Metrics up to this node |
| 238 | @param item Returned item for next recursion |
| 239 | @param state Pointer to a void* where select_next can store its internal state. |
| 240 | |
| 241 | @tt *state is @tt NULL on first call for each node. |
| 242 | |
| 243 | Successive calls to select_next for a given node in a given exploration use the same @tt state value. |
| 244 | |
| 245 | @note As there is no warning for end of iteration, there is no way of calling @tt free(), so @tt *state should be a pointer to preallocated internal data. |
| 246 | */ |
| 247 | typedef error_t topo_model_select_next_func_t( |
| 248 | const struct topo_node_s *node, |
| 249 | const struct topo_port_s *input, |
| 250 | const struct topo_metrics_s *input_metrics, |
| 251 | struct topo_select_item_s *item, |
| 252 | void **state); |
| 253 | }}} |
| 254 | |
| 255 | = topo_model_s struct = |
| 256 | |
| 257 | {{{ |
| 258 | #!c |
| 259 | struct topo_model_s |
| 260 | { |
| 261 | topo_model_init_func_t *init; |
| 262 | topo_model_cleanup_func_t *cleanup; |
| 263 | topo_model_journey_next_func_t *journey_next; |
| 264 | topo_model_select_next_func_t *select_next; |
| 265 | }; |
| 266 | }}} |