From 471d6247dbadeb46f0ef721bce4a221581b03bfe Mon Sep 17 00:00:00 2001 From: Johan Kiviniemi Date: Sat, 28 Dec 2013 14:57:53 +0200 Subject: [PATCH 1/3] tileset: Automatically resume an interrupted forcerender --- overviewer_core/tileset.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/overviewer_core/tileset.py b/overviewer_core/tileset.py index e933c49..bedbdd8 100644 --- a/overviewer_core/tileset.py +++ b/overviewer_core/tileset.py @@ -115,6 +115,9 @@ Bounds = namedtuple("Bounds", ("mincol", "maxcol", "minrow", "maxrow")) # For render-tiles, render all whose chunks have an mtime greater than # the mtime of the tile on disk, and their composite-tile ancestors. # +# Also rerender any tiles rendered before forcerendertime. It is nonzero +# whenever a mode=2 render has been interrupted. +# # Also check all other composite-tiles and render any that have children # with more rencent mtimes than itself. # @@ -283,6 +286,7 @@ class TileSet(object): self.config = config self.last_rendertime = config.get('last_rendertime', 0) + self.forcerendertime = config.get('forcerendertime', 0) if "renderchecks" not in self.options: # renderchecks was not given, this indicates it was not specified @@ -347,6 +351,11 @@ class TileSet(object): self.options['renderchecks'] = 2 os.mkdir(self.outputdir) + if self.options['renderchecks'] == 2: + # Set forcerendertime so that upon an interruption the next render + # will continue where we left off. + self.forcerendertime = int(time.time()) + # Set the image format according to the options if self.options['imgformat'] == 'png': self.imgextension = 'png' @@ -502,8 +511,11 @@ class TileSet(object): # following exceptions: # * last_rendertime is not changed # * A key "render_in_progress" is set to True + # * forcerendertime is set so that an interrupted mode=2 render will + # finish properly. d['last_rendertime'] = self.last_rendertime d['render_in_progress'] = True + d['forcerendertime'] = self.forcerendertime return d def get_persistent_data(self): @@ -1063,8 +1075,10 @@ class TileSet(object): "information") logging.warning("Tile was: %s", imgpath) - if max_chunk_mtime > tile_mtime: - # chunks have a more recent mtime than the tile. Render the tile + if max_chunk_mtime > tile_mtime or tile_mtime < self.forcerendertime: + # chunks have a more recent mtime than the tile or the tile has + # an older mtime than the forcerendertime from an interrupted + # render. Render the tile. yield (path, None, True) else: # This doesn't need rendering. Return mtime to parent in case From 65f375eaac96febadf374899c677fd9933ff7624 Mon Sep 17 00:00:00 2001 From: Johan Kiviniemi Date: Sun, 29 Dec 2013 01:36:36 +0200 Subject: [PATCH 2/3] Add debugging code to RendertileSet counts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There seems to be something wrong with count caching. Calculate the count by iterating and log an error when that count doesn’t equal the precalculated one. --- overviewer_core/tileset.py | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/overviewer_core/tileset.py b/overviewer_core/tileset.py index bedbdd8..39b7c3c 100644 --- a/overviewer_core/tileset.py +++ b/overviewer_core/tileset.py @@ -1480,14 +1480,28 @@ class RendertileSet(object): """Returns the total number of render-tiles in this set. """ - return self.num_tiles + # XXX There seems to be something wrong with the num_tiles calculation. + # Calculate the number of tiles by iteration and emit a warning if it + # does not match. + from itertools import imap + num = sum(imap(lambda _: 1, self.iterate())) + if num != self.num_tiles: + logging.error("Please report this to the developers: RendertileSet num_tiles=%r, count=%r, children=%r", self.num_tiles, num, self.children) + return num def count_all(self): """Returns the total number of render-tiles plus implicitly marked upper-tiles in this set """ - return self.num_tiles_all + # XXX There seems to be something wrong with the num_tiles calculation. + # Calculate the number of tiles by iteration and emit a warning if it + # does not match. + from itertools import imap + num = sum(imap(lambda _: 1, self.posttraversal())) + if num != self.num_tiles_all: + logging.error("Please report this to the developers: RendertileSet num_tiles_all=%r, count_all=%r, children=%r", self.num_tiles, num, self.children) + return num def distance_sort(children, (off_x, off_y)): order = [] From 8ac4f2811e9a3e3a6ba010267b5ebdee5734f9cf Mon Sep 17 00:00:00 2001 From: Johan Kiviniemi Date: Sun, 29 Dec 2013 01:43:32 +0200 Subject: [PATCH 3/3] RendertileSet: Do not render the root tile unnecessarily --- overviewer_core/tileset.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/overviewer_core/tileset.py b/overviewer_core/tileset.py index 39b7c3c..c8aa1f7 100644 --- a/overviewer_core/tileset.py +++ b/overviewer_core/tileset.py @@ -1442,7 +1442,7 @@ class RendertileSet(object): for p in roundrobin(gens) if robin else chain(*gens): yield p - if onlydepth is None and children: + if onlydepth is None and any(children_list): yield path def query_path(self, path):