diff options
author | ZyX <kp-pav@yandex.ru> | 2015-07-04 17:55:58 +0300 |
---|---|---|
committer | ZyX <kp-pav@yandex.ru> | 2015-10-08 21:59:54 +0300 |
commit | 4eeafe7f72de2e63c68977ff929a4a0d49c711f9 (patch) | |
tree | c797c113a13befe443ac2e277ccac501f3a8ca8f | |
parent | 75c9a7e65bf71444ca1a43a9d88909b41c2909ca (diff) | |
download | rneovim-4eeafe7f72de2e63c68977ff929a4a0d49c711f9.tar.gz rneovim-4eeafe7f72de2e63c68977ff929a4a0d49c711f9.tar.bz2 rneovim-4eeafe7f72de2e63c68977ff929a4a0d49c711f9.zip |
shada: Use pre-populated set of buffers on removable media
Should be faster then constantly running shada_removable for each buffer many
times.
-rw-r--r-- | src/nvim/shada.c | 67 |
1 files changed, 48 insertions, 19 deletions
diff --git a/src/nvim/shada.c b/src/nvim/shada.c index 4c44624b76..aaa9f1d9c1 100644 --- a/src/nvim/shada.c +++ b/src/nvim/shada.c @@ -200,6 +200,27 @@ typedef struct { RINGBUF_INIT(HM, hm, ShadaEntry, shada_free_shada_entry) +/// Check whether buffer is in the given set +/// +/// @param[in] set Set to check within. +/// @param[in] buf Buffer to find. +/// +/// @return true or false. +static inline bool in_bufset(const khash_t(bufset) *const set, const buf_T *buf) + FUNC_ATTR_PURE +{ + return kh_get(bufset, set, (uintptr_t) buf) != kh_end(set); +} + +/// Check whether buffer is on removable media +/// +/// Uses pre-populated set with buffers on removable media named removable_bufs. +/// +/// @param[in] buf Buffer to check. +/// +/// @return true or false. +#define SHADA_REMOVABLE(buf) in_bufset(removable_bufs, buf) + /// Msgpack callback for writing to FILE* static int msgpack_fbuffer_write(void *data, const char *buf, size_t len) { @@ -720,7 +741,7 @@ static void shada_read(FILE *const fp, const int flags) } FOR_ALL_TAB_WINDOWS(tp, wp) { (void) tp; - if (kh_get(bufset, cl_bufs, (uintptr_t) wp->w_buffer) != kh_end(cl_bufs)) { + if (in_bufset(cl_bufs, wp->w_buffer)) { wp->w_changelistidx = wp->w_buffer->b_changelistlen; } } @@ -1031,6 +1052,7 @@ static void shada_pack_entry(msgpack_packer *const packer, static void shada_write(FILE *const newfp, FILE *const oldfp) FUNC_ATTR_NONNULL_ARG(1) { + khash_t(bufset) *const removable_bufs = kh_init(bufset); int max_kbyte_i = get_viminfo_parameter('s'); if (max_kbyte_i < 0) { max_kbyte_i = 10; @@ -1042,6 +1064,13 @@ static void shada_write(FILE *const newfp, FILE *const oldfp) msgpack_packer *packer = msgpack_packer_new(newfp, &msgpack_fbuffer_write); + FOR_ALL_BUFFERS(buf) { + if (buf->b_ffname != NULL && shada_removable((char *) buf->b_ffname)) { + int kh_ret; + (void) kh_put(bufset, removable_bufs, (uintptr_t) buf, &kh_ret); + } + } + // First write values that do not require merging // 1. Header shada_pack_entry(packer, (ShadaEntry) { @@ -1074,13 +1103,13 @@ static void shada_write(FILE *const newfp, FILE *const oldfp) size_t buf_count = 0; FOR_ALL_BUFFERS(buf) { - if (buf->b_ffname != NULL && !shada_removable(buf->b_ffname)) { + if (buf->b_ffname != NULL && !SHADA_REMOVABLE(buf)) { buf_count++; } } msgpack_pack_array(packer, buf_count); FOR_ALL_BUFFERS(buf) { - if (buf->b_ffname == NULL || shada_removable(buf->b_ffname)) { + if (buf->b_ffname == NULL || SHADA_REMOVABLE(buf)) { continue; } msgpack_pack_map(packer, 3); @@ -1107,7 +1136,7 @@ static void shada_write(FILE *const newfp, FILE *const oldfp) ? NULL : buflist_findnr(fm.fmark.fnum)); if (buf != NULL - ? shada_removable(buf->b_ffname) + ? SHADA_REMOVABLE(buf) : fm.fmark.fnum != 0) { continue; } @@ -1219,8 +1248,9 @@ static void shada_write(FILE *const newfp, FILE *const oldfp) // 7. Global marks if (get_viminfo_parameter('f') != 0) { - ShadaEntry *const global_marks = list_global_marks(); - for (ShadaEntry *mark = global_marks; mark->type != kSDItemMissing; mark++) { + ShadaEntry *const global_marks = list_global_marks(removable_bufs); + for (ShadaEntry *mark = global_marks; mark->type != kSDItemMissing; + mark++) { shada_pack_entry(packer, *mark, max_kbyte); } xfree(global_marks); @@ -1228,7 +1258,7 @@ static void shada_write(FILE *const newfp, FILE *const oldfp) // 8. Buffer marks and buffer change list FOR_ALL_BUFFERS(buf) { - if (buf->b_ffname == NULL || shada_removable(buf->b_ffname)) { + if (buf->b_ffname == NULL || SHADA_REMOVABLE(buf)) { continue; } ShadaEntry *const buffer_marks = list_buffer_marks(buf); @@ -1300,6 +1330,7 @@ static void shada_write(FILE *const newfp, FILE *const oldfp) } while (var_iter != NULL); } + kh_destroy(bufset, removable_bufs); msgpack_packer_free(packer); } @@ -2280,11 +2311,14 @@ shada_read_next_item_end: /// @warning Listed marks must be used before any buffer- or mark-editing /// function is run. /// +/// @param[in] removable_bufs Set of buffers on removable media. +/// /// @return Array of ShadaEntry values, last one has type kSDItemMissing. /// /// @warning Resulting ShadaEntry values must not be freed. Returned /// array must be freed with `xfree()`. -static ShadaEntry *list_global_marks(void) +static ShadaEntry *list_global_marks( + const khash_t(bufset) *const removable_bufs) { const void *iter = NULL; const size_t nummarks = mark_global_amount(); @@ -2299,24 +2333,19 @@ static ShadaEntry *list_global_marks(void) cur->data.filemark.additional_data = cur_fm.fmark.additional_data; cur->timestamp = cur_fm.fmark.timestamp; if (cur_fm.fmark.fnum == 0) { - cur->data.filemark.fname = (char *) (cur_fm.fname == NULL - ? NULL - : cur_fm.fname); + if (cur_fm.fname == NULL) { + continue; + } + cur->data.filemark.fname = (char *) cur_fm.fname; } else { const buf_T *const buf = buflist_findnr(cur_fm.fmark.fnum); - if (buf == NULL) { + if (buf == NULL || buf->b_ffname == NULL || SHADA_REMOVABLE(buf)) { continue; } else { cur->data.filemark.fname = (char *) buf->b_ffname; } } - if (cur->data.filemark.fname != NULL) { - if (shada_removable(cur->data.filemark.fname)) { - continue; - } else { - cur++; - } - } + cur++; } while(iter != NULL); } cur->type = kSDItemMissing; |