move get_level_render_data to LevelRenderData.get() and cache locally

This commit is contained in:
Laura Klünder 2017-11-08 18:21:54 +01:00
parent ef29f48873
commit 1a797b16f7
2 changed files with 28 additions and 20 deletions

View file

@ -1,11 +1,11 @@
import operator import operator
import pickle import pickle
import threading
from collections import namedtuple from collections import namedtuple
from functools import reduce from functools import reduce
from itertools import chain from itertools import chain
import numpy as np import numpy as np
from django.core.cache import cache
from django.db import transaction from django.db import transaction
from django.utils.functional import cached_property from django.utils.functional import cached_property
from shapely.geometry import GeometryCollection, LineString, MultiLineString from shapely.geometry import GeometryCollection, LineString, MultiLineString
@ -191,6 +191,31 @@ class LevelRenderData:
for level in levels: for level in levels:
level.save() level.save()
cached = {}
cache_key = None
cache_lock = threading.Lock()
@classmethod
def get(cls, level):
with cls.cache_lock:
cache_key = MapUpdate.current_cache_key()
level_pk = str(level.pk if isinstance(level, Level) else level)
if cls.cache_key != cache_key:
cls.cache_key = cache_key
cls.cached = {}
else:
result = cls.cached.get(level_pk, None)
if result is not None:
return result
if isinstance(level, Level):
result = pickle.loads(level.render_data)
else:
result = pickle.loads(Level.objects.filter(pk=level).values_list('render_data', flat=True)[0])
cls.cached[level_pk] = result
return result
class LevelGeometries: class LevelGeometries:
def __init__(self): def __init__(self):
@ -307,20 +332,3 @@ class LevelGeometries:
rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries()))) rings = tuple(chain(*(get_rings(geom) for geom in self.get_geometries())))
self.vertices, self.faces = triangulate_rings(rings) self.vertices, self.faces = triangulate_rings(rings)
self.create_hybrid_geometries(face_centers=self.vertices[self.faces].sum(axis=1) / 3) self.create_hybrid_geometries(face_centers=self.vertices[self.faces].sum(axis=1) / 3)
def get_level_render_data(level):
cache_key = 'mapdata:level_render_data:%s:%s' % (str(level.pk if isinstance(level, Level) else level),
MapUpdate.current_cache_key())
result = cache.get(cache_key, None)
if result is not None:
return result
if isinstance(level, Level):
result = pickle.loads(level.render_data)
else:
result = pickle.loads(Level.objects.filter(pk=level).values_list('render_data', flat=True)[0])
cache.set(cache_key, result, 900)
return result

View file

@ -5,7 +5,7 @@ from shapely.geometry import box
from c3nav.mapdata.cache import MapHistory from c3nav.mapdata.cache import MapHistory
from c3nav.mapdata.models import MapUpdate from c3nav.mapdata.models import MapUpdate
from c3nav.mapdata.render.data import get_level_render_data, hybrid_union from c3nav.mapdata.render.data import LevelRenderData, hybrid_union
from c3nav.mapdata.render.engines.base import FillAttribs, StrokeAttribs from c3nav.mapdata.render.engines.base import FillAttribs, StrokeAttribs
@ -28,7 +28,7 @@ class MapRenderer:
@cached_property @cached_property
def level_render_data(self): def level_render_data(self):
return get_level_render_data(self.level) return LevelRenderData.get(self.level)
@cached_property @cached_property
def last_update(self): def last_update(self):