vim-patch:8.1.0644: finding next sign ID is inefficient

Problem:    Finding next sign ID is inefficient.
Solution:   Add next_sign_id. (Yegappan Lakshmanan, closes vim/vim#3717)
6436cd83f9
This commit is contained in:
Andrej Zieger
2019-05-15 22:02:10 +02:00
parent 4f844c587c
commit 3ee55edd2e
8 changed files with 78 additions and 33 deletions

View File

@@ -5257,6 +5257,16 @@ bool find_win_for_buf(buf_T *buf, win_T **wp, tabpage_T **tp)
}
static hashtab_T sg_table; // sign group (signgroup_T) hashtable
static int next_sign_id = 1; // next sign id in the global group
/*
* Initialize data needed for managing signs
*/
void
init_signs(void)
{
hash_init(&sg_table); // sign group hash table
}
/*
* A new sign in group 'groupname' is added. If the group is not present,
@@ -5264,16 +5274,10 @@ static hashtab_T sg_table; // sign group (signgroup_T) hashtable
*/
static signgroup_T * sign_group_ref(char_u *groupname)
{
static int initialized = FALSE;
hash_T hash;
hashitem_T *hi;
signgroup_T *group;
if (!initialized) {
initialized = TRUE;
hash_init(&sg_table);
}
hash = hash_hash(groupname);
hi = hash_lookup(&sg_table, S_LEN(groupname), hash);
if (HASHITEM_EMPTY(hi))
@@ -5285,6 +5289,7 @@ static signgroup_T * sign_group_ref(char_u *groupname)
return NULL;
STRCPY(group->sg_name, groupname);
group->refcount = 1;
group->next_sign_id = 1;
hash_add_item(&sg_table, hi, group->sg_name, hash);
}
else
@@ -5320,6 +5325,49 @@ static void sign_group_unref(char_u *groupname)
}
}
/*
* Get the next free sign identifier in the specified group
*/
int
sign_group_get_next_signid(buf_T *buf, char_u *groupname)
{
int id = 1;
signgroup_T *group = NULL;
signlist_T *sign;
hashitem_T *hi;
int found = FALSE;
if (groupname != NULL)
{
hi = hash_find(&sg_table, groupname);
if (HASHITEM_EMPTY(hi))
return id;
group = HI2SG(hi);
}
// Search for the next usuable sign identifier
while (!found)
{
if (group == NULL)
id = next_sign_id++; // global group
else
id = group->next_sign_id++;
// Check whether this sign is already placed in the buffer
found = TRUE;
FOR_ALL_SIGNS_IN_BUF(buf, sign)
{
if (id == sign->id && sign_in_group(sign, groupname))
{
found = FALSE; // sign identifier is in use
break;
}
}
}
return id;
}
/*
* Insert a new sign into the signlist for buffer 'buf' between the 'prev' and
* 'next' signs.
@@ -5542,7 +5590,7 @@ void buf_addsign(
signlist_T *prev; // the previous sign
prev = NULL;
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (lnum == sign->lnum && id == sign->id &&
sign_in_group(sign, groupname)) {
// Update an existing sign
@@ -5583,7 +5631,7 @@ linenr_T buf_change_sign_type(
{
signlist_T *sign; // a sign in the signlist
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->id == markId && sign_in_group(sign, group)) {
sign->typenr = typenr;
return sign->lnum;
@@ -5611,7 +5659,7 @@ int buf_getsigntype(buf_T *buf, linenr_T lnum, SignType type,
signlist_T *matches[9];
int nr_matches = 0;
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->lnum == lnum
&& (type == SIGN_ANY
|| (type == SIGN_TEXT
@@ -5711,7 +5759,7 @@ int buf_findsign(
{
signlist_T *sign; // a sign in the signlist
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->id == id && sign_in_group(sign, group)){
return (int)sign->lnum;
}
@@ -5731,7 +5779,7 @@ static signlist_T * buf_getsign_at_line(
{
signlist_T *sign; // a sign in the signlist
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->lnum == lnum) {
return sign;
}
@@ -5751,7 +5799,7 @@ signlist_T *buf_getsign_with_id(
{
signlist_T *sign; // a sign in the signlist
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (sign->id == id && sign_in_group(sign, group)) {
return sign;
}
@@ -5849,7 +5897,7 @@ void sign_list_placed(buf_T *rbuf, char_u *sign_group)
MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D));
msg_putchar('\n');
}
FOR_ALL_SIGNS_IN_BUF(buf) {
FOR_ALL_SIGNS_IN_BUF(buf, sign) {
if (got_int) {
break;
}
@@ -5887,7 +5935,7 @@ void sign_mark_adjust(linenr_T line1, linenr_T line2, long amount, long amount_a
curbuf->b_signcols_max = -1;
lastp = &curbuf->b_signlist;
FOR_ALL_SIGNS_IN_BUF(curbuf) {
FOR_ALL_SIGNS_IN_BUF(curbuf, sign) {
next = sign->next;
if (sign->lnum >= line1 && sign->lnum <= line2) {
if (amount == MAXLNUM) {