comparison src/buffer.c @ 15271:a6319aca721b v8.1.0644

patch 8.1.0644: finding next sign ID is inefficient commit https://github.com/vim/vim/commit/6436cd83f90a0efc326798792e49e8ff96a43dce Author: Bram Moolenaar <Bram@vim.org> Date: Thu Dec 27 00:28:33 2018 +0100 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 https://github.com/vim/vim/issues/3717)
author Bram Moolenaar <Bram@vim.org>
date Thu, 27 Dec 2018 00:30:06 +0100
parents 336728a577f5
children 890203d87ee5
comparison
equal deleted inserted replaced
15270:18c956b49ee5 15271:a6319aca721b
5864 } 5864 }
5865 #endif 5865 #endif
5866 5866
5867 #if defined(FEAT_SIGNS) || defined(PROTO) 5867 #if defined(FEAT_SIGNS) || defined(PROTO)
5868 static hashtab_T sg_table; // sign group (signgroup_T) hashtable 5868 static hashtab_T sg_table; // sign group (signgroup_T) hashtable
5869 static int next_sign_id = 1; // next sign id in the global group
5870
5871 /*
5872 * Initialize data needed for managing signs
5873 */
5874 void
5875 init_signs(void)
5876 {
5877 hash_init(&sg_table); // sign group hash table
5878 }
5869 5879
5870 /* 5880 /*
5871 * A new sign in group 'groupname' is added. If the group is not present, 5881 * A new sign in group 'groupname' is added. If the group is not present,
5872 * create it. Otherwise reference the group. 5882 * create it. Otherwise reference the group.
5873 */ 5883 */
5874 static signgroup_T * 5884 static signgroup_T *
5875 sign_group_ref(char_u *groupname) 5885 sign_group_ref(char_u *groupname)
5876 { 5886 {
5877 static int initialized = FALSE;
5878 hash_T hash; 5887 hash_T hash;
5879 hashitem_T *hi; 5888 hashitem_T *hi;
5880 signgroup_T *group; 5889 signgroup_T *group;
5881
5882 if (!initialized)
5883 {
5884 initialized = TRUE;
5885 hash_init(&sg_table);
5886 }
5887 5890
5888 hash = hash_hash(groupname); 5891 hash = hash_hash(groupname);
5889 hi = hash_lookup(&sg_table, groupname, hash); 5892 hi = hash_lookup(&sg_table, groupname, hash);
5890 if (HASHITEM_EMPTY(hi)) 5893 if (HASHITEM_EMPTY(hi))
5891 { 5894 {
5894 (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); 5897 (unsigned)(sizeof(signgroup_T) + STRLEN(groupname)));
5895 if (group == NULL) 5898 if (group == NULL)
5896 return NULL; 5899 return NULL;
5897 STRCPY(group->sg_name, groupname); 5900 STRCPY(group->sg_name, groupname);
5898 group->refcount = 1; 5901 group->refcount = 1;
5902 group->next_sign_id = 1;
5899 hash_add_item(&sg_table, hi, group->sg_name, hash); 5903 hash_add_item(&sg_table, hi, group->sg_name, hash);
5900 } 5904 }
5901 else 5905 else
5902 { 5906 {
5903 // existing group 5907 // existing group
5928 // All the signs in this group are removed 5932 // All the signs in this group are removed
5929 hash_remove(&sg_table, hi); 5933 hash_remove(&sg_table, hi);
5930 vim_free(group); 5934 vim_free(group);
5931 } 5935 }
5932 } 5936 }
5937 }
5938
5939 /*
5940 * Get the next free sign identifier in the specified group
5941 */
5942 int
5943 sign_group_get_next_signid(buf_T *buf, char_u *groupname)
5944 {
5945 int id = 1;
5946 signgroup_T *group = NULL;
5947 signlist_T *sign;
5948 hashitem_T *hi;
5949 int found = FALSE;
5950
5951 if (groupname != NULL)
5952 {
5953 hi = hash_find(&sg_table, groupname);
5954 if (HASHITEM_EMPTY(hi))
5955 return id;
5956 group = HI2SG(hi);
5957 }
5958
5959 // Search for the next usuable sign identifier
5960 while (!found)
5961 {
5962 if (group == NULL)
5963 id = next_sign_id++; // global group
5964 else
5965 id = group->next_sign_id++;
5966
5967 // Check whether this sign is already placed in the buffer
5968 found = TRUE;
5969 FOR_ALL_SIGNS_IN_BUF(buf, sign)
5970 {
5971 if (id == sign->id && sign_in_group(sign, groupname))
5972 {
5973 found = FALSE; // sign identifier is in use
5974 break;
5975 }
5976 }
5977 }
5978
5979 return id;
5933 } 5980 }
5934 5981
5935 /* 5982 /*
5936 * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and 5983 * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and
5937 * 'next' signs. 5984 * 'next' signs.
6070 { 6117 {
6071 signlist_T *sign; // a sign in the signlist 6118 signlist_T *sign; // a sign in the signlist
6072 signlist_T *prev; // the previous sign 6119 signlist_T *prev; // the previous sign
6073 6120
6074 prev = NULL; 6121 prev = NULL;
6075 FOR_ALL_SIGNS_IN_BUF(buf) 6122 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6076 { 6123 {
6077 if (lnum == sign->lnum && id == sign->id && 6124 if (lnum == sign->lnum && id == sign->id &&
6078 sign_in_group(sign, groupname)) 6125 sign_in_group(sign, groupname))
6079 { 6126 {
6080 // Update an existing sign 6127 // Update an existing sign
6105 char_u *group, // sign group 6152 char_u *group, // sign group
6106 int typenr) // typenr of sign we are adding 6153 int typenr) // typenr of sign we are adding
6107 { 6154 {
6108 signlist_T *sign; // a sign in the signlist 6155 signlist_T *sign; // a sign in the signlist
6109 6156
6110 FOR_ALL_SIGNS_IN_BUF(buf) 6157 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6111 { 6158 {
6112 if (sign->id == markId && sign_in_group(sign, group)) 6159 if (sign->id == markId && sign_in_group(sign, group))
6113 { 6160 {
6114 sign->typenr = typenr; 6161 sign->typenr = typenr;
6115 return sign->lnum; 6162 return sign->lnum;
6130 linenr_T lnum, 6177 linenr_T lnum,
6131 int type) /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */ 6178 int type) /* SIGN_ICON, SIGN_TEXT, SIGN_ANY, SIGN_LINEHL */
6132 { 6179 {
6133 signlist_T *sign; /* a sign in a b_signlist */ 6180 signlist_T *sign; /* a sign in a b_signlist */
6134 6181
6135 FOR_ALL_SIGNS_IN_BUF(buf) 6182 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6136 if (sign->lnum == lnum 6183 if (sign->lnum == lnum
6137 && (type == SIGN_ANY 6184 && (type == SIGN_ANY
6138 # ifdef FEAT_SIGN_ICONS 6185 # ifdef FEAT_SIGN_ICONS
6139 || (type == SIGN_ICON 6186 || (type == SIGN_ICON
6140 && sign_get_image(sign->typenr) != NULL) 6187 && sign_get_image(sign->typenr) != NULL)
6214 int id, // sign ID 6261 int id, // sign ID
6215 char_u *group) // sign group 6262 char_u *group) // sign group
6216 { 6263 {
6217 signlist_T *sign; // a sign in the signlist 6264 signlist_T *sign; // a sign in the signlist
6218 6265
6219 FOR_ALL_SIGNS_IN_BUF(buf) 6266 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6220 if (sign->id == id && sign_in_group(sign, group)) 6267 if (sign->id == id && sign_in_group(sign, group))
6221 return sign->lnum; 6268 return sign->lnum;
6222 6269
6223 return 0; 6270 return 0;
6224 } 6271 }
6232 buf_T *buf, // buffer whose sign we are searching for 6279 buf_T *buf, // buffer whose sign we are searching for
6233 linenr_T lnum) // line number of sign 6280 linenr_T lnum) // line number of sign
6234 { 6281 {
6235 signlist_T *sign; // a sign in the signlist 6282 signlist_T *sign; // a sign in the signlist
6236 6283
6237 FOR_ALL_SIGNS_IN_BUF(buf) 6284 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6238 if (sign->lnum == lnum) 6285 if (sign->lnum == lnum)
6239 return sign; 6286 return sign;
6240 6287
6241 return NULL; 6288 return NULL;
6242 } 6289 }
6250 int id, // sign identifier 6297 int id, // sign identifier
6251 char_u *group) // sign group 6298 char_u *group) // sign group
6252 { 6299 {
6253 signlist_T *sign; // a sign in the signlist 6300 signlist_T *sign; // a sign in the signlist
6254 6301
6255 FOR_ALL_SIGNS_IN_BUF(buf) 6302 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6256 if (sign->id == id && sign_in_group(sign, group)) 6303 if (sign->id == id && sign_in_group(sign, group))
6257 return sign; 6304 return sign;
6258 6305
6259 return NULL; 6306 return NULL;
6260 } 6307 }
6286 linenr_T lnum, /* line number of sign */ 6333 linenr_T lnum, /* line number of sign */
6287 int typenr) /* sign type number */ 6334 int typenr) /* sign type number */
6288 { 6335 {
6289 signlist_T *sign; /* a sign in the signlist */ 6336 signlist_T *sign; /* a sign in the signlist */
6290 6337
6291 FOR_ALL_SIGNS_IN_BUF(buf) 6338 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6292 if (sign->lnum == lnum && sign->typenr == typenr) 6339 if (sign->lnum == lnum && sign->typenr == typenr)
6293 return sign->id; 6340 return sign->id;
6294 6341
6295 return 0; 6342 return 0;
6296 } 6343 }
6304 buf_signcount(buf_T *buf, linenr_T lnum) 6351 buf_signcount(buf_T *buf, linenr_T lnum)
6305 { 6352 {
6306 signlist_T *sign; // a sign in the signlist 6353 signlist_T *sign; // a sign in the signlist
6307 int count = 0; 6354 int count = 0;
6308 6355
6309 FOR_ALL_SIGNS_IN_BUF(buf) 6356 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6310 if (sign->lnum == lnum) 6357 if (sign->lnum == lnum)
6311 if (sign_get_image(sign->typenr) != NULL) 6358 if (sign_get_image(sign->typenr) != NULL)
6312 count++; 6359 count++;
6313 6360
6314 return count; 6361 return count;
6389 { 6436 {
6390 vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname); 6437 vim_snprintf(lbuf, BUFSIZ, _("Signs for %s:"), buf->b_fname);
6391 MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); 6438 MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D));
6392 msg_putchar('\n'); 6439 msg_putchar('\n');
6393 } 6440 }
6394 FOR_ALL_SIGNS_IN_BUF(buf) 6441 FOR_ALL_SIGNS_IN_BUF(buf, sign)
6395 { 6442 {
6396 if (got_int) 6443 if (got_int)
6397 break; 6444 break;
6398 if (!sign_in_group(sign, sign_group)) 6445 if (!sign_in_group(sign, sign_group))
6399 continue; 6446 continue;
6425 long amount, 6472 long amount,
6426 long amount_after) 6473 long amount_after)
6427 { 6474 {
6428 signlist_T *sign; /* a sign in a b_signlist */ 6475 signlist_T *sign; /* a sign in a b_signlist */
6429 6476
6430 FOR_ALL_SIGNS_IN_BUF(curbuf) 6477 FOR_ALL_SIGNS_IN_BUF(curbuf, sign)
6431 { 6478 {
6432 if (sign->lnum >= line1 && sign->lnum <= line2) 6479 if (sign->lnum >= line1 && sign->lnum <= line2)
6433 { 6480 {
6434 if (amount == MAXLNUM) 6481 if (amount == MAXLNUM)
6435 sign->lnum = line1; 6482 sign->lnum = line1;