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

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

see #19334 - javadoc fixes + protected constructors for abstract classes

  • Property svn:eol-style set to native
File size: 6.0 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.jcs3.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 * Returns a new {@link ThreadPoolExecutor}.
66 * @param nameFormat see {@link Utils#newThreadFactory(String, int)}
67 * @param workers number of worker thread to keep
68 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
69 */
70 public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers) {
71 return getNewThreadPoolExecutor(nameFormat, workers, HOST_LIMIT.get().intValue());
72 }
73
74 /**
75 * Returns a new {@link ThreadPoolExecutor}.
76 * @param nameFormat see {@link Utils#newThreadFactory(String, int)}
77 * @param workers number of worker thread to keep
78 * @param hostLimit number of concurrent downloads per host allowed
79 * @return new ThreadPoolExecutor that will use a @see HostLimitQueue based queue
80 */
81 public static ThreadPoolExecutor getNewThreadPoolExecutor(String nameFormat, int workers, int hostLimit) {
82 return new ThreadPoolExecutor(
83 workers, // keep core pool the same size as max, as we use unbounded queue so there will
84 workers, // be never more threads than corePoolSize
85 300, // keep alive for thread
86 TimeUnit.SECONDS,
87 new HostLimitQueue(hostLimit),
88 Utils.newThreadFactory(nameFormat, Thread.NORM_PRIORITY)
89 );
90 }
91
92 /**
93 * Returns a new {@link ThreadPoolExecutor}.
94 * @param name name of threads
95 * @return new ThreadPoolExecutor that will use a {@link HostLimitQueue} based queue, with default number of threads
96 */
97 public static ThreadPoolExecutor getNewThreadPoolExecutor(String name) {
98 return getNewThreadPoolExecutor(name, THREAD_LIMIT.get().intValue());
99 }
100
101 @Override
102 public TileJob createTileLoaderJob(Tile tile) {
103 return new TMSCachedTileLoaderJob(
104 listener,
105 tile,
106 cache,
107 options,
108 getDownloadExecutor());
109 }
110
111 @Override
112 public void clearCache(TileSource source) {
113 this.cache.remove(source.getName() + ':');
114 }
115
116 /**
117 * Returns cache statistics as string.
118 * @return cache statistics as string
119 */
120 public String getStats() {
121 return cache.getStats();
122 }
123
124 /**
125 * cancels all outstanding tasks in the queue. This rollbacks the state of the tiles in the queue
126 * to loading = false / loaded = false
127 */
128 @Override
129 public void cancelOutstandingTasks() {
130 for (Runnable r: downloadExecutor.getQueue()) {
131 if (downloadExecutor.remove(r) && r instanceof TMSCachedTileLoaderJob) {
132 ((TMSCachedTileLoaderJob) r).handleJobCancellation();
133 }
134 }
135 }
136
137 @Override
138 public boolean hasOutstandingTasks() {
139 return downloadExecutor.getTaskCount() > downloadExecutor.getCompletedTaskCount();
140 }
141
142 /**
143 * Sets the download executor that will be used to download tiles instead of default one.
144 * You can use {@link #getNewThreadPoolExecutor} to create a new download executor with separate
145 * queue from default.
146 *
147 * @param downloadExecutor download executor that will be used to download tiles
148 */
149 public void setDownloadExecutor(ThreadPoolExecutor downloadExecutor) {
150 this.downloadExecutor = downloadExecutor;
151 }
152
153 /**
154 * Returns download executor that is used by this factory.
155 * @return download executor that is used by this factory
156 */
157 public ThreadPoolExecutor getDownloadExecutor() {
158 return downloadExecutor;
159 }
160}
Note: See TracBrowser for help on using the repository browser.