From ee76b7aaf3e39fac459ac819d25b2c64c848bb3e Mon Sep 17 00:00:00 2001 From: sinanmohd Date: Sat, 24 Aug 2024 20:06:12 +0530 Subject: jobs/job_cost_estimate: init --- include/evanix.h | 7 +++++- src/evanix.c | 36 ++++++++++++++++++++++-------- src/jobs.c | 67 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ tests/meson.build | 2 +- 4 files changed, 101 insertions(+), 11 deletions(-) diff --git a/include/evanix.h b/include/evanix.h index 62dd22d..1d3d661 100644 --- a/include/evanix.h +++ b/include/evanix.h @@ -6,6 +6,11 @@ #ifndef EVANIX_H +struct estimate { + struct sqlite3 *db; + sqlite3_stmt *statement; +}; + struct evanix_opts_t { bool isflake; bool isdryrun; @@ -15,7 +20,7 @@ struct evanix_opts_t { bool check_cache_status; bool break_evanix; char *system; - struct sqlite3 *estimate; + struct estimate estimate; uint32_t max_builds; uint32_t max_time; int (*solver)(struct job **, struct job_clist *, int32_t); diff --git a/src/evanix.c b/src/evanix.c index 375678a..54379de 100644 --- a/src/evanix.c +++ b/src/evanix.c @@ -42,7 +42,8 @@ struct evanix_opts_t evanix_opts = { .check_cache_status = true, .solver = solver_highs, .break_evanix = false, - .estimate = NULL, + .estimate.db = NULL, + .estimate.statement = NULL, }; static int evanix_build_thread_create(struct build_thread *build_thread); @@ -139,6 +140,11 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, extern char *optarg; int longindex, c; + const char *query = "SELECT duration " + "FROM estimate " + "WHERE estimate.pname = ? " + "LIMIT 1 "; + int ret = 0; static struct option longopts[] = { @@ -181,7 +187,7 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, opts->solver_report = true; break; case 'e': - if (opts->estimate) { + if (opts->estimate.db) { fprintf(stderr, "option -%c can't be redefined " "Try 'evanix --help' for more " @@ -190,16 +196,23 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, return -EINVAL; } - ret = sqlite3_open_v2(optarg, &opts->estimate, + ret = sqlite3_open_v2(optarg, &opts->estimate.db, SQLITE_OPEN_READONLY | SQLITE_OPEN_FULLMUTEX, NULL); if (ret != SQLITE_OK) { print_err("Can't open database: %s", - sqlite3_errmsg(opts->estimate)); + sqlite3_errmsg(opts->estimate.db)); ret = -EPERM; goto out_free_evanix; } + ret = sqlite3_prepare_v2(opts->estimate.db, query, -1, + &opts->estimate.statement, + NULL); + if (ret != SQLITE_OK) { + print_err("%s", "Failed to prepare sql"); + return -EPERM; + } break; case 'k': @@ -311,7 +324,7 @@ static int opts_read(struct evanix_opts_t *opts, char **expr, int argc, "Try 'evanix --help' for more information.\n"); ret = -EINVAL; goto out_free_evanix; - } else if (opts->max_time && !opts->estimate) { + } else if (opts->max_time && !opts->estimate.db) { fprintf(stderr, "evanix: option --max-time implies --estimate\n" "Try 'evanix --help' for more information.\n"); ret = -EINVAL; @@ -334,15 +347,20 @@ static int evanix_free(struct evanix_opts_t *opts) { int ret; - if (opts->estimate) { - ret = sqlite3_close(opts->estimate); + if (opts->estimate.statement) { + sqlite3_finalize(opts->estimate.statement); + opts->estimate.statement = NULL; + } + + if (opts->estimate.db) { + ret = sqlite3_close(opts->estimate.db); if (ret != SQLITE_OK) { print_err("Can't open database: %s", - sqlite3_errmsg(opts->estimate)); + sqlite3_errmsg(opts->estimate.db)); return -EPERM; } - opts->estimate = NULL; + opts->estimate.db = NULL; } return 0; diff --git a/src/jobs.c b/src/jobs.c index 043dac0..485a188 100644 --- a/src/jobs.c +++ b/src/jobs.c @@ -5,6 +5,7 @@ #include #include +#include #include "evanix.h" #include "jobs.h" @@ -27,6 +28,7 @@ static int job_read_inputdrvs(struct job *job, cJSON *input_drvs); static int job_read_outputs(struct job *job, cJSON *outputs); static int job_deps_list_insert(struct job *job, struct job *dep); static int job_output_list_insert(struct job *job, struct output *output); +static char *drv_path_to_pname(char *drv_path); static void output_free(struct output *output) { @@ -39,6 +41,32 @@ static void output_free(struct output *output) free(output); } +static char *drv_path_to_pname(char *drv_path) +{ + char *pname, *p; + + p = strrchr(drv_path, '/'); + if (p == NULL) + return NULL; + + p = strchr(p, '-'); + if (p == NULL) + return NULL; + p++; + if (*p == '\0') + return NULL; + + pname = strdup(p); + if (pname == NULL) + return NULL; + + p = strchr(pname, '-'); + if (p != NULL) + *p = '\0'; + + return pname; +} + static int job_output_list_insert(struct job *job, struct output *output) { size_t newsize; @@ -123,6 +151,45 @@ int job_parents_list_insert(struct job *job, struct job *parent) return 0; } +static int job_cost_estimate(struct job *job) +{ + int ret; + char *pname; + + pname = drv_path_to_pname(job->drv_path); + if (pname == NULL) { + print_err("Unable to obtain pname from drv_path: %s", + job->drv_path); + return -EINVAL; + } + + ret = sqlite3_bind_text(evanix_opts.estimate.statement, 1, pname, -1, + NULL); + if (ret != SQLITE_OK) { + print_err("%s", "Failed to bind sql"); + ret = -EPERM; + goto out_free_pname; + } + + ret = sqlite3_step(evanix_opts.estimate.statement); + if (ret == SQLITE_DONE) { + ret = -ENOENT; + goto out_free_pname; + } + if (ret != SQLITE_ROW) { + print_err("%s", "Failed to step sql"); + ret = -EPERM; + goto out_free_pname; + } + + ret = sqlite3_column_int(evanix_opts.estimate.statement, 0); + +out_free_pname: + free(pname); + + return ret; +} + int job_cost_recursive(struct job *job) { int32_t builds = 1; diff --git a/tests/meson.build b/tests/meson.build index d8f1ef6..5b30498 100644 --- a/tests/meson.build +++ b/tests/meson.build @@ -8,7 +8,7 @@ dag_test = executable( ], include_directories: evanix_inc, - dependencies: [ cjson_dep, highs_dep ], + dependencies: [ cjson_dep, highs_dep, sqlite_dep ], ) test('dag', dag_test) -- cgit v1.2.3