source: josm/trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java@ 17486

Last change on this file since 17486 was 17486, checked in by GerdP, 3 years ago

see #20014: Tiles constantly reloading

  • change synchronization a bit. No idea if it helps.
  • simplify code
  • Property svn:eol-style set to native
File size: 4.9 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.gui.layer;
3
4import java.util.Map;
5import java.util.concurrent.ConcurrentHashMap;
6
7import org.apache.commons.jcs3.access.CacheAccess;
8import org.apache.commons.jcs3.access.behavior.ICacheAccess;
9import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
10import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource;
11import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
12import org.openstreetmap.josm.data.cache.JCSCacheManager;
13import org.openstreetmap.josm.data.imagery.CachedTileLoaderFactory;
14import org.openstreetmap.josm.data.imagery.ImageryInfo;
15import org.openstreetmap.josm.data.imagery.TileLoaderFactory;
16import org.openstreetmap.josm.data.preferences.IntegerProperty;
17
18/**
19 *
20 * Class providing cache to other layers
21 *
22 * @author Wiktor Niesiobędzki
23 * @param <T> Tile Source class used by this Imagery Layer
24 *
25 */
26public abstract class AbstractCachedTileSourceLayer<T extends AbstractTMSTileSource> extends AbstractTileSourceLayer<T> {
27 /** loader factory responsible for loading tiles for all layers */
28 private static final Map<String, TileLoaderFactory> loaderFactories = new ConcurrentHashMap<>();
29
30 private static final String PREFERENCE_PREFIX = "imagery.cache.";
31
32 private static volatile TileLoaderFactory loaderFactoryOverride;
33
34 /**
35 * how many object on disk should be stored for TMS region in MB. 500 MB is default value
36 */
37 public static final IntegerProperty MAX_DISK_CACHE_SIZE = new IntegerProperty(PREFERENCE_PREFIX + "max_disk_size", 512);
38
39 private ICacheAccess<String, BufferedImageCacheEntry> cache;
40 private volatile TileLoaderFactory loaderFactory;
41
42 /**
43 * Creates an instance of class based on ImageryInfo
44 *
45 * @param info ImageryInfo describing the layer
46 */
47 protected AbstractCachedTileSourceLayer(ImageryInfo info) {
48 super(info);
49
50 if (loaderFactoryOverride != null) {
51 loaderFactory = loaderFactoryOverride;
52 } else {
53 String key = this.getClass().getCanonicalName();
54 loaderFactory = loaderFactories.get(key);
55 synchronized (AbstractCachedTileSourceLayer.class) {
56 if (loaderFactory == null) {
57 // check again, maybe another thread initialized factory
58 loaderFactory = loaderFactories.get(key);
59 if (loaderFactory == null) {
60 loaderFactory = new CachedTileLoaderFactory(getCache(), getTileLoaderClass());
61 loaderFactories.put(key, loaderFactory);
62 }
63 }
64 }
65 }
66 }
67
68 @Override
69 protected synchronized TileLoaderFactory getTileLoaderFactory() {
70 if (loaderFactory == null) {
71 loaderFactory = new CachedTileLoaderFactory(getCache(), getTileLoaderClass());
72 }
73 return loaderFactory;
74 }
75
76 /**
77 * @return cache used by this layer
78 */
79 private synchronized ICacheAccess<String, BufferedImageCacheEntry> getCache() {
80 if (cache == null) {
81 cache = JCSCacheManager.getCache(getCacheName(),
82 0,
83 getDiskCacheSize(),
84 CachedTileLoaderFactory.PROP_TILECACHE_DIR.get());
85 }
86 return cache;
87 }
88
89 /**
90 * Plugins that wish to set custom tile loader should call this method
91 * @param newLoaderFactory that will be used to load tiles
92 */
93
94 public static synchronized void setTileLoaderFactory(TileLoaderFactory newLoaderFactory) {
95 loaderFactoryOverride = newLoaderFactory;
96 }
97
98 /**
99 * Returns tile loader factory for cache region and specified TileLoader class
100 * @param name of the cache region
101 * @param klazz type of the TileLoader
102 * @return factory returning cached tile loaders using specified cache and TileLoaders
103 */
104 public static TileLoaderFactory getTileLoaderFactory(String name, Class<? extends TileLoader> klazz) {
105 CacheAccess<String, BufferedImageCacheEntry> cache = getCache(name);
106 if (cache == null) {
107 return null;
108 }
109 return new CachedTileLoaderFactory(cache, klazz);
110 }
111
112 /**
113 * Returns cache configured object for specified cache region.
114 * @param name of cache region
115 * @return cache configured object for specified cache region
116 */
117 public static CacheAccess<String, BufferedImageCacheEntry> getCache(String name) {
118 return JCSCacheManager.getCache(name,
119 0,
120 MAX_DISK_CACHE_SIZE.get() * 1024, // MAX_DISK_CACHE_SIZE is in MB, needs to by in sync with getDiskCacheSize
121 CachedTileLoaderFactory.PROP_TILECACHE_DIR.get());
122 }
123
124 protected abstract Class<? extends TileLoader> getTileLoaderClass();
125
126 protected int getDiskCacheSize() {
127 return MAX_DISK_CACHE_SIZE.get() * 1024;
128 }
129
130 protected abstract String getCacheName();
131}
Note: See TracBrowser for help on using the repository browser.