source: josm/trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoader.java@ 14624

Last change on this file since 14624 was 14624, checked in by Don-vip, 5 years ago

fix various SonarQube issues

  • Property svn:eol-style set to native
File size: 5.8 KB
Line 
1// License: GPL. For details, see LICENSE file.
2package org.openstreetmap.josm.data.imagery;
3
4import java.util.concurrent.ThreadPoolExecutor;
5import java.util.concurrent.TimeUnit;
6
7import org.apache.commons.jcs.access.behavior.ICacheAccess;
8import org.openstreetmap.gui.jmapviewer.Tile;
9import org.openstreetmap.gui.jmapviewer.interfaces.CachedTileLoader;
10import org.openstreetmap.gui.jmapviewer.interfaces.TileJob;
11import org.openstreetmap.gui.jmapviewer.interfaces.TileLoader;
12import org.openstreetmap.gui.jmapviewer.interfaces.TileLoaderListener;
13import org.openstreetmap.gui.jmapviewer.interfaces.TileSource;
14import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;
15import org.openstreetmap.josm.data.cache.HostLimitQueue;
16import org.openstreetmap.josm.data.preferences.IntegerProperty;
17import org.openstreetmap.josm.tools.CheckParameterUtil;
18import org.openstreetmap.josm.tools.Utils;
19
20/**
21 * Wrapper class that bridges between JCS cache and Tile Loaders
22 *
23 * @author Wiktor Niesiobędzki
24 */
25public class TMSCachedTileLoader implements TileLoader, CachedTileLoader {
26
27 protected final ICacheAccess<String, BufferedImageCacheEntry> cache;
28 protected final TileLoaderListener listener;
29
30 /**
31 * overrides the THREAD_LIMIT in superclass, as we want to have separate limit and pool for TMS
32 */
33
34 public static final IntegerProperty THREAD_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobs", 25);
35
36 /**
37 * Limit definition for per host concurrent connections
38 */
39 public static final IntegerProperty HOST_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobsperhost", 6);
40
41 /**
42 * separate from JCS thread pool for TMS loader, so we can have different thread pools for default JCS
43 * and for TMS imagery
44 */
45 private static final ThreadPoolExecutor DEFAULT_DOWNLOAD_JOB_DISPATCHER = getNewThreadPoolExecutor("TMS-downloader-%d");
46
47 private ThreadPoolExecutor downloadExecutor = DEFAULT_DOWNLOAD_JOB_DISPATCHER;
48 protected final TileJobOptions options;
49
50 /**
51 * Constructor
52 * @param listener called when tile loading has finished
53 * @param cache of the cache
54 * @param options tile job options
55 */
56 public TMSCachedTileLoader(TileLoaderListener listener, ICacheAccess<String, BufferedImageCacheEntry> cache,
57 TileJobOptions options) {
58 CheckParameterUtil.ensureParameterNotNull(cache, "cache");
59 this.cache = cache;
60 this.options = options;
61 this.listener = listener;
62 }
63
64 /**
65 * @param nameFormat see {@link Utils#newThreadFactory(String, int)}
66 * @param workers number of worker thread to keep
67 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
68 */
69 public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers) {
70 return getNewThreadPoolExecutor(nameFormat, workers, HOST_LIMIT.get().intValue());
71 }
72
73 /**
74 * @param nameFormat see {@link Utils#newThreadFactory(String, int)}
75 * @param workers number of worker thread to keep
76 * @param hostLimit number of concurrent downloads per host allowed
77 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
78 */
79 public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers, int hostLimit) {
80 return new ThreadPoolExecutor(
81 workers, // keep core pool the same size as max, as we use unbounded queue so there will
82 workers, // be never more threads than corePoolSize
83 300, // keep alive for thread
84 TimeUnit.SECONDS,
85 new HostLimitQueue(hostLimit),
86 Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
87 );
88 }
89
90 /**
91 * @param name name of threads
92 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue, with default number of threads
93 */
94 public static ThreadPoolExecutor getNewThreadPoolExecutor(String name) {
95 return getNewThreadPoolExecutor(name, THREAD_LIMIT.get().intValue());
96 }
97
98 @Override
99 public TileJob createTileLoaderJob(Tile tile) {
100 return new TMSCachedTileLoaderJob(
101 listener,
102 tile,
103 cache,
104 options,
105 getDownloadExecutor());
106 }
107
108 @Override
109 public void clearCache(TileSource source) {
110 this.cache.remove(source.getName() + ':');
111 }
112
113 /**
114 * @return cache statistics as string
115 */
116 public String getStats() {
117 return cache.getStats();
118 }
119
120 /**
121 * cancels all outstanding tasks in the queue. This rollbacks the state of the tiles in the queue
122 * to loading = false / loaded = false
123 */
124 @Override
125 public void cancelOutstandingTasks() {
126 for (Runnable r: downloadExecutor.getQueue()) {
127 if (downloadExecutor.remove(r) && r instanceof TMSCachedTileLoaderJob) {
128 ((TMSCachedTileLoaderJob) r).handleJobCancellation();
129 }
130 }
131 }
132
133 @Override
134 public boolean hasOutstandingTasks() {
135 return downloadExecutor.getTaskCount() > downloadExecutor.getCompletedTaskCount();
136 }
137
138 /**
139 * Sets the download executor that will be used to download tiles instead of default one.
140 * You can use {@link #getNewThreadPoolExecutor} to create a new download executor with separate
141 * queue from default.
142 *
143 * @param downloadExecutor download executor that will be used to download tiles
144 */
145 public void setDownloadExecutor(ThreadPoolExecutor downloadExecutor) {
146 this.downloadExecutor = downloadExecutor;
147 }
148
149 /**
150 * @return download executor that is used by this factory
151 */
152 public ThreadPoolExecutor getDownloadExecutor() {
153 return downloadExecutor;
154 }
155}
Note: See TracBrowser for help on using the repository browser.