Changeset 8307 in josm for trunk/src/org
- Timestamp:
- 2015-05-02T00:38:57+02:00 (9 years ago)
- Location:
- trunk/src/org/openstreetmap/josm
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/data/imagery/TMSCachedTileLoaderJob.java
r8286 r8307 6 6 import java.net.URL; 7 7 import java.util.Map; 8 import java.util.concurrent.ConcurrentHashMap; 8 9 import java.util.concurrent.Executor; 9 10 import java.util.concurrent.LinkedBlockingDeque; 11 import java.util.concurrent.Semaphore; 10 12 import java.util.concurrent.ThreadPoolExecutor; 11 13 import java.util.concurrent.TimeUnit; … … 20 22 import org.openstreetmap.gui.jmapviewer.interfaces.TileSource; 21 23 import org.openstreetmap.gui.jmapviewer.tilesources.AbstractTMSTileSource; 24 import org.openstreetmap.josm.Main; 22 25 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry; 23 26 import org.openstreetmap.josm.data.cache.CacheEntry; … … 42 45 */ 43 46 public static final IntegerProperty THREAD_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobs", 25); 47 48 /** 49 * Limit definition for per host concurrent connections 50 */ 51 public static final IntegerProperty HOST_LIMIT = new IntegerProperty("imagery.tms.tmsloader.maxjobsperhost", 6); 52 53 54 private static class LIFOQueue extends LinkedBlockingDeque<Runnable> { 55 public LIFOQueue(int capacity) { 56 super(capacity); 57 } 58 59 private final static Semaphore getSemaphore(Runnable r) { 60 if (!(r instanceof TMSCachedTileLoaderJob)) 61 return null; 62 TMSCachedTileLoaderJob cachedJob = (TMSCachedTileLoaderJob) r; 63 Semaphore limit = HOST_LIMITS.get(cachedJob.getUrl().getHost()); 64 if (limit == null) { 65 synchronized(HOST_LIMITS) { 66 limit = HOST_LIMITS.get(cachedJob.getUrl().getHost()); 67 if (limit == null) { 68 limit = new Semaphore(HOST_LIMIT.get().intValue()); 69 HOST_LIMITS.put(cachedJob.getUrl().getHost(), limit); 70 } 71 } 72 } 73 return limit; 74 } 75 76 private boolean acquireSemaphore(Runnable r) { 77 boolean ret = true; 78 Semaphore limit = getSemaphore(r); 79 if (limit != null) { 80 ret = limit.tryAcquire(); 81 if (!ret) { 82 Main.debug("rejecting job because of per host limit"); 83 } 84 } 85 return ret; 86 } 87 88 @Override 89 public boolean offer(Runnable t) { 90 return acquireSemaphore(t) && super.offerFirst(t); 91 } 92 93 private Runnable releaseSemaphore(Runnable r) { 94 Semaphore limit = getSemaphore(r); 95 if (limit != null) 96 limit.release(); 97 return r; 98 } 99 100 @Override 101 public Runnable remove() { 102 return releaseSemaphore(super.removeFirst()); 103 } 104 105 @Override 106 public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException { 107 return releaseSemaphore(super.poll(timeout, unit)); 108 } 109 110 @Override 111 public Runnable take() throws InterruptedException { 112 return releaseSemaphore(super.take()); 113 } 114 } 115 116 private static Map<String, Semaphore> HOST_LIMITS = new ConcurrentHashMap<>(); 117 44 118 /** 45 119 * separate from JCS thread pool for TMS loader, so we can have different thread pools for default JCS 46 120 * and for TMS imagery 47 121 */ 48 private static ThreadPoolExecutor DOWNLOAD_JOB_DISPATCHER = new ThreadPoolExecutor( 49 THREAD_LIMIT.get().intValue(), // keep the thread number constant 50 THREAD_LIMIT.get().intValue(), // do not this number of threads 51 30, // keepalive for thread 52 TimeUnit.SECONDS, 53 // make queue of LIFO type - so recently requested tiles will be loaded first (assuming that these are which user is waiting to see) 54 new LinkedBlockingDeque<Runnable>(5) { 55 /* keep the queue size fairly small, we do not want to 56 download a lot of tiles, that user is not seeing anyway */ 57 @Override 58 public boolean offer(Runnable t) { 59 return super.offerFirst(t); 60 } 61 62 @Override 63 public Runnable remove() { 64 return super.removeFirst(); 65 } 66 } 67 ); 122 private static ThreadPoolExecutor DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor(); 123 124 private static ThreadPoolExecutor getThreadPoolExecutor() { 125 return new ThreadPoolExecutor( 126 THREAD_LIMIT.get().intValue(), // keep the thread number constant 127 THREAD_LIMIT.get().intValue(), // do not this number of threads 128 30, // keepalive for thread 129 TimeUnit.SECONDS, 130 // make queue of LIFO type - so recently requested tiles will be loaded first (assuming that these are which user is waiting to see) 131 new LIFOQueue(5) 132 /* keep the queue size fairly small, we do not want to 133 download a lot of tiles, that user is not seeing anyway */ 134 ); 135 } 136 137 /** 138 * Reconfigures download dispatcher using current values of THREAD_LIMIT and HOST_LIMIT 139 */ 140 public static final void reconfigureDownloadDispatcher() { 141 HOST_LIMITS = new ConcurrentHashMap<>(); 142 DOWNLOAD_JOB_DISPATCHER = getThreadPoolExecutor(); 143 } 144 68 145 69 146 /** -
trunk/src/org/openstreetmap/josm/gui/preferences/imagery/TMSSettingsPanel.java
r8168 r8307 33 33 private final JSpinner maxElementsOnDisk; 34 34 private final JSpinner maxConcurrentDownloads; 35 private final JSpinner maxDownloadsPerHost; 35 36 36 37 … … 44 45 maxElementsOnDisk = new JSpinner(new SpinnerNumberModel(TMSCachedTileLoader.MAX_OBJECTS_ON_DISK.get().intValue(), 0, Integer.MAX_VALUE, 1)); 45 46 maxConcurrentDownloads = new JSpinner(new SpinnerNumberModel(TMSCachedTileLoaderJob.THREAD_LIMIT.get().intValue(), 0, Integer.MAX_VALUE, 1)); 47 maxDownloadsPerHost = new JSpinner(new SpinnerNumberModel(TMSCachedTileLoaderJob.HOST_LIMIT.get().intValue(), 0, Integer.MAX_VALUE, 1)); 46 48 47 49 add(new JLabel(tr("Auto zoom by default: ")), GBC.std()); … … 73 75 add(maxConcurrentDownloads, GBC.eol()); 74 76 77 add(new JLabel(tr("Maximum concurrent downloads per host: ")), GBC.std()); 78 add(GBC.glue(5, 0), GBC.std()); 79 add(maxDownloadsPerHost, GBC.eol()); 80 81 75 82 add(new JLabel(tr("Maximum elements in disk cache: ")), GBC.std()); 76 83 add(GBC.glue(5, 0), GBC.std()); … … 91 98 this.maxElementsOnDisk.setValue(TMSCachedTileLoader.MAX_OBJECTS_ON_DISK.get()); 92 99 this.maxConcurrentDownloads.setValue(TMSCachedTileLoaderJob.THREAD_LIMIT.get()); 100 this.maxDownloadsPerHost.setValue(TMSCachedTileLoaderJob.HOST_LIMIT.get()); 93 101 } 94 102 … … 111 119 TMSCachedTileLoader.MAX_OBJECTS_ON_DISK.put((Integer) this.maxElementsOnDisk.getValue()); 112 120 113 if (!TMSCachedTileLoaderJob.THREAD_LIMIT.get().equals(this.maxConcurrentDownloads.getValue())) { 114 restartRequired = true; 115 TMSCachedTileLoaderJob.THREAD_LIMIT.put((Integer) this.maxConcurrentDownloads.getValue()); 116 } 121 TMSCachedTileLoaderJob.THREAD_LIMIT.put((Integer) this.maxConcurrentDownloads.getValue()); 122 TMSCachedTileLoaderJob.HOST_LIMIT.put((Integer) this.maxDownloadsPerHost.getValue()); 123 TMSCachedTileLoaderJob.reconfigureDownloadDispatcher(); 117 124 118 125 if (!TMSLayer.PROP_TILECACHE_DIR.get().equals(this.tilecacheDir.getText())) {
Note:
See TracChangeset
for help on using the changeset viewer.