0
0
mirror of https://github.com/vim/vim.git synced 2025-09-24 03:44:06 -04:00

patch 7.4.2036

Problem:    Looking up a buffer by number is slow if there are many.
Solution:   Use a hashtab.
This commit is contained in:
Bram Moolenaar
2016-07-14 22:09:39 +02:00
parent da4127794a
commit 480778b805
3 changed files with 45 additions and 8 deletions

View File

@@ -349,6 +349,28 @@ buf_valid(buf_T *buf)
return FALSE; return FALSE;
} }
/*
* A hash table used to quickly lookup a buffer by its number.
*/
static hashtab_T buf_hashtab;
static void
buf_hashtab_add(buf_T *buf)
{
sprintf((char *)buf->b_key, "%x", buf->b_fnum);
if (hash_add(&buf_hashtab, buf->b_key) == FAIL)
EMSG(_("E931: Buffer cannot be registered"));
}
static void
buf_hashtab_remove(buf_T *buf)
{
hashitem_T *hi = hash_find(&buf_hashtab, buf->b_key);
if (!HASHITEM_EMPTY(hi))
hash_remove(&buf_hashtab, hi);
}
/* /*
* Close the link to a buffer. * Close the link to a buffer.
* "action" is used when there is no longer a window for the buffer. * "action" is used when there is no longer a window for the buffer.
@@ -723,6 +745,9 @@ free_buffer(buf_T *buf)
#endif #endif
#ifdef FEAT_AUTOCMD #ifdef FEAT_AUTOCMD
aubuflocal_remove(buf); aubuflocal_remove(buf);
buf_hashtab_remove(buf);
if (autocmd_busy) if (autocmd_busy)
{ {
/* Do not free the buffer structure while autocommands are executing, /* Do not free the buffer structure while autocommands are executing,
@@ -1703,6 +1728,8 @@ do_autochdir(void)
* functions for dealing with the buffer list * functions for dealing with the buffer list
*/ */
static int top_file_num = 1; /* highest file number */
/* /*
* Add a file name to the buffer list. Return a pointer to the buffer. * Add a file name to the buffer list. Return a pointer to the buffer.
* If the same file name already exists return a pointer to that buffer. * If the same file name already exists return a pointer to that buffer.
@@ -1715,8 +1742,6 @@ do_autochdir(void)
* if the buffer already exists. * if the buffer already exists.
* This is the ONLY way to create a new buffer. * This is the ONLY way to create a new buffer.
*/ */
static int top_file_num = 1; /* highest file number */
buf_T * buf_T *
buflist_new( buflist_new(
char_u *ffname, /* full path of fname or relative */ char_u *ffname, /* full path of fname or relative */
@@ -1729,6 +1754,9 @@ buflist_new(
stat_T st; stat_T st;
#endif #endif
if (top_file_num == 1)
hash_init(&buf_hashtab);
fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */ fname_expand(curbuf, &ffname, &sfname); /* will allocate ffname */
/* /*
@@ -1907,6 +1935,7 @@ buflist_new(
} }
top_file_num = 1; top_file_num = 1;
} }
buf_hashtab_add(buf);
/* /*
* Always copy the options from the current buffer. * Always copy the options from the current buffer.
@@ -2579,19 +2608,22 @@ fname_match(
#endif #endif
/* /*
* find file in buffer list by number * Find a file in the buffer list by buffer number.
*/ */
buf_T * buf_T *
buflist_findnr(int nr) buflist_findnr(int nr)
{ {
buf_T *buf; char_u key[VIM_SIZEOF_INT * 2 + 1];
hashitem_T *hi;
if (nr == 0) if (nr == 0)
nr = curwin->w_alt_fnum; nr = curwin->w_alt_fnum;
/* Assume newer buffers are used more often, start from the end. */ sprintf((char *)key, "%x", nr);
for (buf = lastbuf; buf != NULL; buf = buf->b_prev) hi = hash_find(&buf_hashtab, key);
if (buf->b_fnum == nr)
return buf; if (!HASHITEM_EMPTY(hi))
return (buf_T *)(hi->hi_key
- ((unsigned)(curbuf->b_key - (char_u *)curbuf)));
return NULL; return NULL;
} }

View File

@@ -1753,6 +1753,9 @@ struct file_buffer
unsigned int b_fab_mrs; /* Max record size */ unsigned int b_fab_mrs; /* Max record size */
#endif #endif
int b_fnum; /* buffer number for this file. */ int b_fnum; /* buffer number for this file. */
char_u b_key[VIM_SIZEOF_INT * 2 + 1];
/* key used for buf_hashtab, holds b_fnum as
hex string */
int b_changed; /* 'modified': Set to TRUE if something in the int b_changed; /* 'modified': Set to TRUE if something in the
file has been changed and not written out. */ file has been changed and not written out. */

View File

@@ -758,6 +758,8 @@ static char *(features[]) =
static int included_patches[] = static int included_patches[] =
{ /* Add new patch number below this line */ { /* Add new patch number below this line */
/**/
2036,
/**/ /**/
2035, 2035,
/**/ /**/