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

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

Loading…
Cancel
Save