]> git.kaiwu.me - njs.git/commitdiff
Shell: simplified console.time()/timeEnd() pair.
authorDmitry Volyntsev <xeioex@nginx.com>
Thu, 21 Sep 2023 19:40:53 +0000 (12:40 -0700)
committerDmitry Volyntsev <xeioex@nginx.com>
Thu, 21 Sep 2023 19:40:53 +0000 (12:40 -0700)
Using a queue instead of a hash here because we assume that the
number of profile timers will be low.

external/njs_shell.c
test/shell_test.exp

index 9fc86d6bdca8fcb6fa012a26924255abd37b3957..d14586505e5ef4dbd554e3485f1582e172de6e9b 100644 (file)
@@ -80,8 +80,9 @@ typedef struct {
 
 
 typedef struct {
-    njs_opaque_value_t      name;
+    njs_str_t               name;
     uint64_t                time;
+    njs_queue_link_t        link;
 } njs_timelabel_t;
 
 
@@ -91,7 +92,7 @@ typedef struct {
     njs_lvlhsh_t            events;  /* njs_ev_t * */
     njs_queue_t             posted_events;
 
-    njs_lvlhsh_t            labels;  /* njs_timelabel_t */
+    njs_queue_t             labels;
 
     njs_completion_t        completion;
 } njs_console_t;
@@ -136,8 +137,6 @@ static void njs_console_clear_timer(njs_external_ptr_t external,
 static void njs_console_log(njs_vm_t *vm, njs_external_ptr_t external,
     njs_log_level_t level, const u_char *start, size_t length);
 
-static njs_int_t njs_timelabel_hash_test(njs_lvlhsh_query_t *lhq, void *data);
-
 static njs_int_t lvlhsh_key_test(njs_lvlhsh_query_t *lhq, void *data);
 static void *lvlhsh_pool_alloc(void *pool, size_t size);
 static void lvlhsh_pool_free(void *pool, void *p, size_t size);
@@ -275,14 +274,6 @@ static const njs_lvlhsh_proto_t  lvlhsh_proto  njs_aligned(64) = {
 };
 
 
-static const njs_lvlhsh_proto_t  njs_timelabel_hash_proto njs_aligned(64) = {
-    NJS_LVLHSH_DEFAULT,
-    njs_timelabel_hash_test,
-    lvlhsh_pool_alloc,
-    lvlhsh_pool_free,
-};
-
-
 static njs_vm_ops_t njs_console_ops = {
     njs_console_set_timer,
     njs_console_clear_timer,
@@ -840,8 +831,7 @@ njs_console_init(njs_vm_t *vm, njs_console_t *console)
 
     njs_lvlhsh_init(&console->events);
     njs_queue_init(&console->posted_events);
-
-    njs_lvlhsh_init(&console->labels);
+    njs_queue_init(&console->labels);
 
     console->completion.completions = njs_vm_completions(vm, NULL);
     if (console->completion.completions == NULL) {
@@ -1408,12 +1398,13 @@ static njs_int_t
 njs_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    njs_int_t           ret;
-    njs_str_t           name;
-    njs_value_t         *value;
-    njs_console_t       *console;
-    njs_timelabel_t     *label;
-    njs_lvlhsh_query_t  lhq;
+    njs_int_t         ret;
+    njs_str_t         name;
+    njs_queue_t       *labels;
+    njs_value_t       *value;
+    njs_console_t     *console;
+    njs_timelabel_t   *label;
+    njs_queue_link_t  *link;
 
     static const njs_str_t  default_label = njs_str("default");
 
@@ -1441,41 +1432,32 @@ njs_ext_console_time(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_value_string_get(value, &name);
     }
 
-    label = njs_mp_alloc(njs_vm_memory_pool(vm), sizeof(njs_timelabel_t));
-    if (njs_slow_path(label == NULL)) {
-        njs_vm_memory_error(vm);
-        return NJS_ERROR;
-    }
-
-    lhq.replace = 0;
-    lhq.key = name;
-    lhq.key_hash = njs_djb_hash(name.start, name.length);
-    lhq.value = label;
-    lhq.pool = njs_vm_memory_pool(vm);
-    lhq.proto = &njs_timelabel_hash_proto;
-
-    ret = njs_lvlhsh_insert(&console->labels, &lhq);
+    labels = &console->labels;
+    link = njs_queue_first(labels);
 
-    if (njs_fast_path(ret == NJS_OK)) {
-        (void) njs_vm_value_string_set(vm, njs_value_arg(&label->name),
-                                       name.start, name.length);
-
-    } else {
-        njs_mp_free(njs_vm_memory_pool(vm), label);
+    while (link != njs_queue_tail(labels)) {
+        label = njs_queue_link_data(link, njs_timelabel_t, link);
 
-        if (njs_slow_path(ret == NJS_ERROR)) {
-            njs_vm_error(vm, "lvlhsh insert failed");
-
-            return NJS_ERROR;
+        if (njs_strstr_eq(&name, &label->name)) {
+            njs_vm_log(vm, "Timer \"%V\" already exists.\n", &name);
+            njs_value_undefined_set(retval);
+            return NJS_OK;
         }
 
-        njs_vm_log(vm, "Timer \"%V\" already exists.\n", &name);
+        link = njs_queue_next(link);
+    }
 
-        label = lhq.value;
+    label = njs_mp_alloc(njs_vm_memory_pool(vm), sizeof(njs_timelabel_t));
+    if (njs_slow_path(label == NULL)) {
+        njs_vm_memory_error(vm);
+        return NJS_ERROR;
     }
 
+    label->name = name;
     label->time = njs_time();
 
+    njs_queue_insert_tail(&console->labels, &label->link);
+
     njs_value_undefined_set(retval);
 
     return NJS_OK;
@@ -1486,13 +1468,14 @@ static njs_int_t
 njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
     njs_index_t unused, njs_value_t *retval)
 {
-    uint64_t            ns, ms;
-    njs_int_t           ret;
-    njs_str_t           name;
-    njs_value_t         *value;
-    njs_console_t       *console;
-    njs_timelabel_t     *label;
-    njs_lvlhsh_query_t  lhq;
+    uint64_t          ns, ms;
+    njs_int_t         ret;
+    njs_str_t         name;
+    njs_queue_t       *labels;
+    njs_value_t       *value;
+    njs_console_t     *console;
+    njs_timelabel_t   *label;
+    njs_queue_link_t  *link;
 
     static const njs_str_t  default_label = njs_str("default");
 
@@ -1522,36 +1505,34 @@ njs_ext_console_time_end(njs_vm_t *vm, njs_value_t *args, njs_uint_t nargs,
         njs_value_string_get(value, &name);
     }
 
-    lhq.key = name;
-    lhq.key_hash = njs_djb_hash(name.start, name.length);
-    lhq.pool = njs_vm_memory_pool(vm);
-    lhq.proto = &njs_timelabel_hash_proto;
-
-    ret = njs_lvlhsh_delete(&console->labels, &lhq);
+    labels = &console->labels;
+    link = njs_queue_first(labels);
 
-    if (njs_fast_path(ret == NJS_OK)) {
-
-        label = lhq.value;
+    for ( ;; ) {
+        if (link == njs_queue_tail(labels)) {
+            njs_vm_log(vm, "Timer \"%V\" doesn’t exist.\n", &name);
+            njs_value_undefined_set(retval);
+            return NJS_OK;
+        }
 
-        ns = ns - label->time;
+        label = njs_queue_link_data(link, njs_timelabel_t, link);
 
-        ms = ns / 1000000;
-        ns = ns % 1000000;
+        if (njs_strstr_eq(&name, &label->name)) {
+            njs_queue_remove(&label->link);
+            break;
+        }
 
-        njs_vm_log(vm, "%V: %uL.%06uLms\n", &name, ms, ns);
+        link = njs_queue_next(link);
+    }
 
-        /* GC: release. */
-        njs_mp_free(njs_vm_memory_pool(vm), label);
+    ns = ns - label->time;
 
-    } else {
-        if (ret == NJS_ERROR) {
-            njs_vm_error(vm, "lvlhsh delete failed");
+    ms = ns / 1000000;
+    ns = ns % 1000000;
 
-            return NJS_ERROR;
-        }
+    njs_vm_log(vm, "%V: %uL.%06uLms\n", &name, ms, ns);
 
-        njs_vm_log(vm, "Timer \"%V\" doesn’t exist.\n", &name);
-    }
+    njs_mp_free(njs_vm_memory_pool(vm), label);
 
     njs_value_undefined_set(retval);
 
@@ -1655,23 +1636,6 @@ njs_console_log(njs_vm_t *vm, njs_external_ptr_t external,
 }
 
 
-static njs_int_t
-njs_timelabel_hash_test(njs_lvlhsh_query_t *lhq, void *data)
-{
-    njs_str_t        str;
-    njs_timelabel_t  *label;
-
-    label = data;
-    njs_value_string_get(njs_value_arg(&label->name), &str);
-
-    if (njs_strstr_eq(&lhq->key, &str)) {
-        return NJS_OK;
-    }
-
-    return NJS_DECLINED;
-}
-
-
 static njs_int_t
 lvlhsh_key_test(njs_lvlhsh_query_t *lhq, void *data)
 {
index e889eea4f86a8c5fea1b291420b9329c25aac3fc..eee76c34e7431bb5a36bb94999492d63177ed917 100644 (file)
@@ -299,6 +299,8 @@ njs_test {
      "console.timeEnd()\r\nTimer \"default\" doesn’t exist."}
     {"console.timeEnd('abc')\r\n"
      "console.timeEnd('abc')\r\nTimer \"abc\" doesn’t exist."}
+    {"console.time('abc')\r\n"
+     "console.time('abc')\r\nundefined\r\n>> "}
 }
 
 njs_test {