" ============================================================================= " Filename: autoload/calendar/countcache.vim " Author: itchyny " License: MIT License " Last Change: 2020/11/19 07:40:05. " ============================================================================= let s:save_cpo = &cpo set cpo&vim " CountCache object, caching anything with countdown. " Caching is imporant for speeding up. However, storing everything causes the " cache to grow bigger and bigger. For efficient caching, this CountCache object " is used. Basically, data are stored with numbers. " [ num, data ] " The number refers to how many times the data is referenced to. And when saving " to the cache file, data are saved if the data was referenced many times enough. " When restoring the data from the cache file, all the counts are subtracted " one, so that data will disappear if it is not referenced to for a long time. let s:cache = calendar#cache#new('countcache') let s:caches = [] function! calendar#countcache#new(name) abort let self = extend(copy(s:self), { 'name': a:name }) let cache = s:cache.get(a:name) " When restoring from the cache file, negate each count by 1. " Also, keep the number small (50 in max) so that the number will not overflow. let self.cache = type(cache) == type({}) ? map(cache, '[min([v:val[0] - 1, 50]), v:val[1]]') : {} call add(s:caches, self) return self endfunction let s:saveflag = {} let s:count = 0 " Saving the cache to the cache file. function! calendar#countcache#save() abort if s:count < 10 let s:count += 1 return endif let s:count = 0 if exists('s:reltime') && has('reltime') let time = split(split(reltimestr(reltime(s:reltime)))[0], '\.') if time[0] < 60 return endif endif for c in s:caches if get(s:saveflag, c.name, 1) call s:cache.save(c.name, filter(c.cache, 'v:val[0] > 29')) let s:saveflag[c.name] = 0 endif endfor if has('reltime') let s:reltime = reltime() endif endfunction augroup CalendarCountCache autocmd! autocmd CursorHold * call calendar#countcache#save() augroup END let s:self = {} " Check if the key is found in the cache. function! s:self.has_key(k) dict abort return has_key(self.cache, a:k) endfunction " Be sure to check has_key before getting the data. function! s:self.get(k) dict abort let self.cache[a:k][0] += 1 return self.cache[a:k][1] endfunction " Save a data with a key. function! s:self.save(k, v) dict abort let self.cache[a:k] = [ get(self.cache, a:k, [0])[0] + 1, a:v ] let s:saveflag[self.name] = 1 return a:v endfunction let &cpo = s:save_cpo unlet s:save_cpo