Class TLfnCachingTileStore

All Implemented Interfaces:
ILfnResourceMetadataResolver, Closeable, AutoCloseable

public class TLfnCachingTileStore extends ALfnTileStoreWrapper
A Tile Store implementation that caches both metadata and data from a remote Tile Store in a local Tile Store (tile cache). The cache size can be controlled using a low and a high mark. When the high mark is exceeded, the cache will be swept asynchronously, on a thread maintained by this object. By sweeping the cache, a best effort is made to keep the cache size between the low and high mark. There is however no guarantee that the size will always stay strictly between those marks. The cache size may be above the high mark, or it may be below the low mark.

All write operations (ALfnTileStoreWrapper.deleteResource(java.lang.String), ALfnTileStoreWrapper.putResourceMetadata(T) etc.) work on the remote Tile Store. These operations propagate failures of the remote Tile Store onto the handlers.

The query(com.luciad.fusion.tilestore.ILfnQueryHandler, com.luciad.fusion.tilestore.TLfnQuery) operation first tries the remote Tile Store, and only falls back to the tile cache in case of a failure.

The ALfnCoverage.getTile(com.luciad.fusion.core.TLfnTileCoordinates, long, java.nio.channels.WritableByteChannel, java.nio.ByteBuffer, com.luciad.fusion.tilestore.ILfnReadCallback) operation tries the tile cache first, and only falls back to the remote Tile Store in case of a cache miss. This may return stale tiles: when tiles are deleted or updated on the remote Tile Store, a stale cached version may still be returned. The staleness of cached tiles can be controlled with the expiration duration, but is ignored if the remote Tile Store is offline. A low expiration duration yields tiles that are less state, at the expense of bandwidth. Caching and expiration of tiles works according to the following rules:

  • If a tile is not found in cache and is found on the remote Tile Store, the result is the new tile.
  • If a tile is not found in cache and is not found on the remote Tile Store, the result is "tile not found".
  • If a tile is found in cache and not expired, the result is the cached tile.
  • If a tile is found in cache and expired and found on the remote Tile Store, the result is the new tile. The cached tile is updated and its expiration duration is reset.
  • If a tile is found in cache and expired and not found on the remote Tile Store, the result is "tile not found". The cached tile is deleted.
  • If the remote Tile Store is offline and a tile is not found in cache, the result is "tile not found".
  • If the remote Tile Store is offline and a tile is found in cache, the result is the cached tile, regardless of whether it is expired or not.
  • Failures meaning "remote Tile Store offline" are never propagated onto the user's handler. The user can check if the remote Tile Store is online with the method isOnline().
  • Failures other than "remote Tile Store offline" are always propagated onto the user's handler.

Read operations query(com.luciad.fusion.tilestore.ILfnQueryHandler, com.luciad.fusion.tilestore.TLfnQuery) and ALfnCoverage.getTile(com.luciad.fusion.core.TLfnTileCoordinates, long, java.nio.channels.WritableByteChannel, java.nio.ByteBuffer, com.luciad.fusion.tilestore.ILfnReadCallback) never propagate failures of the remote Tile Store onto the handlers. This allows users to continue working offline.

The remote Tile Store instance is owned (created and maintained) by an instance of this class. Closing an instance also closes the Tile Store it owns. Remote Tile Store instances are created through the ALfnTileStoreProvider. When the remote Tile Store is offline, an instance of this class will regularly attempt to reconnect by recreating a new remote Tile Store instance.

The tile cache instance is never owned by an instance of this class. This means that the tile cache instance is not closed when the caching instance is closed. Tile stores that are retrieved from an ALfnTileStoreProvider must be closed by destroying the tile store provider instance.
In either case, the tile cache must not be in use by other clients.

It is a known limitation of this implementation that it ignores the modification time of a 'getTile' request. As a result, the implementation never returns "not modified", but always transfers the whole data, even if it has a modification time less than or equal to a modification time. In other words, the benefit of "conditional" 'getTile' requests is lost.

Since:
2013.0
  • Constructor Details

    • TLfnCachingTileStore

      public TLfnCachingTileStore(ALfnTileStoreProvider aTileStoreProvider, URI aTileStoreUri, ALfnTileStore aTileCache, long aLowMark, long aHighMark, long aExpirationDuration) throws TLfnServiceException, IOException
      Constructs an instance of this class, using a local Tile Store owned by the caller as tile cache.

      Closing this instance will close the remote Tile Store but not the tile cache, since it is owned by the caller.

      The tile cache (aTileCache) must not be in use by other clients.

      Parameters:
      aTileStoreProvider - the Tile Store provider which will be used to (re)create the Tile Store(s) from URI
      aTileStoreUri - the URI of the backing Tile Store
      aTileCache - the tile cache, which must be a TLfnFileSystemTileStore or a wrapper thereof. The tile cache instance will not be closed when this object is closed, it is the responsibility of the caller to close it. Must not be in use by other clients.
      aLowMark - the cache size's low mark, in bytes, which must be positive and strictly smaller than the high mark. This is the size the cache will be reduced to when the cache is swept. This is not a strict guarantee, it is more a guideline. Setting the low mark to a significantly smaller value than the high mark will result in less frequent sweeps, at the cost of falling back to nearly no cached tiles. A good trade-off typically involves a low mark that is at 75 % of the high mark. It makes no sense to set the low mark higher than 95 % of the high mark, because that would result in too frequent sweeps with little benefit. The system will guard itself against this by keeping at least a 5 % distance between the low and high mark.

      When using a high mark of Long.MAX_VALUE, the low mark is irrelevant and can be set to 0.

      aHighMark - the cache size's high mark, in bytes, which must be positive. When the cache size grows larger than the high mark, the oldest tiles will automatically be swept in an attempt to keep its size between the high and low mark. Because this sweeping is an asynchronous background process, there is no guarantee that the cache size will be between the low and high mark at all times. The marks are more guidelines than strict guarantees.

      For maximum flexibility when working offline, use Long.MAX_VALUE as high mark (when disk space is no issue).

      aExpirationDuration - the expiration duration of cached tiles in milliseconds. A low value yields cached tiles which are more up-to-date, at the expense of bandwidth: expired tiles will need to be reloaded from the remote Tile Store more often. Use a high value of one hour or more if you don't require up-to-date tiles. Use a low value of a couple of minutes or less if you require up-to-date tiles. For a Tile Store containing truly static tiles, you can even use Long.MAX_VALUE.
      Throws:
      TLfnServiceException
      IOException
    • TLfnCachingTileStore

      public TLfnCachingTileStore(ALfnTileStoreProvider aTileStoreProvider, URI aTileStoreUri, URI aTileCacheUri, long aLowMark, long aHighMark, long aExpirationDuration) throws IOException, TLfnServiceException
      Constructs an instance of this class, using a tile cache owned by the instance.

      Closing this instance will close both the remote Tile Store and the tile cache.

      The tile cache (aTileCacheUri) must not be in use by other clients.

      Parameters:
      aTileStoreProvider - a Tile Store provider from which both Tile Store and tile cache will be created. It must not be null.
      aTileStoreUri - the URI of the remote Tile Store, which must not be null
      aTileCacheUri - the URI of the tile cache, which must not be null. Must not be in use by other clients.
      aLowMark - the low mark
      aHighMark - the high mark
      aExpirationDuration - the expiration duration in milliseconds since epoch
      Throws:
      IOException - if creation of the tile cache or remote Tile Store failed
      TLfnServiceException - if creation of the tile cache or remote Tile Store failed
      See Also:
  • Method Details