fix #1064 by adding timestamp of document in cache key

so that when document is modified the persistent cache will
be invalidated automatically because the cache key will not
be matched. There is no perfermance overhead here at all. We
even don't need to check the modification time of the cache item
on disk, because the name of the on disk cache is a md5sum of the
cacheitem key, now the filename of the cache files contains the
modification time information.
If the document is modified since one rendered page is cached to disk,
the cache key won't match the cache file. And the cache file will
be discarded without the need to open the cache file or to check
the modification time of the cache file itself.
pull/1071/head
chrox 10 years ago
parent 72f9449de8
commit 8c9751744e

@ -1,11 +1,12 @@
local TileCacheItem = require("document/tilecacheitem")
local DrawContext = require("ffi/drawcontext") local DrawContext = require("ffi/drawcontext")
local Configurable = require("configurable")
local Blitbuffer = require("ffi/blitbuffer") local Blitbuffer = require("ffi/blitbuffer")
local Cache = require("cache") local lfs = require("libs/libkoreader-lfs")
local CacheItem = require("cacheitem") local CacheItem = require("cacheitem")
local TileCacheItem = require("document/tilecacheitem")
local Geom = require("ui/geometry") local Geom = require("ui/geometry")
local Configurable = require("configurable")
local Math = require("optmath") local Math = require("optmath")
local Cache = require("cache")
local DEBUG = require("dbg") local DEBUG = require("dbg")
--[[ --[[
@ -114,6 +115,7 @@ function Document:getNativePageDimensions(pageno)
end end
function Document:_readMetadata() function Document:_readMetadata()
self.mod_time = lfs.attributes(self.file, "modification")
self.info.number_of_pages = self._document:getPages() self.info.number_of_pages = self._document:getPages()
return true return true
end end
@ -215,8 +217,13 @@ function Document:getCoverPageImage()
return nil return nil
end end
function Document:getFullPageHash(pageno, zoom, rotation, gamma, render_mode)
return "renderpg|"..self.file.."|"..self.mod_time.."|"..pageno.."|"
..zoom.."|"..rotation.."|"..gamma.."|"..render_mode
end
function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode) function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
local hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode local hash = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode)
local page_size = self:getPageDimensions(pageno, zoom, rotation) local page_size = self:getPageDimensions(pageno, zoom, rotation)
-- this will be the size we actually render -- this will be the size we actually render
local size = page_size local size = page_size
@ -231,12 +238,13 @@ function Document:renderPage(pageno, rect, zoom, rotation, gamma, render_mode)
return return
end end
-- only render required part -- only render required part
hash = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode.."|"..tostring(rect) hash = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode).."|"..tostring(rect)
size = rect size = rect
end end
-- prepare cache item with contained blitbuffer -- prepare cache item with contained blitbuffer
local tile = TileCacheItem:new{ local tile = TileCacheItem:new{
persistent = true,
size = size.w * size.h + 64, -- estimation size = size.w * size.h + 64, -- estimation
excerpt = size, excerpt = size,
pageno = pageno, pageno = pageno,
@ -274,7 +282,7 @@ end
-- a hint for the cache engine to paint a full page to the cache -- a hint for the cache engine to paint a full page to the cache
-- TODO: this should trigger a background operation -- TODO: this should trigger a background operation
function Document:hintPage(pageno, zoom, rotation, gamma, render_mode) function Document:hintPage(pageno, zoom, rotation, gamma, render_mode)
local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode local hash_full_page = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode)
if not Cache:check(hash_full_page, TileCacheItem) then if not Cache:check(hash_full_page, TileCacheItem) then
DEBUG("hinting page", pageno) DEBUG("hinting page", pageno)
self:renderPage(pageno, nil, zoom, rotation, gamma, render_mode) self:renderPage(pageno, nil, zoom, rotation, gamma, render_mode)
@ -290,7 +298,7 @@ Draw page content to blitbuffer.
@rect: visible_area inside document page @rect: visible_area inside document page
--]] --]]
function Document:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode) function Document:drawPage(target, x, y, rect, pageno, zoom, rotation, gamma, render_mode)
local hash_full_page = "renderpg|"..self.file.."|"..pageno.."|"..zoom.."|"..rotation.."|"..gamma.."|"..render_mode local hash_full_page = self:getFullPageHash(pageno, zoom, rotation, gamma, render_mode)
local hash_excerpt = hash_full_page.."|"..tostring(rect) local hash_excerpt = hash_full_page.."|"..tostring(rect)
local tile = Cache:check(hash_full_page, TileCacheItem) local tile = Cache:check(hash_full_page, TileCacheItem)
if not tile then if not tile then

