/* * Copyright (C) 2010 Brockmann Consult GmbH (info@brockmann-consult.de) * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 3 of the License, or (at your option) * any later version. * This program is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for * more details. * * You should have received a copy of the GNU General Public License along * with this program; if not, see http://www.gnu.org/licenses/ */ package com.bc.ceres.jai.tilecache; import junit.framework.TestCase; import javax.media.jai.ComponentSampleModelJAI; import javax.media.jai.PlanarImage; import javax.media.jai.TiledImage; import java.awt.image.DataBuffer; import java.awt.image.Raster; import java.awt.image.RenderedImage; import java.util.HashMap; public class SwappingTileCacheTest extends TestCase { public void testTileStoreRestore() { long tileSize = 256 * 256 * 4; TiledImage im0 = createImage(4, 4); SwapSpaceMock swapSpaceMock = new SwapSpaceMock(); SwappingTileCache cache = new SwappingTileCache(3 * tileSize + 1, swapSpaceMock); Raster tile00 = im0.getTile(0, 0); Raster tile10 = im0.getTile(1, 0); Raster tile01 = im0.getTile(0, 1); Raster tile32 = im0.getTile(3, 2); swapSpaceMock.trace = ""; cache.add(im0, 0, 0, tile00); assertEquals("", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im0, 1, 0, tile10); assertEquals("", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im0, 0, 1, tile01); assertEquals("", swapSpaceMock.trace); // Expected: 2 swapped tiles LRU order. Two tiles, because memoryThreshold=75% swapSpaceMock.trace = ""; cache.add(im0, 3, 2, tile32); assertEquals("" + "storeTile(0-0-0);" + "storeTile(0-1-0);", swapSpaceMock.trace); assertTrue(swapSpaceMock.containsTile(im0, 0, 0)); assertTrue(swapSpaceMock.containsTile(im0, 1, 0)); assertFalse(swapSpaceMock.containsTile(im0, 0, 1)); assertFalse(swapSpaceMock.containsTile(im0, 3, 2)); swapSpaceMock.trace = ""; Raster tile00r = cache.getTile(im0, 0, 0); assertEquals("" + "restoreTile(0-0-0)=MemoryTile;", swapSpaceMock.trace); swapSpaceMock.trace = ""; Raster tile10r = cache.getTile(im0, 1, 0); assertEquals("" + "restoreTile(0-1-0)=MemoryTile;" + "storeTile(0-0-1);" + "storeTile(0-3-2);", swapSpaceMock.trace); swapSpaceMock.trace = ""; Raster tile01r = cache.getTile(im0, 0, 1); assertEquals("" + "restoreTile(0-0-1)=MemoryTile;", swapSpaceMock.trace); swapSpaceMock.trace = ""; Raster tile32r = cache.getTile(im0, 3, 2); assertEquals("" + "restoreTile(0-3-2)=MemoryTile;" + "storeTile(0-0-0);" + "storeTile(0-1-0);", swapSpaceMock.trace); // Expected: failed restore, bacause tile does not exist swapSpaceMock.trace = ""; Raster tile33r = cache.getTile(im0, 3, 3); assertEquals("restoreTile(0-3-3)=null;", swapSpaceMock.trace); testEqualTile(tile00, tile00r); testEqualTile(tile10, tile10r); testEqualTile(tile01, tile01r); testEqualTile(tile32, tile32r); assertNull(tile33r); swapSpaceMock.trace = ""; cache.remove(im0, 0, 0); cache.remove(im0, 0, 1); cache.remove(im0, 2, 2); assertEquals("" + "deleteTile(0-0-0)=true;" + "deleteTile(0-0-1)=true;" + "deleteTile(0-2-2)=false;", swapSpaceMock.trace); assertFalse(swapSpaceMock.containsTile(im0, 0, 0)); assertTrue(swapSpaceMock.containsTile(im0, 1, 0)); assertFalse(swapSpaceMock.containsTile(im0, 0, 1)); assertTrue(swapSpaceMock.containsTile(im0, 3, 2)); TiledImage im1 = createImage(4, 4); swapSpaceMock.trace = ""; cache.add(im1, 0, 0, im1.getTile(0, 0)); assertEquals("", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im1, 0, 1, im1.getTile(0, 1)); assertEquals("", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im1, 0, 2, im1.getTile(0, 2)); assertEquals("" + "storeTile(0-3-2);" + "storeTile(1-0-0);", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im1, 0, 3, im1.getTile(0, 3)); assertEquals("", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im1, 1, 0, im1.getTile(1, 0)); assertEquals("" + "storeTile(1-0-1);" + "storeTile(1-0-2);", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im1, 1, 1, im1.getTile(1, 1)); assertEquals("", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.add(im1, 1, 2, im1.getTile(1, 2)); assertEquals("" + "storeTile(1-0-3);" + "storeTile(1-1-0);", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.removeTiles(im0); assertEquals("" + "deleteTile(0-0-0)=false;" + "deleteTile(0-1-0)=true;" + "deleteTile(0-2-0)=false;" + "deleteTile(0-3-0)=false;" + "deleteTile(0-0-1)=false;" + "deleteTile(0-1-1)=false;" + "deleteTile(0-2-1)=false;" + "deleteTile(0-3-1)=false;" + "deleteTile(0-0-2)=false;" + "deleteTile(0-1-2)=false;" + "deleteTile(0-2-2)=false;" + "deleteTile(0-3-2)=true;" + "deleteTile(0-0-3)=false;" + "deleteTile(0-1-3)=false;" + "deleteTile(0-2-3)=false;" + "deleteTile(0-3-3)=false;", swapSpaceMock.trace); swapSpaceMock.trace = ""; cache.removeTiles(im1); assertEquals("" + "deleteTile(1-0-0)=true;" + "deleteTile(1-1-0)=true;" + "deleteTile(1-2-0)=false;" + "deleteTile(1-3-0)=false;" + "deleteTile(1-0-1)=true;" + "deleteTile(1-1-1)=false;" + "deleteTile(1-2-1)=false;" + "deleteTile(1-3-1)=false;" + "deleteTile(1-0-2)=true;" + "deleteTile(1-1-2)=false;" + "deleteTile(1-2-2)=false;" + "deleteTile(1-3-2)=false;" + "deleteTile(1-0-3)=true;" + "deleteTile(1-1-3)=false;" + "deleteTile(1-2-3)=false;" + "deleteTile(1-3-3)=false;", swapSpaceMock.trace); } private static TiledImage createImage(int numXTiles, int numYTiles) { ComponentSampleModelJAI sm = new ComponentSampleModelJAI(DataBuffer.TYPE_FLOAT, 256, 256, 1, 256, new int[1]); return new TiledImage(0, 0, numXTiles * 256, numYTiles * 256, 0, 0, sm, PlanarImage.createColorModel(sm)); } private void testEqualTile(Raster tile00, Raster tile00r) { assertNotNull(tile00); assertNotNull(tile00r); assertEquals(tile00.getWidth(), tile00r.getWidth()); assertEquals(tile00.getHeight(), tile00r.getHeight()); assertEquals(tile00.getSampleModel(), tile00r.getSampleModel()); } private static class SwapSpaceMock implements SwapSpace { HashMap<RenderedImage, Integer> ids = new HashMap<RenderedImage, Integer>(); HashMap<String, MemoryTile> tiles = new HashMap<String, MemoryTile>(); String trace = ""; public boolean containsTile(RenderedImage owner, int tileX, int tileY) { String key = getKey(owner, tileX, tileY); return tiles.containsKey(key); } public boolean storeTile(MemoryTile memoryTile) { String key = getKey(memoryTile.getOwner(), memoryTile.getTileX(), memoryTile.getTileY()); tiles.put(key, memoryTile); trace += "storeTile(" + key + ");"; return true; } public MemoryTile restoreTile(RenderedImage owner, int tileX, int tileY) { String key = getKey(owner, tileX, tileY); final MemoryTile memoryTile = tiles.get(key); trace += "restoreTile(" + key + ")=" + (memoryTile != null ? "MemoryTile" : "null") + ";"; return memoryTile; } public boolean deleteTile(RenderedImage owner, int tileX, int tileY) { String key = getKey(owner, tileX, tileY); final boolean b = tiles.remove(key) != null; trace += "deleteTile(" + key + ")=" + b + ";"; return b; } private int getId(RenderedImage owner) { Integer integer = ids.get(owner); if (integer != null) { return integer; } integer = ids.size(); ids.put(owner, integer); return integer; } private String getKey(RenderedImage owner, int tileX, int tileY) { return getId(owner) + "-" + tileX + "-" + tileY; } } }