ssize_t data_list_t(data_t *data){ // {{{ if( (data->ptr = list_t_alloc()) == NULL) return -ENOMEM; data->type = TYPE_LISTT; return 0; } // }}}
void search_state_t_alloc(search_state_t* p_state) { if (!p_state) return; p_state->p_weight_list = list_t_alloc(INITIAL_CAPACITY); p_state->p_open_set = heap_t_alloc(4, INITIAL_CAPACITY, LOAD_FACTOR, hash_function, equals_function, priority_cmp); p_state->p_closed_set = unordered_set_t_alloc(INITIAL_CAPACITY, LOAD_FACTOR, hash_function, equals_function); p_state->p_parent_map = unordered_map_t_alloc(INITIAL_CAPACITY, LOAD_FACTOR, hash_function, equals_function); p_state->p_cost_map = unordered_map_t_alloc(INITIAL_CAPACITY, LOAD_FACTOR, hash_function, equals_function); }
list_t* traceback_bidirectional_path(directed_graph_node_t* p_middle_node, unordered_map_t* p_parent_map_a, unordered_map_t* p_parent_map_b) { list_t* p_ret; directed_graph_node_t* p_current; if (!p_middle_node) return NULL; if (!p_parent_map_a) return NULL; if (!p_parent_map_b) return NULL; p_ret = list_t_alloc(INITIAL_CAPACITY); if (!p_ret) return NULL; p_current = p_middle_node; while (p_current) { list_t_push_front(p_ret, p_current); p_current = unordered_map_t_get(p_parent_map_a, p_current); } p_current = unordered_map_t_get(p_parent_map_b, p_middle_node); while (p_current) { list_t_push_back(p_ret, p_current); p_current = unordered_map_t_get(p_parent_map_b, p_current); } return p_ret; }
static ssize_t data_list_t_push(data_t *data, fastcall_push *fargs){ // {{{ list_t *fdata = (list_t *)data->ptr; if(fargs->data == NULL) // EOF return 0; if(fdata == NULL){ if( (fdata = data->ptr = list_t_alloc()) == NULL) return -ENOMEM; } return list_t_push(fdata, fargs->data); } // }}}
static ssize_t data_list_t_create(data_t *data, fastcall_crud *fargs){ // {{{ list_t *fdata = (list_t *)data->ptr; if(fargs->value == NULL) // EOF return 0; if(fdata == NULL){ if( (fdata = data->ptr = list_t_alloc()) == NULL) return -ENOMEM; } if(fargs->key == NULL || data_is_void(fargs->key)) return list_t_push(fdata, fargs->value); return -ENOSYS; } // }}}
list_t * list_t_copy (list_t *list){ // {{{ ssize_t ret; list_t *new_list; list_chunk_t *chunk; data_t data_copy; new_list = list_t_alloc(); for(chunk = list->head; chunk; chunk = chunk->cnext){ holder_copy(ret, &data_copy, &chunk->data); if(ret < 0) goto error; list_t_push(new_list, &data_copy); } return new_list; error: list_t_free(new_list); return NULL; } // }}}
list_t* traceback_path(directed_graph_node_t* p_target, unordered_map_t* p_parent_map) { list_t* p_ret; directed_graph_node_t* p_current; if (!p_target) return NULL; if (!p_parent_map) return NULL; p_ret = list_t_alloc(10); if (!p_ret) return NULL; p_current = p_target; while (p_current) { list_t_push_front(p_ret, p_current); p_current = unordered_map_t_get(p_parent_map, p_current); } return p_ret; }
list_t* dijkstra(directed_graph_node_t* p_source, directed_graph_node_t* p_target, directed_graph_weight_function_t* p_weight_function) { search_state_t state; list_t* p_weight_list; heap_t* p_open_set; unordered_set_t* p_closed_set; unordered_map_t* p_parent_map; unordered_map_t* p_cost_map; list_t* p_list; directed_graph_node_t* p_current; directed_graph_node_t* p_child; unordered_set_iterator_t* p_child_iterator; size_t i; /* Cannot pack a double into a void*, so use this simple structure. */ weight_t* p_weight; if (!p_source) return NULL; if (!p_target) return NULL; if (!p_weight_function) return NULL; search_state_t_alloc(&state); if (!search_state_t_is_ready(&state)) { search_state_t_free(&state); return NULL; } p_weight = malloc(sizeof(*p_weight)); p_weight->weight = 0.0; p_open_set = state.p_open_set; p_closed_set = state.p_closed_set; p_weight_list = state.p_weight_list; p_cost_map = state.p_cost_map; p_parent_map = state.p_parent_map; heap_t_add(p_open_set, p_source, p_weight); unordered_map_t_put(p_parent_map, p_source, NULL); unordered_map_t_put(p_cost_map, p_source, p_weight); list_t_push_back(p_weight_list, p_weight); while (heap_t_size(p_open_set) > 0) { p_current = heap_t_extract_min(p_open_set); if (equals_function(p_current, p_target)) { p_list = traceback_path(p_target, p_parent_map); search_state_t_free(&state); return p_list; } unordered_set_t_add(p_closed_set, p_current); p_child_iterator = unordered_set_iterator_t_alloc( directed_graph_node_t_children_set(p_current)); while (unordered_set_iterator_t_has_next(p_child_iterator)) { unordered_set_iterator_t_next(p_child_iterator, &p_child); if (unordered_set_t_contains(p_closed_set, p_child)) { continue; } double tmp_cost = ((weight_t*) unordered_map_t_get(p_cost_map, p_current))->weight; tmp_cost += *directed_graph_weight_function_t_get( p_weight_function, p_current, p_child); if (!unordered_map_t_contains_key(p_parent_map, p_child)) { p_weight = malloc(sizeof(*p_weight)); p_weight->weight = tmp_cost; heap_t_add(p_open_set, p_child, p_weight); unordered_map_t_put(p_parent_map, p_child, p_current); unordered_map_t_put(p_cost_map, p_child, p_weight); list_t_push_back(p_weight_list, p_weight); } else if (tmp_cost < ((weight_t*) unordered_map_t_get(p_cost_map, p_child))->weight) { p_weight = malloc(sizeof(*p_weight)); p_weight->weight = tmp_cost; heap_t_decrease_key(p_open_set, p_child, p_weight); unordered_map_t_put(p_parent_map, p_child, p_current); unordered_map_t_put(p_cost_map, p_child, p_weight); list_t_push_back(p_weight_list, p_weight); } } unordered_set_iterator_t_free(p_child_iterator); } /* Once here, return a empty path in order to denote the fact that the target node is not reachable from source node. */ search_state_t_free(&state); p_list = list_t_alloc(10); /* Deallocate the weights. */ for (i = 0; i < list_t_size(p_weight_list); ++i) { free(list_t_get(p_weight_list, i)); } return p_list; }
static ssize_t data_list_t_convert_from(data_t *dst, fastcall_convert_from *fargs){ // {{{ ssize_t ret = 0; list_t *fdata; uintmax_t transfered = 0; data_t sl_input = DATA_SLIDERT(fargs->src, 0); switch(fargs->format){ case FORMAT(native): case FORMAT(human): case FORMAT(config):; return data_list_t(dst); case FORMAT(hash):; hash_t *config; data_get(ret, TYPE_HASHT, config, fargs->src); if(ret != 0) return -EINVAL; if((fdata = dst->ptr) == NULL){ if( (fdata = dst->ptr = list_t_alloc()) == NULL) return -ENOMEM; } if(hash_iter(config, (hash_iterator)&iter_list_t_convert_from, dst, 0) != ITER_OK){ list_t_free(dst->ptr); return -EFAULT; } return 0; case FORMAT(packed):; data_t item; data_t d_item = DATA_PTR_DATAT(&item); if((fdata = dst->ptr) == NULL){ if( (fdata = dst->ptr = list_t_alloc()) == NULL) return -ENOMEM; } while(1){ data_set_void(&item); fastcall_convert_from r_convert = { { 5, ACTION_CONVERT_FROM }, &sl_input, FORMAT(packed) }; if( (ret = data_query(&d_item, &r_convert)) < 0) break; data_slider_t_set_offset(&sl_input, r_convert.transfered, SEEK_CUR); if(item.type == TYPE_LISTENDT) break; if( (ret = list_t_push(fdata, &item)) < 0) break; } transfered = data_slider_t_get_offset(&sl_input); break; default: return -ENOSYS; }; if(fargs->header.nargs >= 5) fargs->transfered = transfered; return ret; } // }}}