Mercurial > vim
comparison src/buffer.c @ 15247:336728a577f5 v8.1.0632
patch 8.1.0632: using sign group names is inefficient
commit https://github.com/vim/vim/commit/7a2d9892b7158edf8dc48e9bcaaae70a40787b37
Author: Bram Moolenaar <Bram@vim.org>
Date: Mon Dec 24 20:23:49 2018 +0100
patch 8.1.0632: using sign group names is inefficient
Problem: Using sign group names is inefficient.
Solution: Store group names in a hash table and use a reference to them.
Also remove unnecessary use of ":exe" from the tests. (Yegappan
Lakshmanan, closes #3715)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Mon, 24 Dec 2018 20:30:04 +0100 |
parents | 3a99b2e6d136 |
children | a6319aca721b |
comparison
equal
deleted
inserted
replaced
15246:a6fc4675cf61 | 15247:336728a577f5 |
---|---|
5863 return OK; | 5863 return OK; |
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 | |
5869 | |
5870 /* | |
5871 * A new sign in group 'groupname' is added. If the group is not present, | |
5872 * create it. Otherwise reference the group. | |
5873 */ | |
5874 static signgroup_T * | |
5875 sign_group_ref(char_u *groupname) | |
5876 { | |
5877 static int initialized = FALSE; | |
5878 hash_T hash; | |
5879 hashitem_T *hi; | |
5880 signgroup_T *group; | |
5881 | |
5882 if (!initialized) | |
5883 { | |
5884 initialized = TRUE; | |
5885 hash_init(&sg_table); | |
5886 } | |
5887 | |
5888 hash = hash_hash(groupname); | |
5889 hi = hash_lookup(&sg_table, groupname, hash); | |
5890 if (HASHITEM_EMPTY(hi)) | |
5891 { | |
5892 // new group | |
5893 group = (signgroup_T *)alloc( | |
5894 (unsigned)(sizeof(signgroup_T) + STRLEN(groupname))); | |
5895 if (group == NULL) | |
5896 return NULL; | |
5897 STRCPY(group->sg_name, groupname); | |
5898 group->refcount = 1; | |
5899 hash_add_item(&sg_table, hi, group->sg_name, hash); | |
5900 } | |
5901 else | |
5902 { | |
5903 // existing group | |
5904 group = HI2SG(hi); | |
5905 group->refcount++; | |
5906 } | |
5907 | |
5908 return group; | |
5909 } | |
5910 | |
5911 /* | |
5912 * A sign in group 'groupname' is removed. If all the signs in this group are | |
5913 * removed, then remove the group. | |
5914 */ | |
5915 static void | |
5916 sign_group_unref(char_u *groupname) | |
5917 { | |
5918 hashitem_T *hi; | |
5919 signgroup_T *group; | |
5920 | |
5921 hi = hash_find(&sg_table, groupname); | |
5922 if (!HASHITEM_EMPTY(hi)) | |
5923 { | |
5924 group = HI2SG(hi); | |
5925 group->refcount--; | |
5926 if (group->refcount == 0) | |
5927 { | |
5928 // All the signs in this group are removed | |
5929 hash_remove(&sg_table, hi); | |
5930 vim_free(group); | |
5931 } | |
5932 } | |
5933 } | |
5934 | |
5868 /* | 5935 /* |
5869 * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and | 5936 * Insert a new sign into the signlist for buffer 'buf' between the 'prev' and |
5870 * 'next' signs. | 5937 * 'next' signs. |
5871 */ | 5938 */ |
5872 static void | 5939 static void |
5888 { | 5955 { |
5889 newsign->id = id; | 5956 newsign->id = id; |
5890 newsign->lnum = lnum; | 5957 newsign->lnum = lnum; |
5891 newsign->typenr = typenr; | 5958 newsign->typenr = typenr; |
5892 if (group != NULL) | 5959 if (group != NULL) |
5893 newsign->group = vim_strsave(group); | 5960 { |
5961 newsign->group = sign_group_ref(group); | |
5962 if (newsign->group == NULL) | |
5963 { | |
5964 vim_free(newsign); | |
5965 return; | |
5966 } | |
5967 } | |
5894 else | 5968 else |
5895 newsign->group = NULL; | 5969 newsign->group = NULL; |
5896 newsign->priority = prio; | 5970 newsign->priority = prio; |
5897 newsign->next = next; | 5971 newsign->next = next; |
5898 newsign->prev = prev; | 5972 newsign->prev = prev; |
5957 sign_in_group(signlist_T *sign, char_u *group) | 6031 sign_in_group(signlist_T *sign, char_u *group) |
5958 { | 6032 { |
5959 return ((group != NULL && STRCMP(group, "*") == 0) || | 6033 return ((group != NULL && STRCMP(group, "*") == 0) || |
5960 (group == NULL && sign->group == NULL) || | 6034 (group == NULL && sign->group == NULL) || |
5961 (group != NULL && sign->group != NULL && | 6035 (group != NULL && sign->group != NULL && |
5962 STRCMP(group, sign->group) == 0)); | 6036 STRCMP(group, sign->group->sg_name) == 0)); |
5963 } | 6037 } |
5964 | 6038 |
5965 /* | 6039 /* |
5966 * Return information about a sign in a Dict | 6040 * Return information about a sign in a Dict |
5967 */ | 6041 */ |
5972 | 6046 |
5973 if ((d = dict_alloc_id(aid_sign_getinfo)) == NULL) | 6047 if ((d = dict_alloc_id(aid_sign_getinfo)) == NULL) |
5974 return NULL; | 6048 return NULL; |
5975 dict_add_number(d, "id", sign->id); | 6049 dict_add_number(d, "id", sign->id); |
5976 dict_add_string(d, "group", (sign->group == NULL) ? | 6050 dict_add_string(d, "group", (sign->group == NULL) ? |
5977 (char_u *)"" : sign->group); | 6051 (char_u *)"" : sign->group->sg_name); |
5978 dict_add_number(d, "lnum", sign->lnum); | 6052 dict_add_number(d, "lnum", sign->lnum); |
5979 dict_add_string(d, "name", sign_typenr2name(sign->typenr)); | 6053 dict_add_string(d, "name", sign_typenr2name(sign->typenr)); |
5980 dict_add_number(d, "priority", sign->priority); | 6054 dict_add_number(d, "priority", sign->priority); |
5981 | 6055 |
5982 return d; | 6056 return d; |
5987 */ | 6061 */ |
5988 void | 6062 void |
5989 buf_addsign( | 6063 buf_addsign( |
5990 buf_T *buf, // buffer to store sign in | 6064 buf_T *buf, // buffer to store sign in |
5991 int id, // sign ID | 6065 int id, // sign ID |
5992 char_u *group, // sign group | 6066 char_u *groupname, // sign group |
5993 int prio, // sign priority | 6067 int prio, // sign priority |
5994 linenr_T lnum, // line number which gets the mark | 6068 linenr_T lnum, // line number which gets the mark |
5995 int typenr) // typenr of sign we are adding | 6069 int typenr) // typenr of sign we are adding |
5996 { | 6070 { |
5997 signlist_T *sign; // a sign in the signlist | 6071 signlist_T *sign; // a sign in the signlist |
5999 | 6073 |
6000 prev = NULL; | 6074 prev = NULL; |
6001 FOR_ALL_SIGNS_IN_BUF(buf) | 6075 FOR_ALL_SIGNS_IN_BUF(buf) |
6002 { | 6076 { |
6003 if (lnum == sign->lnum && id == sign->id && | 6077 if (lnum == sign->lnum && id == sign->id && |
6004 sign_in_group(sign, group)) | 6078 sign_in_group(sign, groupname)) |
6005 { | 6079 { |
6006 // Update an existing sign | 6080 // Update an existing sign |
6007 sign->typenr = typenr; | 6081 sign->typenr = typenr; |
6008 return; | 6082 return; |
6009 } | 6083 } |
6010 else if (lnum < sign->lnum) | 6084 else if (lnum < sign->lnum) |
6011 { | 6085 { |
6012 insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr); | 6086 insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, |
6087 lnum, typenr); | |
6013 return; | 6088 return; |
6014 } | 6089 } |
6015 prev = sign; | 6090 prev = sign; |
6016 } | 6091 } |
6017 | 6092 |
6018 insert_sign_by_lnum_prio(buf, prev, id, group, prio, lnum, typenr); | 6093 insert_sign_by_lnum_prio(buf, prev, id, groupname, prio, lnum, typenr); |
6019 | |
6020 return; | 6094 return; |
6021 } | 6095 } |
6022 | 6096 |
6023 /* | 6097 /* |
6024 * For an existing, placed sign "markId" change the type to "typenr". | 6098 * For an existing, placed sign "markId" change the type to "typenr". |
6104 { | 6178 { |
6105 *lastp = next; | 6179 *lastp = next; |
6106 if (next != NULL) | 6180 if (next != NULL) |
6107 next->prev = sign->prev; | 6181 next->prev = sign->prev; |
6108 lnum = sign->lnum; | 6182 lnum = sign->lnum; |
6109 vim_free(sign->group); | 6183 if (sign->group != NULL) |
6184 sign_group_unref(sign->group->sg_name); | |
6110 vim_free(sign); | 6185 vim_free(sign); |
6111 // Check whether only one sign needs to be deleted | 6186 // Check whether only one sign needs to be deleted |
6112 if (group == NULL || (*group != '*' && id != 0)) | 6187 if (group == NULL || (*group != '*' && id != 0)) |
6113 break; | 6188 break; |
6114 } | 6189 } |
6267 if (sign_in_group(sign, group)) | 6342 if (sign_in_group(sign, group)) |
6268 { | 6343 { |
6269 *lastp = next; | 6344 *lastp = next; |
6270 if (next != NULL) | 6345 if (next != NULL) |
6271 next->prev = sign->prev; | 6346 next->prev = sign->prev; |
6272 vim_free(sign->group); | 6347 if (sign->group != NULL) |
6348 sign_group_unref(sign->group->sg_name); | |
6273 vim_free(sign); | 6349 vim_free(sign); |
6274 } | 6350 } |
6275 else | 6351 else |
6276 lastp = &sign->next; | 6352 lastp = &sign->next; |
6277 } | 6353 } |
6315 MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); | 6391 MSG_PUTS_ATTR(lbuf, HL_ATTR(HLF_D)); |
6316 msg_putchar('\n'); | 6392 msg_putchar('\n'); |
6317 } | 6393 } |
6318 FOR_ALL_SIGNS_IN_BUF(buf) | 6394 FOR_ALL_SIGNS_IN_BUF(buf) |
6319 { | 6395 { |
6396 if (got_int) | |
6397 break; | |
6320 if (!sign_in_group(sign, sign_group)) | 6398 if (!sign_in_group(sign, sign_group)) |
6321 continue; | 6399 continue; |
6322 if (sign->group != NULL) | 6400 if (sign->group != NULL) |
6323 vim_snprintf(group, BUFSIZ, " group=%s", sign->group); | 6401 vim_snprintf(group, BUFSIZ, " group=%s", |
6402 sign->group->sg_name); | |
6324 else | 6403 else |
6325 group[0] = '\0'; | 6404 group[0] = '\0'; |
6326 vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s " | 6405 vim_snprintf(lbuf, BUFSIZ, _(" line=%ld id=%d%s name=%s " |
6327 "priority=%d"), | 6406 "priority=%d"), |
6328 (long)sign->lnum, sign->id, group, | 6407 (long)sign->lnum, sign->id, group, |