texinfo-commits
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[no subject]


From: Patrice Dumas
Date: Thu, 28 Dec 2023 11:40:35 -0500 (EST)

branch: master
commit c91c05940209ec286c83b00007e295d09183c6e7
Author: Patrice Dumas <pertusus@free.fr>
AuthorDate: Thu Dec 28 16:23:34 2023 +0100

    * tp/Texinfo/XS/convert/convert_html.c
    (find_element_target_number_linear, compare_element_target)
    (find_element_target_search, find_element_target)
    (find_element_special_target, sort_cmd_targets)
    (html_prepare_conversion_units_targets, reset_html_targets)
    (html_reset_converter, html_free_converter): sort target elements and
    use bsearch in find_element_target through find_element_target_search.
    Rename find_element_target_number as
    find_element_target_number_linear.
    
    * tp/Texinfo/XS/convert/convert_html.c (reset_html_targets)
    (html_reset_converter), tp/Texinfo/XS/main/converter_types.h
    (CONVERTER): add html_target_cmds, a list of cmd identifiers with
    associated targets to free only those when resetting parser.  Free
    targets lists when resetting parser, not when freeing it.
---
 ChangeLog                            |  18 ++++++
 tp/Texinfo/XS/convert/convert_html.c | 108 ++++++++++++++++++++++++++++++-----
 tp/Texinfo/XS/main/converter_types.h |   1 +
 3 files changed, 113 insertions(+), 14 deletions(-)

diff --git a/ChangeLog b/ChangeLog
index ff20c20855..ae9453927a 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,21 @@
+2023-12-27  Patrice Dumas  <pertusus@free.fr>
+
+       * tp/Texinfo/XS/convert/convert_html.c
+       (find_element_target_number_linear, compare_element_target)
+       (find_element_target_search, find_element_target)
+       (find_element_special_target, sort_cmd_targets)
+       (html_prepare_conversion_units_targets, reset_html_targets)
+       (html_reset_converter, html_free_converter): sort target elements and
+       use bsearch in find_element_target through find_element_target_search.
+       Rename find_element_target_number as
+       find_element_target_number_linear.
+
+       * tp/Texinfo/XS/convert/convert_html.c (reset_html_targets)
+       (html_reset_converter), tp/Texinfo/XS/main/converter_types.h
+       (CONVERTER): add html_target_cmds, a list of cmd identifiers with
+       associated targets to free only those when resetting parser.  Free
+       targets lists when resetting parser, not when freeing it.
+
 2023-12-27  Gavin Smith <gavinsmith0123@gmail.com>
 
        * contrib/txipsfonts-gildea.diff, contrib/txipsfonts-bronger.tex:
diff --git a/tp/Texinfo/XS/convert/convert_html.c 
b/tp/Texinfo/XS/convert/convert_html.c
index b4452eff51..1274e1cbc3 100644
--- a/tp/Texinfo/XS/convert/convert_html.c
+++ b/tp/Texinfo/XS/convert/convert_html.c
@@ -424,8 +424,8 @@ html_get_tree_root_element (CONVERTER *self, const ELEMENT 
*command,
 /* this number should be safe to use even after targets list has been
    reallocated */
 size_t
-find_element_target_number (const HTML_TARGET_LIST *targets,
-                            const ELEMENT *element)
+find_element_target_number_linear (const HTML_TARGET_LIST *targets,
+                                   const ELEMENT *element)
 {
   size_t i;
 
@@ -441,28 +441,66 @@ find_element_target_number (const HTML_TARGET_LIST 
*targets,
   return 0;
 }
 
+static int
+compare_element_target (const void *a, const void *b)
+{
+  const HTML_TARGET *ete_a = (const HTML_TARGET *) a;
+  const HTML_TARGET *ete_b = (const HTML_TARGET *) b;
+  /* we cast to uintptr_t because comparison of pointers from different
+     objects is undefined behaviour in C.  In practice it is probably
+     not an issue */
+  uintptr_t a_element_addr = (uintptr_t)ete_a->element;
+  uintptr_t b_element_addr = (uintptr_t)ete_b->element;
+
+  return (a_element_addr > b_element_addr) - (a_element_addr < b_element_addr);
+}
+
+HTML_TARGET *
+find_element_target_search (const HTML_TARGET_LIST *targets,
+                                          const ELEMENT *element)
+{
+  HTML_TARGET *result;
+  static HTML_TARGET searched_element;
+
+  if (targets->number == 0)
+    return 0;
+
+  searched_element.element = element;
+  result = (HTML_TARGET *) bsearch (&searched_element,
+               targets->list, targets->number, sizeof(HTML_TARGET),
+               compare_element_target);
+  return result;
+}
+
 /* becomes invalid if the targets list is reallocated */
 HTML_TARGET *
 find_element_target (const HTML_TARGET_LIST *targets, const ELEMENT *element)
 {
   enum command_id cmd = element_builtin_cmd (element);
-  size_t i = find_element_target_number (&targets[cmd], element);
+  return find_element_target_search (&targets[cmd], element);
+  /* with a linear search:
+  size_t i = find_element_target_number_linear (&targets[cmd], element);
 
   if (i > 0)
     return &targets[cmd].list[i - 1];
 
   return 0;
+  */
 }
 
 HTML_TARGET *
-find_element_special_target (const HTML_TARGET_LIST *targets, const ELEMENT 
*element)
+find_element_special_target (const HTML_TARGET_LIST *targets,
+                             const ELEMENT *element)
 {
-  size_t i = find_element_target_number (targets, element);
+  return find_element_target_search (targets, element);
+  /* with a linear search:
+  size_t i = find_element_target_number_linear (targets, element);
 
   if (i > 0)
     return &targets->list[i - 1];
 
   return 0;
+  */
 }
 
 char *
@@ -4691,6 +4729,41 @@ set_heading_commands_targets (CONVERTER *self)
     }
 }
 
