Skip to content

Commit 4d47b18

Browse files
add move-to-front optimisation
1 parent 6bdd72a commit 4d47b18

1 file changed

Lines changed: 58 additions & 8 deletions

File tree

src/basic/variable.c

Lines changed: 58 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -413,12 +413,29 @@ const char* basic_get_string_variable(const char* var, struct basic_ctx* ctx)
413413
}
414414
list[0] = ctx->str_variables;
415415
size_t len = strlen(var);
416+
416417
for (j = ctx->call_stack_ptr; j >= 0; --j) {
417418
struct ub_var_string* cur = list[j];
418-
for (; cur; cur = cur->next) {
419+
struct ub_var_string* prev = NULL;
420+
while (cur) {
419421
if (len == cur->name_length && !strcmp(var, cur->varname)) {
422+
/* move-to-front optimisation */
423+
if (prev) {
424+
/* unlink */
425+
prev->next = cur->next;
426+
/* relink at head */
427+
if (j == 0) {
428+
cur->next = ctx->str_variables;
429+
ctx->str_variables = cur;
430+
} else {
431+
cur->next = ctx->local_string_variables[j];
432+
ctx->local_string_variables[j] = cur;
433+
}
434+
}
420435
return cur->value;
421436
}
437+
prev = cur;
438+
cur = cur->next;
422439
}
423440
}
424441

@@ -492,7 +509,7 @@ int64_t basic_get_int_variable(const char* var, struct basic_ctx* ctx)
492509
if (basic_builtin_int_fn(var, ctx, &retv)) {
493510
return retv;
494511
}
495-
512+
496513
if (varname_is_function(var)) {
497514
return basic_eval_int_fn(var, ctx);
498515
}
@@ -507,18 +524,36 @@ int64_t basic_get_int_variable(const char* var, struct basic_ctx* ctx)
507524
list[j] = ctx->local_int_variables[j];
508525
}
509526
list[0] = ctx->int_variables;
527+
510528
size_t len = strlen(var);
511529
for (j = ctx->call_stack_ptr; j >= 0; --j) {
512530
struct ub_var_int* cur = list[j];
513-
for (; cur; cur = cur->next) {
531+
struct ub_var_int* prev = NULL;
532+
while (cur) {
514533
if (len == cur->name_length && !strcmp(var, cur->varname)) {
515-
int64_t v = cur->value;
516534
/* If ERROR is read, it resets its value */
535+
int64_t v = cur->value;
517536
if (len == 5 && !strcmp(var, "ERROR")) {
518537
basic_set_int_variable("ERROR", 0, ctx, false, false);
519538
}
539+
540+
/* move-to-front optimisation */
541+
if (prev) {
542+
/* unlink */
543+
prev->next = cur->next;
544+
/* relink at head */
545+
if (j == 0) {
546+
cur->next = ctx->int_variables;
547+
ctx->int_variables = cur;
548+
} else {
549+
cur->next = ctx->local_int_variables[j];
550+
ctx->local_int_variables[j] = cur;
551+
}
552+
}
520553
return v;
521554
}
555+
prev = cur;
556+
cur = cur->next;
522557
}
523558
}
524559

@@ -531,7 +566,7 @@ bool basic_get_double_variable(const char* var, struct basic_ctx* ctx, double* r
531566
if (basic_builtin_double_fn(var, ctx, res)) {
532567
return true;
533568
}
534-
569+
535570
if (varname_is_double_function(var)) {
536571
basic_eval_double_fn(var, ctx, res);
537572
return true;
@@ -541,25 +576,40 @@ bool basic_get_double_variable(const char* var, struct basic_ctx* ctx, double* r
541576
return basic_get_double_array_variable(var, arr_variable_index(ctx), ctx, res);
542577
}
543578

544-
545579
struct ub_var_double* list[ctx->call_stack_ptr + 1];
546580
int64_t j;
547581
for (j = ctx->call_stack_ptr; j > 0; --j) {
548582
list[j] = ctx->local_double_variables[j];
549583
}
550584
list[0] = ctx->double_variables;
585+
551586
size_t len = strlen(var);
552587
for (j = ctx->call_stack_ptr; j >= 0; --j) {
553588
struct ub_var_double* cur = list[j];
554-
for (; cur; cur = cur->next) {
589+
struct ub_var_double* prev = NULL;
590+
while (cur) {
555591
if (len == cur->name_length && !strcmp(var, cur->varname)) {
556592
*res = cur->value;
593+
/* move-to-front optimisation */
594+
if (prev) {
595+
/* unlink */
596+
prev->next = cur->next;
597+
/* relink at head */
598+
if (j == 0) {
599+
cur->next = ctx->double_variables;
600+
ctx->double_variables = cur;
601+
} else {
602+
cur->next = ctx->local_double_variables[j];
603+
ctx->local_double_variables[j] = cur;
604+
}
605+
}
557606
return true;
558607
}
608+
prev = cur;
609+
cur = cur->next;
559610
}
560611
}
561612

562-
563613
if (var[len - 1] == '#') {
564614
tokenizer_error_printf(ctx, "No such real variable '%s'", var);
565615
}

0 commit comments

Comments
 (0)