Ticket #18534: 18534.synchronizedMap.patch

File 18534.synchronizedMap.patch, 9.3 KB (added by taylor.smock, 6 years ago)

Using a synchronizedMap

  • src/org/openstreetmap/josm/tools/ImageProvider.java

     
    3434import java.util.Arrays;
    3535import java.util.Base64;
    3636import java.util.Collection;
     37import java.util.Collections;
    3738import java.util.EnumMap;
    3839import java.util.HashMap;
    3940import java.util.Hashtable;
     
    295296    /**
    296297     * The icon cache
    297298     */
    298     private static final Map<String, ImageResource> cache = new HashMap<>();
     299    private static final Map<String, ImageResource> cache = Collections.synchronizedMap(new HashMap<>());
    299300
    300301    /**
    301302     * Caches the image data for rotated versions of the same image.
     
    835836     * @since 11021
    836837     */
    837838    public static void clearCache() {
    838         synchronized (cache) {
    839             cache.clear();
    840         }
     839        cache.clear();
    841840        synchronized (ROTATE_CACHE) {
    842841            ROTATE_CACHE.clear();
    843842        }
     
    855854     * @return the requested image or null if the request failed
    856855     */
    857856    private ImageResource getIfAvailableImpl() {
    858         synchronized (cache) {
    859             // This method is called from different thread and modifying HashMap concurrently can result
    860             // for example in loops in map entries (ie freeze when such entry is retrieved)
     857        // This method is called from different thread and modifying HashMap
     858        // concurrently can result for example in loops in map entries (ie freeze when
     859        // such entry is retrieved)
    861860
    862             String prefix = isDisabled ? "dis:" : "";
    863             if (name.startsWith("data:")) {
    864                 String url = name;
    865                 ImageResource ir = cache.get(prefix+url);
    866                 if (ir != null) return ir;
    867                 ir = getIfAvailableDataUrl(url);
    868                 if (ir != null) {
    869                     cache.put(prefix+url, ir);
    870                 }
     861        String prefix = isDisabled ? "dis:" : "";
     862        if (name.startsWith("data:")) {
     863            String url = name;
     864            ImageResource ir = cache.get(prefix + url);
     865            if (ir != null)
    871866                return ir;
     867            ir = getIfAvailableDataUrl(url);
     868            if (ir != null) {
     869                cache.put(prefix + url, ir);
    872870            }
     871            return ir;
     872        }
    873873
    874             ImageType type = Utils.hasExtension(name, "svg") ? ImageType.SVG : ImageType.OTHER;
     874        ImageType type = Utils.hasExtension(name, "svg") ? ImageType.SVG : ImageType.OTHER;
    875875
    876             if (name.startsWith(HTTP_PROTOCOL) || name.startsWith(HTTPS_PROTOCOL)) {
    877                 String url = name;
    878                 ImageResource ir = cache.get(prefix+url);
    879                 if (ir != null) return ir;
    880                 ir = getIfAvailableHttp(url, type);
    881                 if (ir != null) {
    882                     cache.put(prefix+url, ir);
    883                 }
     876        if (name.startsWith(HTTP_PROTOCOL) || name.startsWith(HTTPS_PROTOCOL)) {
     877            String url = name;
     878            ImageResource ir = cache.get(prefix + url);
     879            if (ir != null)
    884880                return ir;
    885             } else if (name.startsWith(WIKI_PROTOCOL)) {
    886                 ImageResource ir = cache.get(prefix+name);
    887                 if (ir != null) return ir;
    888                 ir = getIfAvailableWiki(name, type);
    889                 if (ir != null) {
    890                     cache.put(prefix+name, ir);
    891                 }
     881            ir = getIfAvailableHttp(url, type);
     882            if (ir != null) {
     883                cache.put(prefix + url, ir);
     884            }
     885            return ir;
     886        } else if (name.startsWith(WIKI_PROTOCOL)) {
     887            ImageResource ir = cache.get(prefix + name);
     888            if (ir != null)
    892889                return ir;
     890            ir = getIfAvailableWiki(name, type);
     891            if (ir != null) {
     892                cache.put(prefix + name, ir);
    893893            }
     894            return ir;
     895        }
    894896
    895             if (subdir == null) {
    896                 subdir = "";
    897             } else if (!subdir.isEmpty() && !subdir.endsWith("/")) {
    898                 subdir += '/';
    899             }
    900             String[] extensions;
    901             if (name.indexOf('.') != -1) {
    902                 extensions = new String[] {""};
    903             } else {
    904                 extensions = new String[] {".png", ".svg"};
    905             }
    906             final int typeArchive = 0;
    907             final int typeLocal = 1;
    908             for (int place : new Integer[] {typeArchive, typeLocal}) {
    909                 for (String ext : extensions) {
     897        if (subdir == null) {
     898            subdir = "";
     899        } else if (!subdir.isEmpty() && !subdir.endsWith("/")) {
     900            subdir += '/';
     901        }
     902        String[] extensions;
     903        if (name.indexOf('.') != -1) {
     904            extensions = new String[] { "" };
     905        } else {
     906            extensions = new String[] { ".png", ".svg" };
     907        }
     908        final int typeArchive = 0;
     909        final int typeLocal = 1;
     910        for (int place : new Integer[] { typeArchive, typeLocal }) {
     911            for (String ext : extensions) {
    910912
    911                     if (".svg".equals(ext)) {
    912                         type = ImageType.SVG;
    913                     } else if (".png".equals(ext)) {
    914                         type = ImageType.OTHER;
    915                     }
     913                if (".svg".equals(ext)) {
     914                    type = ImageType.SVG;
     915                } else if (".png".equals(ext)) {
     916                    type = ImageType.OTHER;
     917                }
    916918
    917                     String fullName = subdir + name + ext;
    918                     String cacheName = prefix + fullName;
    919                     /* cache separately */
    920                     if (dirs != null && !dirs.isEmpty()) {
    921                         cacheName = "id:" + id + ':' + fullName;
    922                         if (archive != null) {
    923                             cacheName += ':' + archive.getName();
    924                         }
     919                String fullName = subdir + name + ext;
     920                String cacheName = prefix + fullName;
     921                /* cache separately */
     922                if (dirs != null && !dirs.isEmpty()) {
     923                    cacheName = "id:" + id + ':' + fullName;
     924                    if (archive != null) {
     925                        cacheName += ':' + archive.getName();
    925926                    }
     927                }
    926928
    927                     switch (place) {
    928                     case typeArchive:
    929                         if (archive != null) {
    930                             cacheName = "zip:"+archive.hashCode()+':'+cacheName;
    931                             ImageResource ir = cache.get(cacheName);
    932                             if (ir != null) return ir;
    933 
    934                             ir = getIfAvailableZip(fullName, archive, inArchiveDir, type);
    935                             if (ir != null) {
    936                                 cache.put(cacheName, ir);
    937                                 return ir;
    938                             }
    939                         }
    940                         break;
    941                     case typeLocal:
     929                switch (place) {
     930                case typeArchive:
     931                    if (archive != null) {
     932                        cacheName = "zip:" + archive.hashCode() + ':' + cacheName;
    942933                        ImageResource ir = cache.get(cacheName);
    943934                        if (ir != null) return ir;
    944935
    945                         // getImageUrl() does a ton of "stat()" calls and gets expensive
    946                         // and redundant when you have a whole ton of objects. So,
    947                         // index the cache by the name of the icon we're looking for
    948                         // and don't bother to create a URL unless we're actually creating the image.
    949                         URL path = getImageUrl(fullName);
    950                         if (path == null) {
    951                             continue;
    952                         }
    953                         ir = getIfAvailableLocalURL(path, type);
     936                        ir = getIfAvailableZip(fullName, archive, inArchiveDir, type);
    954937                        if (ir != null) {
    955938                            cache.put(cacheName, ir);
    956939                            return ir;
    957940                        }
    958                         break;
    959941                    }
     942                    break;
     943                case typeLocal:
     944                    ImageResource ir = cache.get(cacheName);
     945                    if (ir != null)
     946                        return ir;
     947
     948                    // getImageUrl() does a ton of "stat()" calls and gets expensive
     949                    // and redundant when you have a whole ton of objects. So,
     950                    // index the cache by the name of the icon we're looking for
     951                    // and don't bother to create a URL unless we're actually creating the image.
     952                    URL path = getImageUrl(fullName);
     953                    if (path == null) {
     954                        continue;
     955                    }
     956                    ir = getIfAvailableLocalURL(path, type);
     957                    if (ir != null) {
     958                        cache.put(cacheName, ir);
     959                        return ir;
     960                    }
     961                    break;
    960962                }
    961963            }
    962             return null;
    963964        }
     965        return null;
    964966    }
    965967
    966968    /**