+/* It may not be efficient to sort and find back with bsearch
+   if there is a small number of elements.  However, some target
+   elements should already be ordered when they are accessed in
+   their order of appearance in the document.
+   TODO check in which case it is not true and use another data
+   source if possible  */
+void
+sort_cmd_targets (CONVERTER *self)
+{
+  enum command_id cmd;
+  int type;
+
+  for (cmd = 0; cmd < BUILTIN_CMD_NUMBER; cmd++)
+    {
+      if (self->html_targets[cmd].number > 0)
+        {
+          HTML_TARGET_LIST *element_targets = &self->html_targets[cmd];
+          qsort (element_targets->list,
+                 element_targets->number,
+                 sizeof (HTML_TARGET), compare_element_target);
+          push_command (&self->html_target_cmds, cmd);
+        }
+    }
+  for (type = 0; type < ST_footnote_location+1; type++)
+    {
+     if (self->html_special_targets[type].number > 0)
+        {
+          HTML_TARGET_LIST *element_targets = 
&self->html_special_targets[type];
+          qsort (element_targets->list,
+                 element_targets->number,
+                 sizeof (HTML_TARGET), compare_element_target);
+        }
+    }
+}
+
 /* for conversion units except for associated special units that require
    files for document units to be set */
 void
@@ -4716,6 +4789,8 @@ html_prepare_conversion_units_targets (CONVERTER *self,
   prepare_footnotes_targets (self);
 
   set_heading_commands_targets (self);
+
+  sort_cmd_targets (self);
 }
 
 /* Associate output units to the global targets, First, Last, Top, Index.
@@ -11172,9 +11247,14 @@ reset_html_targets_list (CONVERTER *self, 
HTML_TARGET_LIST *targets)
 void
 reset_html_targets (CONVERTER *self, HTML_TARGET_LIST *targets)
 {
-  enum command_id cmd;
-  for (cmd = 0; cmd < BUILTIN_CMD_NUMBER; cmd++)
-    reset_html_targets_list (self, &targets[cmd]);
+  int i;
+  for (i = 0; i < self->html_target_cmds.top; i++)
+    {
+      enum command_id cmd = self->html_target_cmds.stack[i];
+      reset_html_targets_list (self, &targets[cmd]);
+      free (targets[cmd].list);
+      targets[cmd].space = 0;
+    }
 }
 
 /* called very early in conversion functions, before updating
@@ -11335,7 +11415,10 @@ html_reset_converter (CONVERTER *self)
   for (i = 0; i < ST_footnote_location+1; i++)
     {
       reset_html_targets_list (self, &self->html_special_targets[i]);
+      free (self->html_special_targets[i].list);
+      self->html_special_targets[i].space = 0;
     }
+  self->html_target_cmds.top = 0;
 
   free (self->shared_conversion_state.footnote_id_numbers);
 
@@ -11514,13 +11597,10 @@ html_free_converter (CONVERTER *self)
   free (self->special_unit_body_formatting);
 
   free (self->global_units_directions);
-  for (i = 0; i < BUILTIN_CMD_NUMBER; i++)
-    free (self->html_targets[i].list);
+
+  free (self->html_target_cmds.stack);
+
   free_strings_list (&self->seen_ids);
-  for (i = 0; i < ST_footnote_location+1; i++)
-    {
-      free (self->html_special_targets[i].list);
-    }
 
   free_strings_list (&self->check_htmlxref_already_warned);
 
diff --git a/tp/Texinfo/XS/main/converter_types.h 
b/tp/Texinfo/XS/main/converter_types.h
index 0867ca9db7..a8ee33e43e 100644
--- a/tp/Texinfo/XS/main/converter_types.h
+++ b/tp/Texinfo/XS/main/converter_types.h
@@ -740,6 +740,7 @@ typedef struct CONVERTER {
     /* TODO list with commands possibly associated to targets only? */
     HTML_TARGET_LIST html_targets[BUILTIN_CMD_NUMBER];
     HTML_TARGET_LIST html_special_targets[ST_footnote_location+1];
+    COMMAND_STACK html_target_cmds; /* list of cmd with targets */
     JSLICENSE_CATEGORY_LIST jslicenses;
     /* associate cmd and index in special_unit_varieties STRING_LIST */
     /* number in sync with command_special_unit_variety, +1 for trailing 0 */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]