Open isiyu opened 7 years ago
And as a reminder: this may need to persist in both the cs
and unity
layers, with a way to link the two. For example, we might want to cache Texture2d
in Unity to avoid destroying and regenerating. This would be a huge source of memory fragmentation in a slippy map. :(
And as a reminder: this may need to persist in both the
cs
andunity
layers, with a way to link the two.
To be discussed:
I'm not sure if linking the caches makes sense as they serve different purposes:
mapbox-sdk-cs
: speedup all kinds redundant queries, reduce API hitsmapbox-unity-sdk
: avoid destroying and regenerating Texture2d
All kinds of requests (VTs, raster tiles, geocoding, directions) pass through mapbox-sdk-cs
's FileSource/HTTPRequest
.
I think if/how to additionally cache the processed response data lies within the responsibility of the client library - mapbox-unity-sdk
in this case.
For mapbox-sdk-cs
I'm thinking about just a Dictionary<url, raw response byte[]>
and maybe exposing a ClearCache()
in FileSource
.
Or maybe two lists (List<url>
, List<response>
) to make managing cache size easier.
mapbox-sdk-cs
:
FileSource
doesn't know anything about the type of the requested resource - it just gets an URL.I think plan of attack could be:
FileSource
transparently caches all types of requests in memory - up to a certain (OS dependent?) limitFileSource
accepts additional parameters:CanonicalTileId
Map
object 😏 that handles all the operations/data associated with a region@BergWerkGIS Thanks for the writeup. Please let me clarify what I meant by "linking" the two cache layers. Here's an example scenario:
I've created a raster slippy map. Tile response data (raw bytes) is cached by distance relative to camera or player (some position). As you pan the map, the tile rendering may be "disabled," but the raw data is still in memory. However, we also want to preserve both the game objects (representing the tile itself--likely with a quad mesh) and the `Texture2D`. In the case that the user now pans back to a location that is cached, we want to apply a cached `Texture2D` to the tile, rather than rebuilding from the raw byte data again.
In this case, do we just share keys across dictionaries for each caching implementation? This is slightly related to your question:
Does it even make sense to cache all (successful) responses?
Perhaps we should abstract caching such that different requests (tiles) are cached differently. Does it make sense to cache raw byte data for a raster tile when we can cache a Texture2D
instead? However, it makes more sense to cache the raw data for a vector tile than individual meshes or JSON data. Can we abstract this with interfaces or generics? Developers should be able to implement their own caching strategies, but we can provide a few basic implementations.
Maybe this could be achieved by making a specific FileSource
for each type of tile? We don't need just one FileSource
as I have coded, so we can be flexible here.
Edit: Another option may be to pass in the object that is making the request and use that as a key. This is less ideal because we would have to rely on casting to handle specific types.
@david-rhodes I think we have two different requirements on two different levels:
mapbox-sdk-cs
)mapbox-unity-sdk
)mapbox-sdk-cs
doesn't care if/how its clients cache responses.
It just returns the response from the cache if the same request gets issued more than once.
Nevertheless I'm thinking about implementing a similar concept like we had before:
ICache
interfaceMemoryCache
/FileCache
FileSource
internally defaults to using MemoryCache
for raw response data, but that can be configured via parameters: eg max requests to cacheFileSource
accepts an additional ICache
parameter, which could be any implementation, FileCache
/Texture2dCache
/...Your outlined scenario could work like this:
ICache
implementation: Texture2dCache
FileSource
with
MaxResponsesToCache=0
Texture2dCache
Although I'm not sure that makes sense as getting to the cached Texture2d
would mean issuing the request url again.
To summarize I think mapbox-unity-sdk
should implement its own caching mechanism specifically designed for Unity objects.
Although it could derive from ICache
of course.
If your concern is memory usage I think caching raw response data can be neglected in comparison to caching Unity objects: a few KB vs several MB
Although I'm not sure that makes sense as getting to the cached Texture2d would mean issuing the request url again.
But wouldn't you want your originating request to look identical every single time, regardless if it's cached behind the scenes? To the client, the cache is mostly invisible, right? If I'm making a slippy map and requesting a tile, I shouldn't care if the tile was already fetched or not.
Although it could derive from ICache of course.
Great, this seems like it would be just fine.
If your concern is memory usage I think caching raw response data can be neglected in comparison to caching Unity objects
Well, this is true for most things. Unfortunately, building and destroying Texture2d
is a great way to expand the heap and fragment memory. It also takes significant time to load byte data into a texture. I would be curious to know the size difference in raw byte data versus Texture2d
memory cost for a raster tile, though.
Starting this ticket to track tile caching. @BergWerkGIS
Tier 1: In memory tile caching Tier 2: file system tile caching Tier 3: selected region tile caching (based on mobile)