Changeset 8647 in josm for trunk/src/org


Ignore:
Timestamp:
2015-08-08T12:32:18+02:00 (5 years ago)
Author:
wiktorn
Message:

Performance improvements.

  • getTileUrl now uses generic, staticly compiled pattern, instead of replaceAll (gives 2x improvement)
  • AbstractTileSourceLayer uses MemoryTileCache instead of JCS cache. This give huge improvement when there is a lot of tiles to show (eg. when min zoom is limited by user to some high value)
Location:
trunk/src/org/openstreetmap/josm
Files:
3 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/org/openstreetmap/josm/data/imagery/TemplatedWMSTileSource.java

    r8637 r8647  
    4242    private Bounds worldBounds;
    4343
    44     private static final String PATTERN_HEADER  = "\\{header\\(([^,]+),([^}]+)\\)\\}";
    45     private static final String PATTERN_PROJ    = "\\{proj(\\([^})]+\\))?\\}";
    46     private static final String PATTERN_BBOX    = "\\{bbox\\}";
    47     private static final String PATTERN_W       = "\\{w\\}";
    48     private static final String PATTERN_S       = "\\{s\\}";
    49     private static final String PATTERN_E       = "\\{e\\}";
    50     private static final String PATTERN_N       = "\\{n\\}";
    51     private static final String PATTERN_WIDTH   = "\\{width\\}";
    52     private static final String PATTERN_HEIGHT  = "\\{height\\}";
     44    private static final Pattern PATTERN_HEADER  = Pattern.compile("\\{header\\(([^,]+),([^}]+)\\)\\}");
     45    private static final Pattern PATTERN_PROJ    = Pattern.compile("\\{proj\\}");
     46    private static final Pattern PATTERN_BBOX    = Pattern.compile("\\{bbox\\}");
     47    private static final Pattern PATTERN_W       = Pattern.compile("\\{w\\}");
     48    private static final Pattern PATTERN_S       = Pattern.compile("\\{s\\}");
     49    private static final Pattern PATTERN_E       = Pattern.compile("\\{e\\}");
     50    private static final Pattern PATTERN_N       = Pattern.compile("\\{n\\}");
     51    private static final Pattern PATTERN_WIDTH   = Pattern.compile("\\{width\\}");
     52    private static final Pattern PATTERN_HEIGHT  = Pattern.compile("\\{height\\}");
     53    private static final Pattern PATTERN_PARAM   = Pattern.compile("\\{([^}]+)\\}");
    5354
    5455    private static final NumberFormat latLonFormat = new DecimalFormat("###0.0000000", new DecimalFormatSymbols(Locale.US));
    5556
    56     private static final String[] ALL_PATTERNS = {
     57    private static final Pattern[] ALL_PATTERNS = {
    5758        PATTERN_HEADER, PATTERN_PROJ, PATTERN_BBOX, PATTERN_W, PATTERN_S, PATTERN_E, PATTERN_N, PATTERN_WIDTH, PATTERN_HEIGHT
    5859    };
     
    6768        handleTemplate();
    6869        initProjection();
     70        // FIXME: remove in September 2015, when ImageryPreferenceEntry.tileSize will be initialized to -1 instead to 256
     71        // need to leave it as it is to keep compatiblity between tested and latest JOSM versions
     72        tileSize = WMSLayer.PROP_IMAGE_SIZE.get();
    6973    }
    7074
     
    8993    @Override
    9094    public int getDefaultTileSize() {
    91         return WMSLayer.PROP_IMAGE_SIZE.get();
    92     }
    93 
    94     // FIXME: remove in September 2015, when ImageryPreferenceEntry.tileSize will be initialized to -1 instead to 256
    95     // need to leave it as it is to keep compatiblity between tested and latest JOSM versions
    96     @Override
    97     public int getTileSize() {
    9895        return WMSLayer.PROP_IMAGE_SIZE.get();
    9996    }
     
    156153            bbox = String.format("%s,%s,%s,%s", latLonFormat.format(w), latLonFormat.format(s), latLonFormat.format(e), latLonFormat.format(n));
    157154        }
    158         return baseUrl.
    159                 replaceAll(PATTERN_PROJ,    myProjCode)
    160                 .replaceAll(PATTERN_BBOX,   bbox)
    161                 .replaceAll(PATTERN_W,      latLonFormat.format(w))
    162                 .replaceAll(PATTERN_S,      latLonFormat.format(s))
    163                 .replaceAll(PATTERN_E,      latLonFormat.format(e))
    164                 .replaceAll(PATTERN_N,      latLonFormat.format(n))
    165                 .replaceAll(PATTERN_WIDTH,  String.valueOf(getTileSize()))
    166                 .replaceAll(PATTERN_HEIGHT, String.valueOf(getTileSize()))
    167                 .replace(" ", "%20");
     155
     156        // Using StringBuffer and generic PATTERN_PARAM matcher gives 2x performance improvement over replaceAll
     157        StringBuffer url = new StringBuffer(baseUrl.length());
     158        Matcher matcher = PATTERN_PARAM.matcher(baseUrl);
     159        while (matcher.find()) {
     160            String replacement;
     161            switch (matcher.group(1)) {
     162            case "proj":
     163                replacement = myProjCode;
     164                break;
     165            case "bbox":
     166                replacement = bbox;
     167                break;
     168            case "w":
     169                replacement = latLonFormat.format(w);
     170                break;
     171            case "s":
     172                replacement = latLonFormat.format(s);
     173                break;
     174            case "e":
     175                replacement = latLonFormat.format(e);
     176                break;
     177            case "n":
     178                replacement = latLonFormat.format(n);
     179                break;
     180            case "width":
     181            case "height":
     182                replacement = String.valueOf(getTileSize());
     183                break;
     184            default:
     185                replacement = "{" + matcher.group(1) + "}";
     186            }
     187            matcher.appendReplacement(url, replacement);
     188        }
     189        matcher.appendTail(url);
     190        return url.toString().replace(" ", "%20");
    168191    }
    169192
     
    313336    public static void checkUrl(String url) {
    314337        CheckParameterUtil.ensureParameterNotNull(url, "url");
    315         Matcher m = Pattern.compile("\\{[^}]*\\}").matcher(url);
     338        Matcher m = PATTERN_PARAM.matcher(url);
    316339        while (m.find()) {
    317340            boolean isSupportedPattern = false;
    318             for (String pattern : ALL_PATTERNS) {
    319                 if (m.group().matches(pattern)) {
     341            for (Pattern pattern : ALL_PATTERNS) {
     342                if (pattern.matcher(m.group()).matches()) {
    320343                    isSupportedPattern = true;
    321344                    break;
     
    331354    private void handleTemplate() {
    332355        // Capturing group pattern on switch values
    333         Pattern pattern = Pattern.compile(PATTERN_HEADER);
    334356        StringBuffer output = new StringBuffer();
    335         Matcher matcher = pattern.matcher(this.baseUrl);
     357        Matcher matcher = PATTERN_HEADER.matcher(this.baseUrl);
    336358        while (matcher.find()) {
    337359            headers.put(matcher.group(1), matcher.group(2));
  • trunk/src/org/openstreetmap/josm/gui/layer/AbstractCachedTileSourceLayer.java

    r8628 r8647  
    8989        try {
    9090            cache = JCSCacheManager.getCache(getCacheName(),
    91                     getMemoryCacheSize(),
     91                    0,
    9292                    getDiskCacheSize(),
    9393                    CachedTileLoaderFactory.PROP_TILECACHE_DIR.get());
     
    126126            try {
    127127                return JCSCacheManager.getCache(name,
    128                         MEMORY_CACHE_SIZE.get(),
    129                         MAX_DISK_CACHE_SIZE.get() * 1024, // MAX_DISK_CACHE_SIZE is in MB
     128                        0,
     129                        MAX_DISK_CACHE_SIZE.get() * 1024, // MAX_DISK_CACHE_SIZE is in MB, needs to by in sync with getDiskCacheSize
    130130                        CachedTileLoaderFactory.PROP_TILECACHE_DIR.get());
    131131            } catch (IOException e) {
     
    137137    protected abstract Class<? extends TileLoader> getTileLoaderClass();
    138138
    139     protected int getMemoryCacheSize() {
    140         return MEMORY_CACHE_SIZE.get();
    141     }
    142 
    143139    protected int getDiskCacheSize() {
    144140        return MAX_DISK_CACHE_SIZE.get() * 1024;
  • trunk/src/org/openstreetmap/josm/gui/layer/AbstractTileSourceLayer.java

    r8644 r8647  
    174174
    175175        tileLoader = getTileLoaderFactory().makeTileLoader(this, headers);
    176         if (tileLoader instanceof TMSCachedTileLoader) {
    177             tileCache = (TileCache) tileLoader;
    178         } else {
    179             tileCache = new MemoryTileCache();
    180         }
     176        /*
     177         *  use MemoryTileCache instead of tileLoader JCS cache, as tileLoader caches only content (byte[] of image)
     178         *  and MemoryTileCache caches whole Tile. This gives huge performance improvement when a lot of tiles are visible
     179         *  in MapView (for example - when limiting min zoom in imagery)
     180         */
     181        tileCache = new MemoryTileCache(AbstractCachedTileSourceLayer.MEMORY_CACHE_SIZE.get());
    181182
    182183        try {
    183184            if ("file".equalsIgnoreCase(new URL(tileSource.getBaseUrl()).getProtocol())) {
    184185                tileLoader = new OsmTileLoader(this);
    185                 tileCache = new MemoryTileCache();
    186186            }
    187187        } catch (MalformedURLException e) {
     
    14841484        //g.drawString("currentZoomLevel=" + currentZoomLevel, 120, 120);
    14851485        g.setColor(Color.lightGray);
    1486         if (!autoZoom) {
    1487             if (ts.insane()) {
    1488                 myDrawString(g, tr("zoom in to load any tiles"), 120, 120);
    1489             } else if (ts.tooLarge()) {
    1490                 myDrawString(g, tr("zoom in to load more tiles"), 120, 120);
    1491             } else if (ts.tooSmall()) {
    1492                 myDrawString(g, tr("increase zoom level to see more detail"), 120, 120);
    1493             }
    1494         }
    1495 
    1496         if (zoom < getMinZoomLvl() && (ts.insane() || ts.tooLarge())) {
     1486
     1487        if (ts.insane()) {
    14971488            myDrawString(g, tr("zoom in to load any tiles"), 120, 120);
     1489        } else if (ts.tooLarge()) {
     1490            myDrawString(g, tr("zoom in to load more tiles"), 120, 120);
     1491        } else if (!autoZoom && ts.tooSmall()) {
     1492            myDrawString(g, tr("increase zoom level to see more detail"), 120, 120);
    14981493        }
    14991494
Note: See TracChangeset for help on using the changeset viewer.