0

Merge #1055 -- Prevent opening and parsing files which haven't been modified since the last time that the render was done.

This commit is contained in:
Andrew Chin
2014-03-30 18:21:08 -04:00
3 changed files with 45 additions and 4 deletions

View File

@@ -24,6 +24,7 @@ import functools
import time import time
import errno import errno
import stat import stat
import platform
from collections import namedtuple from collections import namedtuple
from itertools import product, izip, chain from itertools import product, izip, chain
@@ -760,8 +761,8 @@ class TileSet(object):
# Compare the last modified time of the chunk and tile. If the # Compare the last modified time of the chunk and tile. If the
# tile is older, mark it in a RendertileSet object as dirty. # tile is older, mark it in a RendertileSet object as dirty.
for chunkx, chunkz, chunkmtime in self.regionset.iterate_chunks():
for chunkx, chunkz, chunkmtime in self.regionset.iterate_chunks() if (markall or platform.system() == 'Windows') else self.regionset.iterate_newer_chunks(last_rendertime):
chunkcount += 1 chunkcount += 1
if chunkmtime > max_chunk_mtime: if chunkmtime > max_chunk_mtime:

View File

@@ -273,7 +273,7 @@ class RegionSet(object):
for x, y, regionfile in self._iterate_regionfiles(): for x, y, regionfile in self._iterate_regionfiles():
# regionfile is a pathname # regionfile is a pathname
self.regionfiles[(x,y)] = regionfile self.regionfiles[(x,y)] = (regionfile, os.path.getmtime(regionfile))
self.empty_chunk = [None,None] self.empty_chunk = [None,None]
logging.debug("Done scanning regions") logging.debug("Done scanning regions")
@@ -459,7 +459,7 @@ class RegionSet(object):
""" """
for (regionx, regiony), regionfile in self.regionfiles.iteritems(): for (regionx, regiony), (regionfile, filemtime) in self.regionfiles.iteritems():
try: try:
mcr = self._get_regionobj(regionfile) mcr = self._get_regionobj(regionfile)
except nbt.CorruptRegionError: except nbt.CorruptRegionError:
@@ -468,6 +468,27 @@ class RegionSet(object):
for chunkx, chunky in mcr.get_chunks(): for chunkx, chunky in mcr.get_chunks():
yield chunkx+32*regionx, chunky+32*regiony, mcr.get_chunk_timestamp(chunkx, chunky) yield chunkx+32*regionx, chunky+32*regiony, mcr.get_chunk_timestamp(chunkx, chunky)
def iterate_newer_chunks(self, mtime):
"""Returns an iterator over all chunk metadata in this world. Iterates
over tuples of integers (x,z,mtime) for each chunk. Other chunk data
is not returned here.
"""
for (regionx, regiony), (regionfile, filemtime) in self.regionfiles.iteritems():
""" SKIP LOADING A REGION WHICH HAS NOT BEEN MODIFIED! """
if (filemtime < mtime):
continue
try:
mcr = self._get_regionobj(regionfile)
except nbt.CorruptRegionError:
logging.warning("Found a corrupt region file at %s,%s. Skipping it.", regionx, regiony)
continue
for chunkx, chunky in mcr.get_chunks():
yield chunkx+32*regionx, chunky+32*regiony, mcr.get_chunk_timestamp(chunkx, chunky)
def get_chunk_mtime(self, x, z): def get_chunk_mtime(self, x, z):
"""Returns a chunk's mtime, or False if the chunk does not exist. This """Returns a chunk's mtime, or False if the chunk does not exist. This
is therefore a dual purpose method. It corrects for the given north is therefore a dual purpose method. It corrects for the given north
@@ -493,7 +514,7 @@ class RegionSet(object):
Coords can be either be global chunk coords, or local to a region Coords can be either be global chunk coords, or local to a region
""" """
regionfile = self.regionfiles.get((chunkX//32, chunkY//32),None) (regionfile,filemtime) = self.regionfiles.get((chunkX//32, chunkY//32),(None, None))
return regionfile return regionfile
def _iterate_regionfiles(self): def _iterate_regionfiles(self):
@@ -537,6 +558,8 @@ class RegionSetWrapper(object):
return self._r.get_chunk(x,z) return self._r.get_chunk(x,z)
def iterate_chunks(self): def iterate_chunks(self):
return self._r.iterate_chunks() return self._r.iterate_chunks()
def iterate_newer_chunks(self,filemtime):
return self._r.iterate_newer_chunks(filemtime)
def get_chunk_mtime(self, x, z): def get_chunk_mtime(self, x, z):
return self._r.get_chunk_mtime(x,z) return self._r.get_chunk_mtime(x,z)
@@ -623,6 +646,11 @@ class RotatedRegionSet(RegionSetWrapper):
x,z = self.rotate(x,z) x,z = self.rotate(x,z)
yield x,z,mtime yield x,z,mtime
def iterate_newer_chunks(self, filemtime):
for x,z,mtime in super(RotatedRegionSet, self).iterate_newer_chunks(filemtime):
x,z = self.rotate(x,z)
yield x,z,mtime
class CroppedRegionSet(RegionSetWrapper): class CroppedRegionSet(RegionSetWrapper):
def __init__(self, rsetobj, xmin, zmin, xmax, zmax): def __init__(self, rsetobj, xmin, zmin, xmax, zmax):
super(CroppedRegionSet, self).__init__(rsetobj) super(CroppedRegionSet, self).__init__(rsetobj)
@@ -646,6 +674,14 @@ class CroppedRegionSet(RegionSetWrapper):
self.xmin <= x <= self.xmax and self.xmin <= x <= self.xmax and
self.zmin <= z <= self.zmax self.zmin <= z <= self.zmax
) )
def iterate_newer_chunks(self, filemtime):
return ((x,z,mtime) for (x,z,mtime) in super(CroppedRegionSet,self).iterate_newer_chunks(filemtime)
if
self.xmin <= x <= self.xmax and
self.zmin <= z <= self.zmax
)
def get_chunk_mtime(self,x,z): def get_chunk_mtime(self,x,z):
if ( if (
self.xmin <= x <= self.xmax and self.xmin <= x <= self.xmax and

View File

@@ -53,6 +53,10 @@ class FakeRegionset(object):
for (x,z),mtime in self.chunks.iteritems(): for (x,z),mtime in self.chunks.iteritems():
yield x,z,mtime yield x,z,mtime
def iterate_newer_chunks(self, filemtime):
for (x,z),mtime in self.chunks.iteritems():
yield x,z,mtime
def get_chunk_mtime(self, x, z): def get_chunk_mtime(self, x, z):
try: try:
return self.chunks[x,z] return self.chunks[x,z]