xF: maintain an index of buffer by name
Alpine 3.24 Success
Arch Linux AUR Success
OpenBSD 7.8 Success

Imperceptibly improves performance, shortens source code.
This commit is contained in:
2026-08-08 15:29:52 +02:00
parent dbb47ec2ee
commit f1170bc161
+16 -25
View File
@@ -475,6 +475,7 @@ static struct
struct buffer *buffers; ///< Ordered list of all buffers
struct buffer *buffers_tail; ///< The tail of all buffers
struct str_map buffers_by_name; ///< Buffers indexed by name
struct buffer *buffer_current; ///< The current buffer
struct buffer *buffer_last; ///< Last used buffer
@@ -1166,6 +1167,7 @@ app_reset_relay_state (void)
LIST_FOR_EACH (struct buffer, iter, g.buffers)
buffer_destroy (iter);
g.buffers = g.buffers_tail = NULL;
str_map_clear (&g.buffers_by_name);
str_map_free (&g.servers);
g.servers = str_map_make ((str_map_free_fn) server_destroy);
@@ -1245,15 +1247,6 @@ xui_request_attention (void)
#endif
}
static struct buffer *
buffer_find (const char *name)
{
LIST_FOR_EACH (struct buffer, buffer, g.buffers)
if (!strcmp (buffer->buffer_name, name))
return buffer;
return NULL;
}
static void
buffer_line_convert_items (struct buffer_line *line,
const union relay_item_data *items, uint32_t len)
@@ -1462,7 +1455,7 @@ relay_process_buffer_event (struct relay_event_message *m)
const char *buffer_name = relay_message_buffer_name (m);
hard_assert (buffer_name);
struct buffer *b = buffer_find (buffer_name);
struct buffer *b = str_map_find (&g.buffers_by_name, buffer_name);
if (!b)
{
if (m->data.event != RELAY_EVENT_BUFFER_UPDATE)
@@ -1473,6 +1466,7 @@ relay_process_buffer_event (struct relay_event_message *m)
b = buffer_new (buffer_name);
LIST_APPEND_WITH_TAIL (g.buffers, g.buffers_tail, b);
str_map_set (&g.buffers_by_name, b->buffer_name, b);
}
switch (m->data.event)
@@ -1490,11 +1484,13 @@ relay_process_buffer_event (struct relay_event_message *m)
b->highlighted = m->data.buffer_stats.highlighted;
break;
case RELAY_EVENT_BUFFER_RENAME:
free (b->buffer_name);
b->buffer_name = xstrdup (m->data.buffer_rename.new.str);
str_map_set (&g.buffers_by_name, b->buffer_name, NULL);
cstr_set (&b->buffer_name, xstrdup (m->data.buffer_rename.new.str));
str_map_set (&g.buffers_by_name, b->buffer_name, b);
break;
case RELAY_EVENT_BUFFER_REMOVE:
LIST_UNLINK_WITH_TAIL (g.buffers, g.buffers_tail, b);
str_map_set (&g.buffers_by_name, b->buffer_name, NULL);
if (g.buffer_current == b)
g.buffer_current = NULL;
if (g.buffer_last == b)
@@ -1872,17 +1868,6 @@ app_viewport_height (void)
return MAX (0, g_xui.height - 3 * g_xui.vunit);
}
static int
app_buffer_list_content_height (void)
{
size_t count = 0;
LIST_FOR_EACH (struct buffer, buffer, g.buffers)
count++;
uint64_t height = count * (uint64_t) g_xui.vunit;
return MIN ((uint64_t) INT_MAX, height);
}
static int *
app_content_scroll_offset (void)
{
@@ -1906,8 +1891,11 @@ static struct app_scroll_view
app_scroll_view (enum app_widget_id id)
{
if (id == WIDGET_BUFFER_LIST_SCROLLBAR)
{
size_t height = g.buffers_by_name.len * (size_t) g_xui.vunit;
return (struct app_scroll_view) { &g.buffer_list_offset,
app_buffer_list_content_height (), false };
MIN ((size_t) INT_MAX, height), false };
}
hard_assert (id == WIDGET_TRANSCRIPT_SCROLLBAR);
return (struct app_scroll_view) { app_content_scroll_offset (),
@@ -3581,7 +3569,8 @@ app_external_editor_process_file (void)
while (input.len && strchr ("\r\n", input.str[input.len - 1]))
input.str[--input.len] = 0;
struct buffer *buffer = buffer_find (g.editor_running_for);
struct buffer *buffer =
str_map_find (&g.buffers_by_name, g.editor_running_for);
if (buffer == g.buffer_current)
app_editor_set (input.str);
else if (buffer)
@@ -4338,6 +4327,7 @@ app_init_context (void)
g.relay.read_buffer = str_make ();
g.relay.write_buffer = str_make ();
g.buffers_by_name = str_map_make (NULL);
g.servers = str_map_make ((str_map_free_fn) server_destroy);
}
@@ -4348,6 +4338,7 @@ app_free_context (void)
LIST_FOR_EACH (struct buffer_line, iter, g.local_lines)
buffer_line_destroy (iter);
g.local_lines = g.local_lines_tail = NULL;
str_map_free (&g.buffers_by_name);
log_view_free (&g.log);
str_map_free (&g.servers);