@ -107,7 +107,8 @@ function KoptInterface:getContextHash(doc, pageno, bbox)
local screen_size = Screen:getSize() local screen_size = Screen:getSize()
local screen_size_hash = screen_size.w.."|"..screen_size.h local screen_size_hash = screen_size.w.."|"..screen_size.h
local bbox_hash = bbox.x0.."|"..bbox.y0.."|"..bbox.x1.."|"..bbox.y1 local bbox_hash = bbox.x0.."|"..bbox.y0.."|"..bbox.x1.."|"..bbox.y1
return doc.file.."|"..pageno.."|"..doc.configurable:hash("|").."|"..bbox_hash.."|"..screen_size_hash return doc.file.."|"..doc.mod_time.."|"..pageno.."|"
..doc.configurable:hash("|").."|"..bbox_hash.."|"..screen_size_hash
end end
function KoptInterface:getPageBBox(doc, pageno) function KoptInterface:getPageBBox(doc, pageno)
@ -215,6 +216,7 @@ function KoptInterface:getCachedContext(doc, pageno)
DEBUG("reflowed page", pageno, "fullwidth:", fullwidth, "fullheight:", fullheight) DEBUG("reflowed page", pageno, "fullwidth:", fullwidth, "fullheight:", fullheight)
self.last_context_size = fullwidth * fullheight + 128 -- estimation self.last_context_size = fullwidth * fullheight + 128 -- estimation
Cache:insert(kctx_hash, ContextCacheItem:new{ Cache:insert(kctx_hash, ContextCacheItem:new{
persistent = true,
size = self.last_context_size, size = self.last_context_size,
kctx = kc kctx = kc
}) })
@ -289,7 +291,7 @@ function KoptInterface:renderReflowedPage(doc, pageno, rect, zoom, rotation, ren
end end
-- prepare cache item with contained blitbuffer -- prepare cache item with contained blitbuffer
local tile = TileCacheItem:new{ local tile = TileCacheItem:new{
size = fullwidth * fullheight / 2 + 64, -- estimation size = fullwidth * fullheight + 64, -- estimation
excerpt = Geom:new{ w = fullwidth, h = fullheight }, excerpt = Geom:new{ w = fullwidth, h = fullheight },
pageno = pageno, pageno = pageno,
} }
@ -311,7 +313,7 @@ function KoptInterface:renderOptimizedPage(doc, pageno, rect, zoom, rotation, re
local context_hash = self:getContextHash(doc, pageno, bbox) local context_hash = self:getContextHash(doc, pageno, bbox)
local renderpg_hash = "renderoptpg|"..context_hash..zoom local renderpg_hash = "renderoptpg|"..context_hash..zoom
local cached = Cache:check(renderpg_hash) local cached = Cache:check(renderpg_hash, TileCacheItem)
if not cached then if not cached then
local page_size = Document.getNativePageDimensions(doc, pageno) local page_size = Document.getNativePageDimensions(doc, pageno)
local bbox = { local bbox = {
@ -329,7 +331,8 @@ function KoptInterface:renderOptimizedPage(doc, pageno, rect, zoom, rotation, re
local fullwidth, fullheight = kc:getPageDim() local fullwidth, fullheight = kc:getPageDim()
-- prepare cache item with contained blitbuffer -- prepare cache item with contained blitbuffer
local tile = TileCacheItem:new{ local tile = TileCacheItem:new{
size = fullwidth * fullheight / 2 + 64, -- estimation persistent = true,
size = fullwidth * fullheight + 64, -- estimation
excerpt = Geom:new{ excerpt = Geom:new{
x = 0, y = 0, x = 0, y = 0,
w = fullwidth, w = fullwidth,

Loading…
Cancel
Save