Mercurial > vim
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; |