Skip to content

Use hashmap instead of linked list #107

@ligurio

Description

@ligurio

unreliablefs uses linked list for error injections, see

/* apply error injections defined in configuration one by one */
TAILQ_FOREACH(err, conf.errors, entries) {
unsigned int p = rand_range(MIN_PROBABLITY, MAX_PROBABLITY);
if (!(p <= err->probability)) {
fprintf(stderr, "errinj '%s' skipped: probability (%d) is not matched\n",
errinj_name[err->type], err->probability);
continue;
}
const char* op_name = fuse_op_name[operation];
if (is_regex_matched(err->path_regexp, path) != 0) {
fprintf(stderr, "errinj '%s' skipped: path_regexp (%s) is not matched\n",
errinj_name[err->type], err->path_regexp);
continue;
}
if (is_regex_matched(err->op_regexp, op_name) != 0) {
fprintf(stderr, "errinj '%s' skipped: op_regexp (%s) is not matched\n",
errinj_name[err->type], err->op_regexp);
continue;
}
fprintf(stdout, "%s triggered on operation '%s', %s\n",
errinj_name[err->type], op_name, path);
switch (err->type) {
case ERRINJ_NOOP:
rc = -ERRNO_NOOP;
break;
case ERRINJ_KILL_CALLER: ;
struct fuse_context *cxt = fuse_get_context();
if (cxt) {
int ret = kill(cxt->pid, DEFAULT_SIGNAL_NAME);
if (ret == -1) {
perror("kill");
}
fprintf(stdout, "send signal %s to TID %d\n",
strsignal(DEFAULT_SIGNAL_NAME), cxt->pid);
}
break;
case ERRINJ_ERRNO:
rc = op_random_errno(operation);
fprintf(stdout, "errno '%s'\n", strerror(rc));
rc = -rc;
break;
case ERRINJ_SLOWDOWN: ;
struct timespec ts = {};
ts.tv_nsec = err->duration;
fprintf(stdout, "start of '%s' slowdown for '%d' ns\n", op_name, err->duration);
if (nanosleep(&ts, NULL) != 0) {
perror("nanosleep");
} else {
fprintf(stdout, "end of '%s' slowdown with '%d' ns\n", op_name, err->duration);
}
break;
}
}

On each operation, it traverses a list with error injections, and it is not optimal from performance point of view, algorithmic complexity is O(N). It is better to use hashmap. For example, a static hashmap implemented by gperf1.

Footnotes

  1. https://www.gnu.org/software/gperf/manual/gperf.html

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions