Changeset 17369 in josm
- Timestamp:
- 2020-11-27T22:45:55+01:00 (4 years ago)
- Location:
- trunk
- Files:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/com/kitfox/svg/SVGUniverse.java
r17364 r17369 693 693 this.imageDataInlineOnly = imageDataInlineOnly; 694 694 } 695 696 public String statistics() {697 return String.format("%s has loaded %d SVG images", this, loadedDocs.size());698 }699 700 695 } -
trunk/src/org/openstreetmap/josm/data/cache/JCSCacheManager.java
r17364 r17369 31 31 import org.openstreetmap.josm.data.preferences.IntegerProperty; 32 32 import org.openstreetmap.josm.spi.preferences.Config; 33 import org.openstreetmap.josm.tools.ImageResource;34 33 import org.openstreetmap.josm.tools.Logging; 35 34 import org.openstreetmap.josm.tools.Utils; … … 46 45 private static final String PREFERENCE_PREFIX = "jcs.cache"; 47 46 public static final BooleanProperty USE_BLOCK_CACHE = new BooleanProperty(PREFERENCE_PREFIX + ".use_block_cache", true); 48 49 /**50 * The preference key {@code jcs.cache.use_image_resource_cache} controls the caching mechanism used for {@link ImageResource}.51 * If set to {@code true}, a combined memory/disk is used. Otherwise, an in-memory-cache is used.52 */53 public static final BooleanProperty USE_IMAGE_RESOURCE_CACHE = new BooleanProperty(PREFERENCE_PREFIX + ".use_image_resource_cache", false);54 47 55 48 private static final AuxiliaryCacheFactory DISK_CACHE_FACTORY = … … 178 171 * @return cache access object 179 172 */ 173 @SuppressWarnings("unchecked") 180 174 public static <K, V> CacheAccess<K, V> getCache(String cacheName, int maxMemoryObjects, int maxDiskObjects, String cachePath) { 181 return getCache(cacheName, maxMemoryObjects, maxDiskObjects, cachePath, USE_BLOCK_CACHE.get() ? 4096 : 0);182 }183 184 @SuppressWarnings("unchecked")185 private static <K, V> CacheAccess<K, V> getCache(String cacheName, int maxMemoryObjects, int maxDiskObjects,186 String cachePath, int blockSizeBytes) {187 175 CacheAccess<K, V> cacheAccess = JCS.getInstance(cacheName, getCacheAttributes(maxMemoryObjects)); 188 176 CompositeCache<K, V> cc = cacheAccess.getCacheControl(); 189 177 190 178 if (cachePath != null && cacheDirLock != null) { 191 IDiskCacheAttributes diskAttributes = getDiskCacheAttributes(maxDiskObjects, cachePath, cacheName, blockSizeBytes); 192 Logging.debug("Setting up cache: {0}", diskAttributes); 179 IDiskCacheAttributes diskAttributes = getDiskCacheAttributes(maxDiskObjects, cachePath, cacheName); 193 180 try { 194 181 if (cc.getAuxCaches().length == 0) { … … 206 193 207 194 /** 208 * Returns a cache for {@link ImageResource}209 * @param <K> key type210 * @param <V> value type211 * @return cache access object212 */213 public static <K, V> CacheAccess<K, V> getImageResourceCache() {214 if (!USE_IMAGE_RESOURCE_CACHE.get()) {215 return getCache("images", 16 * 1024, 0, null);216 }217 String cachePath = new File(Config.getDirs().getCacheDirectory(true), "images").getAbsolutePath();218 Logging.warn("Using experimental disk cache {0} for ImageResource", cachePath);219 return getCache("images", 16 * 1024, 512 * 1024, cachePath, 1024);220 }221 222 /**223 195 * Close all files to ensure, that all indexes and data are properly written 224 196 */ … … 227 199 } 228 200 229 private static IDiskCacheAttributes getDiskCacheAttributes(int maxDiskObjects, String cachePath, String cacheName , int blockSizeBytes) {201 private static IDiskCacheAttributes getDiskCacheAttributes(int maxDiskObjects, String cachePath, String cacheName) { 230 202 IDiskCacheAttributes ret; 231 boolean isBlockDiskCache = blockSizeBytes > 0; 232 removeStaleFiles(cachePath + File.separator + cacheName, isBlockDiskCache ? "_INDEX_v2" : "_BLOCK_v2"); 233 String newCacheName = cacheName + (isBlockDiskCache ? "_BLOCK_v2" : "_INDEX_v2"); 234 235 if (isBlockDiskCache) { 203 removeStaleFiles(cachePath + File.separator + cacheName, USE_BLOCK_CACHE.get() ? "_INDEX_v2" : "_BLOCK_v2"); 204 String newCacheName = cacheName + (USE_BLOCK_CACHE.get() ? "_BLOCK_v2" : "_INDEX_v2"); 205 206 if (USE_BLOCK_CACHE.get()) { 236 207 BlockDiskCacheAttributes blockAttr = new BlockDiskCacheAttributes(); 237 208 /* … … 247 218 blockAttr.setMaxKeySize(maxDiskObjects); 248 219 } 249 blockAttr.setBlockSizeBytes( blockSizeBytes);220 blockAttr.setBlockSizeBytes(4096); // use 4k blocks 250 221 ret = blockAttr; 251 222 } else { -
trunk/src/org/openstreetmap/josm/gui/MainInitialization.java
r17364 r17369 153 153 MainApplication.toolbar.control.updateUI(); 154 154 MainApplication.contentPanePrivate.updateUI(); 155 // image provider statistics156 ImageProvider.printStatistics();157 155 })) 158 156 ); -
trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
r17364 r17369 954 954 continue; 955 955 } 956 ir = getIfAvailableLocalURL( subdir + name,path, type);956 ir = getIfAvailableLocalURL(path, type); 957 957 if (ir != null) { 958 958 cache.put(cacheName, ir); … … 984 984 svg = getSvgUniverse().getDiagram(uri); 985 985 } 986 return svg == null ? null : new ImageResource( url,svg);986 return svg == null ? null : new ImageResource(svg); 987 987 case OTHER: 988 988 BufferedImage img = null; … … 992 992 Logging.log(Logging.LEVEL_WARN, "Exception while reading HTTP image:", e); 993 993 } 994 return img == null ? null : new ImageResource( url,img);994 return img == null ? null : new ImageResource(img); 995 995 default: 996 996 throw new AssertionError("Unsupported type: " + type); … … 1041 1041 return null; 1042 1042 } 1043 return new ImageResource( url,svg);1043 return new ImageResource(svg); 1044 1044 } else { 1045 1045 try { … … 1050 1050 // CHECKSTYLE.ON: LineLength 1051 1051 Image img = read(new ByteArrayInputStream(bytes), false, true); 1052 return img == null ? null : new ImageResource( url,img);1052 return img == null ? null : new ImageResource(img); 1053 1053 } catch (IOException | UnsatisfiedLinkError e) { 1054 1054 Logging.log(Logging.LEVEL_WARN, "Exception while reading image:", e); … … 1125 1125 svg = getSvgUniverse().getDiagram(uri); 1126 1126 } 1127 return svg == null ? null : new ImageResource( fullName,svg);1127 return svg == null ? null : new ImageResource(svg); 1128 1128 case OTHER: 1129 1129 while (size > 0) { … … 1138 1138 Logging.warn(e); 1139 1139 } 1140 return img == null ? null : new ImageResource( fullName,img);1140 return img == null ? null : new ImageResource(img); 1141 1141 default: 1142 1142 throw new AssertionError("Unknown ImageType: "+type); … … 1157 1157 * @return the requested image or null if the request failed 1158 1158 */ 1159 private static ImageResource getIfAvailableLocalURL( String cacheKey,URL path, ImageType type) {1159 private static ImageResource getIfAvailableLocalURL(URL path, ImageType type) { 1160 1160 switch (type) { 1161 1161 case SVG: 1162 return new ImageResource(cacheKey, () -> { 1163 synchronized (getSvgUniverse()) { 1162 SVGDiagram svg = null; 1163 synchronized (getSvgUniverse()) { 1164 try { 1165 URI uri = null; 1164 1166 try { 1165 URI uri = null; 1166 try { 1167 uri = getSvgUniverse().loadSVG(path); 1168 } catch (InvalidPathException e) { 1169 Logging.error("Cannot open {0}: {1}", path, e.getMessage()); 1170 Logging.trace(e); 1167 uri = getSvgUniverse().loadSVG(path); 1168 } catch (InvalidPathException e) { 1169 Logging.error("Cannot open {0}: {1}", path, e.getMessage()); 1170 Logging.trace(e); 1171 } 1172 if (uri == null && "jar".equals(path.getProtocol())) { 1173 URL betterPath = Utils.betterJarUrl(path); 1174 if (betterPath != null) { 1175 uri = getSvgUniverse().loadSVG(betterPath); 1171 1176 } 1172 if (uri == null && "jar".equals(path.getProtocol())) {1173 URL betterPath = Utils.betterJarUrl(path);1174 if (betterPath != null) {1175 uri = getSvgUniverse().loadSVG(betterPath);1176 }1177 }1178 return getSvgUniverse().getDiagram(uri);1179 } catch (SecurityException | IOException e) {1180 Logging.log(Logging.LEVEL_WARN, "Unable to read SVG", e);1181 1177 } 1182 } 1183 return null; 1184 }); 1178 svg = getSvgUniverse().getDiagram(uri); 1179 } catch (SecurityException | IOException e) { 1180 Logging.log(Logging.LEVEL_WARN, "Unable to read SVG", e); 1181 } 1182 } 1183 return svg == null ? null : new ImageResource(svg); 1185 1184 case OTHER: 1186 1185 BufferedImage img = null; … … 1197 1196 Logging.debug(e); 1198 1197 } 1199 return img == null ? null : new ImageResource( path.toString(),img);1198 return img == null ? null : new ImageResource(img); 1200 1199 default: 1201 1200 throw new AssertionError(); … … 1395 1394 */ 1396 1395 public static Image createBoundedImage(Image img, int maxSize) { 1397 return new ImageResource(img .toString(), img).getImageIconBounded(new Dimension(maxSize, maxSize)).getImage();1396 return new ImageResource(img).getImageIconBounded(new Dimension(maxSize, maxSize)).getImage(); 1398 1397 } 1399 1398 … … 1934 1933 } 1935 1934 1936 /**1937 * Prints statistics concerning the image loading caches.1938 */1939 public static void printStatistics() {1940 Logging.info(getSvgUniverse().statistics());1941 Logging.info(ImageResource.statistics());1942 }1943 1944 1935 @Override 1945 1936 public String toString() { -
trunk/src/org/openstreetmap/josm/tools/ImageResource.java
r17364 r17369 5 5 import java.awt.Image; 6 6 import java.awt.image.BufferedImage; 7 import java.io.IOException;8 import java.io.UncheckedIOException;9 7 import java.util.List; 10 import java.util.Locale; 11 import java.util.Objects; 12 import java.util.function.Supplier; 8 import java.util.Map; 9 import java.util.concurrent.ConcurrentHashMap; 13 10 14 11 import javax.swing.AbstractAction; … … 18 15 import javax.swing.JPanel; 19 16 import javax.swing.UIManager; 20 21 import org.apache.commons.jcs3.access.behavior.ICacheAccess;22 import org.openstreetmap.josm.data.cache.BufferedImageCacheEntry;23 import org.openstreetmap.josm.data.cache.JCSCacheManager;24 17 25 18 import com.kitfox.svg.SVGDiagram; … … 36 29 37 30 /** 38 * Caches the image data for resized versions of the same image. 39 * Depending on {@link JCSCacheManager#USE_IMAGE_RESOURCE_CACHE}, a combined memory/disk, or an in-memory-cache is used. 40 */ 41 private static final ICacheAccess<String, BufferedImageCacheEntry> imgCache = JCSCacheManager.getImageResourceCache(); 42 43 private final String cacheKey; 31 * Caches the image data for resized versions of the same image. The key is obtained using {@link ImageResizeMode#cacheKey(Dimension)}. 32 */ 33 private final Map<Integer, BufferedImage> imgCache = new ConcurrentHashMap<>(4); 44 34 /** 45 35 * SVG diagram information in case of SVG vector image. … … 47 37 private SVGDiagram svg; 48 38 /** 49 * Supplier for SVG diagram information in case of possibly cached SVG vector image.50 */51 private Supplier<SVGDiagram> svgSupplier;52 /**53 39 * Use this dimension to request original file dimension. 54 40 */ … … 69 55 /** 70 56 * Constructs a new {@code ImageResource} from an image. 71 * @param cacheKey the caching identifier of the image72 57 * @param img the image 73 58 */ 74 public ImageResource( String cacheKey,Image img) {75 this.cacheKey = Objects.requireNonNull(cacheKey);76 this.baseImage =Objects.requireNonNull(img);59 public ImageResource(Image img) { 60 CheckParameterUtil.ensureParameterNotNull(img); 61 baseImage = img; 77 62 } 78 63 79 64 /** 80 65 * Constructs a new {@code ImageResource} from SVG data. 81 * @param cacheKey the caching identifier of the image82 66 * @param svg SVG data 83 67 */ 84 public ImageResource(String cacheKey, SVGDiagram svg) { 85 this.cacheKey = Objects.requireNonNull(cacheKey); 86 this.svg = Objects.requireNonNull(svg); 87 } 88 89 public ImageResource(String cacheKey, Supplier<SVGDiagram> svgSupplier) { 90 this.cacheKey = Objects.requireNonNull(cacheKey); 91 this.svgSupplier = Objects.requireNonNull(svgSupplier); 68 public ImageResource(SVGDiagram svg) { 69 CheckParameterUtil.ensureParameterNotNull(svg); 70 this.svg = svg; 92 71 } 93 72 … … 99 78 */ 100 79 public ImageResource(ImageResource res, List<ImageOverlay> overlayInfo) { 101 this.cacheKey = res.cacheKey;102 80 this.svg = res.svg; 103 this.svgSupplier = res.svgSupplier;104 81 this.baseImage = res.baseImage; 105 82 this.overlayInfo = overlayInfo; … … 180 157 ImageIcon getImageIcon(Dimension dim, boolean multiResolution, ImageResizeMode resizeMode) { 181 158 return getImageIconAlreadyScaled(GuiSizesHelper.getDimensionDpiAdjusted(dim), multiResolution, false, resizeMode); 182 }183 184 private BufferedImage getImageFromCache(String cacheKey) {185 try {186 BufferedImageCacheEntry image = imgCache.get(cacheKey);187 if (image == null || image.getImage() == null) {188 return null;189 }190 Logging.trace("{0} is in cache :-)", cacheKey);191 return image.getImage();192 } catch (IOException e) {193 throw new UncheckedIOException(e);194 }195 159 } 196 160 … … 217 181 resizeMode = ImageResizeMode.BOUNDED; 218 182 } 219 final String cacheKey = String.format(Locale.ROOT, "%s--%s--%d--%d", 220 this.cacheKey, resizeMode.name(), dim.width, dim.height); 221 BufferedImage img = getImageFromCache(cacheKey); 183 final int cacheKey = resizeMode.cacheKey(dim); 184 BufferedImage img = imgCache.get(cacheKey); 222 185 if (img == null) { 223 if (svgSupplier != null) {224 svg = svgSupplier.get();225 Logging.trace("{0} is not in cache :-(", cacheKey);226 svgSupplier = null;227 }228 186 if (svg != null) { 229 187 img = ImageProvider.createImageFromSvg(svg, dim, resizeMode); … … 253 211 disabledIcon.paintIcon(new JPanel(), img.getGraphics(), 0, 0); 254 212 } 255 if (img == null) { 256 return null; 257 } 258 BufferedImageCacheEntry cacheEntry = BufferedImageCacheEntry.pngEncoded(img); 259 Logging.trace("Storing {0} ({1} bytes) in cache...", cacheKey, cacheEntry.getContent().length); 260 imgCache.put(cacheKey, cacheEntry); 213 imgCache.put(cacheKey, img); 261 214 } 262 215 … … 298 251 } 299 252 300 static String statistics() {301 return String.format("ImageResource cache: [%s]", imgCache.getStatistics());302 }303 304 253 @Override 305 254 public String toString() { -
trunk/test/unit/org/openstreetmap/josm/gui/tagging/presets/TaggingPresetReaderTest.java
r17364 r17369 90 90 */ 91 91 @Test 92 void testReadDefaul tPresets() throws SAXException, IOException {92 void testReadDefaulPresets() throws SAXException, IOException { 93 93 String presetfile = "resource://data/defaultpresets.xml"; 94 94 final Collection<TaggingPreset> presets = TaggingPresetReader.readAll(presetfile, true); 95 95 Assert.assertTrue("Default presets are empty", presets.size() > 0); 96 TaggingPresetsTest.waitForIconLoading(presets);97 96 } 98 97 }
Note:
See TracChangeset
for help on using the changeset viewer.