aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/evanix.h7
-rw-r--r--src/evanix.c36
-rw-r--r--src/jobs.c67
-rw-r--r--tests/meson.build2
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 <unistd.h>
#include <cjson/cJSON.h>
+#include <sqlite3.h>
#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)