- Timestamp:
- 2020-01-10T00:32:14+01:00 (5 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/org/openstreetmap/josm/tools/ImageProvider.java
r15590 r15675 45 45 import java.util.TreeSet; 46 46 import java.util.concurrent.CompletableFuture; 47 import java.util.concurrent.ConcurrentHashMap; 47 48 import java.util.concurrent.ExecutorService; 48 49 import java.util.concurrent.Executors; … … 296 297 * The icon cache 297 298 */ 298 private static final Map<String, ImageResource> cache = new HashMap<>();299 private static final Map<String, ImageResource> cache = new ConcurrentHashMap<>(); 299 300 300 301 /** … … 836 837 */ 837 838 public static void clearCache() { 838 synchronized (cache) { 839 cache.clear(); 840 } 839 cache.clear(); 841 840 synchronized (ROTATE_CACHE) { 842 841 ROTATE_CACHE.clear(); … … 856 855 */ 857 856 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) 861 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 } 871 return ir; 872 } 873 874 ImageType type = Utils.hasExtension(name, "svg") ? ImageType.SVG : ImageType.OTHER; 875 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 } 884 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 } 892 return ir; 893 } 894 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) { 910 911 if (".svg".equals(ext)) { 912 type = ImageType.SVG; 913 } else if (".png".equals(ext)) { 914 type = ImageType.OTHER; 857 // This method is called from different thread and modifying HashMap concurrently can result 858 // for example in loops in map entries (ie freeze when such entry is retrieved) 859 860 String prefix = isDisabled ? "dis:" : ""; 861 if (name.startsWith("data:")) { 862 String url = name; 863 ImageResource ir = cache.get(prefix + url); 864 if (ir != null) return ir; 865 ir = getIfAvailableDataUrl(url); 866 if (ir != null) { 867 cache.put(prefix + url, ir); 868 } 869 return ir; 870 } 871 872 ImageType type = Utils.hasExtension(name, "svg") ? ImageType.SVG : ImageType.OTHER; 873 874 if (name.startsWith(HTTP_PROTOCOL) || name.startsWith(HTTPS_PROTOCOL)) { 875 String url = name; 876 ImageResource ir = cache.get(prefix + url); 877 if (ir != null) return ir; 878 ir = getIfAvailableHttp(url, type); 879 if (ir != null) { 880 cache.put(prefix + url, ir); 881 } 882 return ir; 883 } else if (name.startsWith(WIKI_PROTOCOL)) { 884 ImageResource ir = cache.get(prefix + name); 885 if (ir != null) return ir; 886 ir = getIfAvailableWiki(name, type); 887 if (ir != null) { 888 cache.put(prefix + name, ir); 889 } 890 return ir; 891 } 892 893 if (subdir == null) { 894 subdir = ""; 895 } else if (!subdir.isEmpty() && !subdir.endsWith("/")) { 896 subdir += '/'; 897 } 898 String[] extensions; 899 if (name.indexOf('.') != -1) { 900 extensions = new String[] {""}; 901 } else { 902 extensions = new String[] {".png", ".svg"}; 903 } 904 final int typeArchive = 0; 905 final int typeLocal = 1; 906 for (int place : new Integer[] {typeArchive, typeLocal}) { 907 for (String ext : extensions) { 908 909 if (".svg".equals(ext)) { 910 type = ImageType.SVG; 911 } else if (".png".equals(ext)) { 912 type = ImageType.OTHER; 913 } 914 915 String fullName = subdir + name + ext; 916 String cacheName = prefix + fullName; 917 /* cache separately */ 918 if (dirs != null && !dirs.isEmpty()) { 919 cacheName = "id:" + id + ':' + fullName; 920 if (archive != null) { 921 cacheName += ':' + archive.getName(); 915 922 } 916 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 } 925 } 926 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: 923 } 924 925 switch (place) { 926 case typeArchive: 927 if (archive != null) { 928 cacheName = "zip:" + archive.hashCode() + ':' + cacheName; 942 929 ImageResource ir = cache.get(cacheName); 943 930 if (ir != null) return ir; 944 931 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); 932 ir = getIfAvailableZip(fullName, archive, inArchiveDir, type); 954 933 if (ir != null) { 955 934 cache.put(cacheName, ir); 956 935 return ir; 957 936 } 958 break;959 937 } 960 } 961 } 962 return null; 963 } 938 break; 939 case typeLocal: 940 ImageResource ir = cache.get(cacheName); 941 if (ir != null) return ir; 942 943 // getImageUrl() does a ton of "stat()" calls and gets expensive 944 // and redundant when you have a whole ton of objects. So, 945 // index the cache by the name of the icon we're looking for 946 // and don't bother to create a URL unless we're actually creating the image. 947 URL path = getImageUrl(fullName); 948 if (path == null) { 949 continue; 950 } 951 ir = getIfAvailableLocalURL(path, type); 952 if (ir != null) { 953 cache.put(cacheName, ir); 954 return ir; 955 } 956 break; 957 } 958 } 959 } 960 return null; 964 961 } 965 962
Note:
See TracChangeset
for help on using the changeset viewer.