From cbf02ca8e9d73f2942d3342a830dc166fb0e9cb0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Karl=20Yngve=20Lerv=C3=A5g?= Date: Mon, 6 Sep 2021 14:02:03 +0200 Subject: [PATCH] feat: use cache for tags This should speed up tag parsing by a lot, except for the first time. refer: #175 --- autoload/wiki/cache.vim | 9 ++++ autoload/wiki/tags.vim | 68 +++++++++++++++++++++-------- test/test-tags/test-custom-yaml.vim | 2 + test/test-tags/test-defaults.vim | 2 + 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/autoload/wiki/cache.vim b/autoload/wiki/cache.vim index 65749843..258db370 100644 --- a/autoload/wiki/cache.vim +++ b/autoload/wiki/cache.vim @@ -128,6 +128,15 @@ function! s:cache.init(name, opts) dict abort " {{{1 let new.ftime = -1 let new.modified = 0 + if has_key(a:opts, 'validate') + call new.read() + if get(new.data, '__validate', {}) != a:opts.validate + call new.clear() + let new.data.__validate = deepcopy(a:opts.validate) + call new.write() + endif + endif + return new endfunction diff --git a/autoload/wiki/tags.vim b/autoload/wiki/tags.vim index 4656fddd..c27d62ca 100644 --- a/autoload/wiki/tags.vim +++ b/autoload/wiki/tags.vim @@ -178,13 +178,27 @@ endfunction " }}}1 function! s:tags.gather() abort dict " {{{1 if !self.parsed - for l:type in g:wiki_filetypes - for l:file in globpath(wiki#get_root(), - \ '**/*.' . l:type , 0, 1) - call self.gather_from_file(l:file) - endfor - endfor + let l:t0 = reltime() + if !has_key(self, 'cache') + let self.cache = wiki#cache#open('tags', { + \ 'default': { 'ftime': -1 }, + \ 'validate': {'opts': [ + \ g:wiki_tag_scan_num_lines, + \ string(g:wiki_tag_parsers), + \ ]}, + \}) + endif + + let l:files = filter( + \ globpath(wiki#get_root(), '**/*.*', 0, 1), + \ {_, x -> index(g:wiki_filetypes, fnamemodify(x, ':e')) >= 0}) + call map(l:files, {_, x -> self.gather_from_file(x)}) + + call self.cache.write() let self.parsed = 1 + + let l:t1 = reltimefloat(reltime(l:t0)) + call wiki#log#info('Parsed tags (took ' . string(l:t1) . ' seconds)') endif return self.collection @@ -192,12 +206,39 @@ endfunction " }}}1 function! s:tags.gather_from_file(file) abort dict " {{{1 + let l:current = self.cache.get(a:file) + + let l:ftime = getftime(a:file) + if l:ftime > l:current.ftime + let self.cache.modified = 1 + let l:current.ftime = l:ftime + let l:current.tags = s:parse_tags_in_file(a:file) + endif + + for [l:tag, l:lnum] in l:current.tags + call self.add(l:tag, a:file, l:lnum) + endfor +endfunction + +" }}}1 +function! s:tags.add(tag, ...) abort dict " {{{1 + if !has_key(self.collection, a:tag) + let self.collection[a:tag] = [] + endif + + call add(self.collection[a:tag], a:000) +endfunction + +" }}}1 + +function! s:parse_tags_in_file(file) abort " {{{1 + let l:tags = [] + let l:lnum = 0 + let l:is_code = v:false let l:lines = g:wiki_tag_scan_num_lines ==# 'all' \ ? readfile(a:file) \ : readfile(a:file, 0, g:wiki_tag_scan_num_lines) - let l:lnum = 0 - let l:is_code = v:false for l:line in l:lines let l:lnum += 1 @@ -213,21 +254,14 @@ function! s:tags.gather_from_file(file) abort dict " {{{1 for l:parser in g:wiki_tag_parsers if l:parser.match(l:line) for l:tag in l:parser.parse(l:line) - call self.add(l:tag, a:file, l:lnum) + call add(l:tags, [l:tag, l:lnum]) endfor continue endif endfor endfor -endfunction - -" }}}1 -function! s:tags.add(tag, ...) abort dict " {{{1 - if !has_key(self.collection, a:tag) - let self.collection[a:tag] = [] - endif - call add(self.collection[a:tag], a:000) + return tags endfunction " }}}1 diff --git a/test/test-tags/test-custom-yaml.vim b/test/test-tags/test-custom-yaml.vim index 3d2c9782..353c479d 100644 --- a/test/test-tags/test-custom-yaml.vim +++ b/test/test-tags/test-custom-yaml.vim @@ -1,6 +1,8 @@ source ../init.vim runtime plugin/wiki.vim +let g:wiki_cache_persistent = 0 + let g:wiki_filetypes = ['md'] let g:wiki_link_extension = '.md' let g:wiki_tag_parsers = [ diff --git a/test/test-tags/test-defaults.vim b/test/test-tags/test-defaults.vim index 6003f450..e870ac4a 100644 --- a/test/test-tags/test-defaults.vim +++ b/test/test-tags/test-defaults.vim @@ -1,6 +1,8 @@ source ../init.vim runtime plugin/wiki.vim +let g:wiki_cache_persistent = 0 + silent edit ../wiki-basic/index.wiki let s:tags = wiki#tags#get_all()