change MapHistory format from cache_key to id and timestamp

This commit is contained in:
Laura Klünder 2017-10-24 01:59:50 +02:00
parent 1b972c4ab0
commit f34dd89424
2 changed files with 23 additions and 14 deletions

View file

@ -1,6 +1,7 @@
import math import math
import os import os
import struct import struct
from itertools import chain
import numpy as np import numpy as np
from django.conf import settings from django.conf import settings
@ -20,8 +21,11 @@ class MapHistory:
# 2 bytes (uint16): origin width # 2 bytes (uint16): origin width
# 2 bytes (uint16): origin height # 2 bytes (uint16): origin height
# 2 bytes (uint16): number of updates # 2 bytes (uint16): number of updates
# n*16 bytes: update keys as null-terminated strings # n uptates times:
# width*height*2 bytes: data (line after line) with uint16 data # 4 bytes (uint32): update id
# 4 bytes (uint32): timestamp
# width*height*2 bytes:
# data array (line after line) with uint16 cells
def __init__(self, resolution=settings.CACHE_RESOLUTION, x=0, y=0, updates=None, data=np.empty((0, 0))): def __init__(self, resolution=settings.CACHE_RESOLUTION, x=0, y=0, updates=None, data=np.empty((0, 0))):
self.resolution = resolution self.resolution = resolution
@ -36,7 +40,8 @@ class MapHistory:
try: try:
with open(filename, 'rb') as f: with open(filename, 'rb') as f:
resolution, x, y, width, height, num_updates = struct.unpack('<BHHHHH', f.read(11)) resolution, x, y, width, height, num_updates = struct.unpack('<BHHHHH', f.read(11))
updates = [s.decode().rstrip('\x00') for s in struct.unpack('16s'*num_updates, f.read(num_updates*16))] updates = struct.unpack('II'*num_updates, f.read(num_updates*8))
updates = list(zip(updates[0::2], updates[1::2]))
# noinspection PyTypeChecker # noinspection PyTypeChecker
data = np.fromstring(f.read(width*height*2), np.uint16).reshape((height, width)) data = np.fromstring(f.read(width*height*2), np.uint16).reshape((height, width))
return cls(resolution, x, y, list(updates), data) return cls(resolution, x, y, list(updates), data)
@ -51,7 +56,7 @@ class MapHistory:
with open(filename, 'wb') as f: with open(filename, 'wb') as f:
f.write(struct.pack('<BHHHHH', self.resolution, self.x, self.y, *reversed(self.data.shape), f.write(struct.pack('<BHHHHH', self.resolution, self.x, self.y, *reversed(self.data.shape),
len(self.updates))) len(self.updates)))
f.write(struct.pack('16s'*len(self.updates), *(s.encode() for s in self.updates))) f.write(struct.pack('II'*len(self.updates), *chain(*self.updates)))
f.write(self.data.tobytes('C')) f.write(self.data.tobytes('C'))
def add_new(self, geometry): def add_new(self, geometry):
@ -87,15 +92,14 @@ class MapHistory:
for iy, y in enumerate(range(miny*res, maxy*res, res), start=miny-self.y): for iy, y in enumerate(range(miny*res, maxy*res, res), start=miny-self.y):
for ix, x in enumerate(range(minx*res, maxx*res, res), start=minx-self.x): for ix, x in enumerate(range(minx*res, maxx*res, res), start=minx-self.x):
if prep.intersects(box(x, y, x+res, y+res)): if prep.intersects(box(x, y, x+res, y+res)):
# print(iy, ix)
data[iy, ix] = new_val data[iy, ix] = new_val
self.data = data self.data = data
self.unfinished = True self.unfinished = True
def finish(self, cache_key): def finish(self, update):
self.unfinished = False self.unfinished = False
self.updates.append(cache_key) self.updates.append(update)
class GeometryChangeTracker: class GeometryChangeTracker:

View file

@ -31,8 +31,13 @@ class MapUpdate(models.Model):
return last_update return last_update
with cls.lock(): with cls.lock():
last_update = cls.objects.latest() last_update = cls.objects.latest()
cache.set('mapdata:last_update', (last_update.pk, last_update.datetime), 900) result = last_update.pk, int(make_naive(last_update.datetime).timestamp())
return last_update.pk, last_update.datetime cache.set('mapdata:last_update', result, 900)
return result
@property
def to_tuple(self):
return self.pk, int(make_naive(self.datetime).timestamp())
@property @property
def cache_key(self): def cache_key(self):
@ -40,8 +45,8 @@ class MapUpdate(models.Model):
@classmethod @classmethod
def current_cache_key(cls): def current_cache_key(cls):
pk, dt = cls.last_update() pk, timestamp = cls.last_update()
return int_to_base36(pk)+'_'+int_to_base36(int(make_naive(dt).timestamp())) return int_to_base36(pk)+'_'+int_to_base36(timestamp)
@classmethod @classmethod
@contextmanager @contextmanager
@ -53,7 +58,7 @@ class MapUpdate(models.Model):
if self.pk is not None: if self.pk is not None:
raise TypeError raise TypeError
old_cache_key = MapUpdate.current_cache_key() last_map_update = MapUpdate.last_update()
from c3nav.mapdata.models import AltitudeArea from c3nav.mapdata.models import AltitudeArea
AltitudeArea.recalculate() AltitudeArea.recalculate()
@ -61,10 +66,10 @@ class MapUpdate(models.Model):
super().save(**kwargs) super().save(**kwargs)
from c3nav.mapdata.cache import changed_geometries from c3nav.mapdata.cache import changed_geometries
changed_geometries.save(old_cache_key, self.cache_key) changed_geometries.save(last_map_update, self.to_tuple)
from c3nav.mapdata.render.base import LevelRenderData from c3nav.mapdata.render.base import LevelRenderData
LevelRenderData.rebuild() LevelRenderData.rebuild()
cache.set('mapdata:last_update', (self.pk, self.datetime), 900) cache.set('mapdata:last_update', self.to_tuple, 900)
delete_old_cached_tiles.apply_async(countdown=5) delete_old_cached_tiles.apply_async(countdown=5)