diff options
Diffstat (limited to 'src_c')
| -rw-r--r-- | src_c/common.c | 12 | ||||
| -rw-r--r-- | src_c/common.h | 6 | ||||
| -rw-r--r-- | src_c/csp.c | 57 | ||||
| -rw-r--r-- | src_c/main.c | 19 | ||||
| -rw-r--r-- | src_c/pool.c | 18 | ||||
| -rw-r--r-- | src_c/pool.h | 3 |
6 files changed, 74 insertions, 41 deletions
diff --git a/src_c/common.c b/src_c/common.c index 403fe87..66b826d 100644 --- a/src_c/common.c +++ b/src_c/common.c @@ -392,8 +392,9 @@ static int read_params(opcut_params_t *params, char *json, jsmntok_t *tokens, } -int opcut_params_init(opcut_params_t *params, opcut_pool_t *panel_pool, - opcut_pool_t *item_pool, opcut_str_t *json) { +int opcut_params_init(hat_allocator_t *a, opcut_params_t *params, + opcut_pool_t *panel_pool, opcut_pool_t *item_pool, + opcut_str_t *json) { params->panel_pool = panel_pool; params->item_pool = item_pool; @@ -405,21 +406,22 @@ int opcut_params_init(opcut_params_t *params, opcut_pool_t *panel_pool, if (tokens_len < 0) return OPCUT_ERROR; - jsmntok_t *tokens = malloc(tokens_len * sizeof(jsmntok_t)); + jsmntok_t *tokens = + hat_allocator_alloc(a, tokens_len * sizeof(jsmntok_t), NULL); if (!tokens) return OPCUT_ERROR; jsmn_init(&parser); tokens_len = jsmn_parse(&parser, json->data, json->len, tokens, tokens_len); if (tokens_len < 0) { - free(tokens); + hat_allocator_free(a, tokens); return OPCUT_ERROR; } size_t pos = 0; int err = read_params(params, json->data, tokens, &pos); - free(tokens); + hat_allocator_free(a, tokens); return err; } diff --git a/src_c/common.h b/src_c/common.h index 3464a61..22e6a88 100644 --- a/src_c/common.h +++ b/src_c/common.h @@ -3,6 +3,7 @@ #include <stdbool.h> #include <stdio.h> +#include <hat/allocator.h> #include "pool.h" #define OPCUT_SUCCESS 0 @@ -86,8 +87,9 @@ typedef struct { } opcut_result_t; -int opcut_params_init(opcut_params_t *params, opcut_pool_t *panel_pool, - opcut_pool_t *item_pool, opcut_str_t *json); +int opcut_params_init(hat_allocator_t *a, opcut_params_t *params, + opcut_pool_t *panel_pool, opcut_pool_t *item_pool, + opcut_str_t *json); int opcut_result_write(opcut_result_t *result, FILE *stream); #ifdef __cplusplus diff --git a/src_c/csp.c b/src_c/csp.c index 9cd25ec..7d837bf 100644 --- a/src_c/csp.c +++ b/src_c/csp.c @@ -1,4 +1,5 @@ #include "csp.h" +#include "common.h" #define FITNESS_K 0.03 @@ -252,12 +253,17 @@ static void free_unused(opcut_result_t *result) { } -static void free_last_used(opcut_result_t *result) { - opcut_pool_free(result->used_pool, result->used); +static void free_used(opcut_result_t *result, opcut_used_t *last_used) { + while (result->used && result->used != last_used) { + opcut_used_t *next = result->used->next; + opcut_pool_free(result->used_pool, result->used); + result->used = next; + } } -static int calculate_greedy(opcut_result_t *result, opcut_item_t *items) { +static int calculate_greedy(opcut_result_t *result, opcut_item_t *items, + bool forward_greedy) { for (opcut_item_t *item = items; item; item = item->next) { opcut_result_t best_result; fitness_t best_fitness; @@ -279,7 +285,33 @@ static int calculate_greedy(opcut_result_t *result, opcut_item_t *items) { return OPCUT_ERROR; fitness_t temp_fitness; - calculate_fitness(&temp_result, &temp_fitness); + if (!forward_greedy) { + calculate_fitness(&temp_result, &temp_fitness); + + } else { + opcut_result_t greedy_result = temp_result; + if (copy_unused(&greedy_result, temp_result.unused)) + return OPCUT_ERROR; + + int err = + calculate_greedy(&greedy_result, item->next, false); + + if (!err) { + calculate_fitness(&greedy_result, &temp_fitness); + free_used(&greedy_result, temp_result.used); + free_unused(&greedy_result); + + } else if (err == OPCUT_UNSOLVABLE) { + free_used(&greedy_result, temp_result.used); + free_used(&temp_result, result->used); + free_unused(&greedy_result); + free_unused(&temp_result); + continue; + + } else { + return err; + } + } if (!solvable) { best_result = temp_result; @@ -288,13 +320,13 @@ static int calculate_greedy(opcut_result_t *result, opcut_item_t *items) { } else if (compare_fitness(&temp_fitness, &best_fitness) < 0) { - free_last_used(&best_result); + free_used(&best_result, result->used); free_unused(&best_result); best_result = temp_result; best_fitness = temp_fitness; } else { - free_last_used(&temp_result); + free_used(&temp_result, result->used); free_unused(&temp_result); } } @@ -312,15 +344,6 @@ static int calculate_greedy(opcut_result_t *result, opcut_item_t *items) { } -static int calculate_forward_greedy(opcut_result_t *result, - opcut_item_t *items) { - for (opcut_item_t *item = items; item; item = item->next) { - } - - return OPCUT_SUCCESS; -} - - int opcut_calculate(opcut_pool_t *used_pool, opcut_pool_t *unused_pool, opcut_method_t method, opcut_params_t *params, opcut_result_t *result) { @@ -350,10 +373,10 @@ int opcut_calculate(opcut_pool_t *used_pool, opcut_pool_t *unused_pool, } if (method == OPCUT_METHOD_GREEDY) - return calculate_greedy(result, params->items); + return calculate_greedy(result, params->items, false); if (method == OPCUT_METHOD_FORWARD_GREEDY) - return calculate_forward_greedy(result, params->items); + return calculate_greedy(result, params->items, true); return OPCUT_ERROR; } diff --git a/src_c/main.c b/src_c/main.c index bf0b117..5532de0 100644 --- a/src_c/main.c +++ b/src_c/main.c @@ -59,12 +59,12 @@ static int parse_args(args_t *args, int argc, char **argv) { } -static int read_stream(FILE *stream, opcut_str_t *json) { +static int read_stream(hat_allocator_t *a, FILE *stream, opcut_str_t *json) { size_t size = 0; while (!(json->len < size)) { size += 4096; - char *data = realloc(json->data, size); + char *data = hat_allocator_alloc(a, size, json->data); if (!data) return OPCUT_ERROR; @@ -77,10 +77,11 @@ static int read_stream(FILE *stream, opcut_str_t *json) { int main(int argc, char **argv) { - opcut_pool_t *panel_pool = opcut_pool_create(sizeof(opcut_panel_t)); - opcut_pool_t *item_pool = opcut_pool_create(sizeof(opcut_item_t)); - opcut_pool_t *used_pool = opcut_pool_create(sizeof(opcut_used_t)); - opcut_pool_t *unused_pool = opcut_pool_create(sizeof(opcut_unused_t)); + hat_allocator_t *a = &hat_allocator_libc; + opcut_pool_t *panel_pool = opcut_pool_create(a, sizeof(opcut_panel_t)); + opcut_pool_t *item_pool = opcut_pool_create(a, sizeof(opcut_item_t)); + opcut_pool_t *used_pool = opcut_pool_create(a, sizeof(opcut_used_t)); + opcut_pool_t *unused_pool = opcut_pool_create(a, sizeof(opcut_unused_t)); args_t args; FILE *input_stream = NULL; @@ -115,13 +116,13 @@ int main(int argc, char **argv) { goto cleanup; } - exit_code = read_stream(input_stream, &json); + exit_code = read_stream(a, input_stream, &json); if (exit_code) { fprintf(stderr, "error reading input stream\n"); goto cleanup; } - exit_code = opcut_params_init(¶ms, panel_pool, item_pool, &json); + exit_code = opcut_params_init(a, ¶ms, panel_pool, item_pool, &json); if (exit_code) { fprintf(stderr, "error parsing calculation parameters\n"); goto cleanup; @@ -139,7 +140,7 @@ int main(int argc, char **argv) { cleanup: if (json.data) - free(json.data); + hat_allocator_free(a, json.data); if (output_stream) fclose(output_stream); if (input_stream) diff --git a/src_c/pool.c b/src_c/pool.c index 04968c8..7e2bd02 100644 --- a/src_c/pool.c +++ b/src_c/pool.c @@ -11,6 +11,7 @@ typedef struct header_t { struct opcut_pool_t { + hat_allocator_t *a; size_t item_size; header_t *blocks; header_t *items; @@ -23,9 +24,11 @@ static void allocate_block(opcut_pool_t *pool) { if (items_per_block < 1) items_per_block = 1; - header_t *block = - malloc(sizeof(header_t) + - items_per_block * (sizeof(header_t) + pool->item_size)); + header_t *block = hat_allocator_alloc( + pool->a, + sizeof(header_t) + + items_per_block * (sizeof(header_t) + pool->item_size), + NULL); if (!block) return; block->next = pool->blocks; @@ -40,14 +43,15 @@ static void allocate_block(opcut_pool_t *pool) { } -opcut_pool_t *opcut_pool_create(size_t item_size) { - opcut_pool_t *pool = malloc(sizeof(opcut_pool_t)); +opcut_pool_t *opcut_pool_create(hat_allocator_t *a, size_t item_size) { + opcut_pool_t *pool = hat_allocator_alloc(a, sizeof(opcut_pool_t), NULL); if (!pool) return NULL; if (item_size % sizeof(void *) != 0) item_size += sizeof(void *) - (item_size % sizeof(void *)); + pool->a = a; pool->item_size = item_size; pool->blocks = NULL; pool->items = NULL; @@ -60,9 +64,9 @@ void opcut_pool_destroy(opcut_pool_t *pool) { while (pool->blocks) { header_t *block = pool->blocks; pool->blocks = block->next; - free(block); + hat_allocator_free(pool->a, block); } - free(pool); + hat_allocator_free(pool->a, pool); } diff --git a/src_c/pool.h b/src_c/pool.h index 6998df6..e6ac0b2 100644 --- a/src_c/pool.h +++ b/src_c/pool.h @@ -2,6 +2,7 @@ #define OPCUT_POOL_H #include <stddef.h> +#include <hat/allocator.h> #ifdef __cplusplus extern "C" { @@ -9,7 +10,7 @@ extern "C" { typedef struct opcut_pool_t opcut_pool_t; -opcut_pool_t *opcut_pool_create(size_t item_size); +opcut_pool_t *opcut_pool_create(hat_allocator_t *a, size_t item_size); void opcut_pool_destroy(opcut_pool_t *pool); void *opcut_pool_alloc(opcut_pool_t *pool); void opcut_pool_free(opcut_pool_t *pool, void *item); |
