change MapHistory format from cache_key to id and timestamp
This commit is contained in:
parent
1b972c4ab0
commit
f34dd89424
2 changed files with 23 additions and 14 deletions
|
@ -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:
|
||||||
|
|
|
@ -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)
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue