xF: maintain an index of buffer by name
Imperceptibly improves performance, shortens source code.
This commit is contained in:
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user