/* JAI-Ext - OpenSource Java Advanced Image Extensions Library
* http://www.geo-solutions.it/
* Copyright 2014 GeoSolutions
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
* http://www.apache.org/licenses/LICENSE-2.0
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package it.geosolutions.concurrent;
import it.geosolutions.concurrent.ConcurrentTileCache.Actions;
import java.awt.image.DataBuffer;
import java.awt.image.Raster;
import java.awt.image.RenderedImage;
import java.lang.ref.WeakReference;
import java.math.BigInteger;
import javax.media.jai.CachedTile;
import javax.media.jai.PlanarImage;
import javax.media.jai.remote.SerializableRenderedImage;
/**
* This class is used by ConcurrentTileCache to create an object that includes all the information associated with a tile, and is put into the cache.
*/
public final class CachedTileImpl implements CachedTile {
/*
* The shallow size of this object, the weak reference, the typical big integer keys
*/
private static final long CACHED_TILE_OVERHEAD = 64 + 32 + 96 + 96;
final Raster tile; // the tile
final WeakReference owner; // the RenderedImage of this tile
final int tileX; // tile X index
final int tileY; // tile Y index
final Object tileCacheMetric; // Metric for weighting tile computation cost
private long timeStamp; // the last time this tile is accessed (if diagnosticEnable==false it is set only at the creation time)
final Object key; // the key used to hash this tile
private final Object imageKey; // Key of the associated image
final long tileSize; // the memory of this tile in bytes
private Actions action; // every action done by the tile cache
/**
* Constructor that takes a tile cache metric
*
* @since 1.1
*/
public CachedTileImpl(RenderedImage owner, int tileX, int tileY, Raster tile,
Object tileCacheMetric) {
this.owner = new WeakReference(owner);
this.tile = tile;
this.tileX = tileX;
this.tileY = tileY;
this.tileCacheMetric = tileCacheMetric; // may be null
key = hashKey(owner, tileX, tileY);
imageKey = hashKey(owner);
DataBuffer db = tile.getDataBuffer();
tileSize = db.getDataTypeSize(db.getDataType()) / 8L * db.getSize() * db.getNumBanks() + CACHED_TILE_OVERHEAD;
updateTileTimeStamp();
}
/**
* Returns the key associated to the tile.
* @return
*/
public Object getKey() {
return key;
}
/**
* Returns the key associate to the tile owner
* @return
*/
public Object getImageKey() {
return imageKey;
}
/**
* Returns the hash table "key" as a <code>Object</code> for this tile.
*/
public static Object hashKey(RenderedImage owner, int tileX, int tileY) {
long idx = tileY * (long) owner.getNumXTiles() + tileX;
BigInteger imageID = null;
if (owner instanceof PlanarImage)
imageID = (BigInteger) ((PlanarImage) owner).getImageID();
else if (owner instanceof SerializableRenderedImage)
imageID = (BigInteger) ((SerializableRenderedImage) owner).getImageID();
if (imageID != null) {
byte[] buf = imageID.toByteArray();
int length = buf.length;
byte[] buf1 = new byte[length + 8];
System.arraycopy(buf, 0, buf1, 0, length);
for (int i = 7, j = 0; i >= 0; i--, j += 8)
buf1[length++] = (byte) (idx >> j);
return new BigInteger(buf1);
}
idx = idx & 0x00000000ffffffffL;
return Long.valueOf((((long) owner.hashCode() << 32) | idx));
}
/**
* Returns the hash table "key" as a <code>Object</code> for this image.
*/
public static Object hashKey(RenderedImage owner) {
BigInteger imageID = null;
if (owner instanceof PlanarImage)
imageID = (BigInteger) ((PlanarImage) owner).getImageID();
else if (owner instanceof SerializableRenderedImage)
imageID = (BigInteger) ((SerializableRenderedImage) owner).getImageID();
if (imageID != null) {
byte[] buf = imageID.toByteArray();
return new BigInteger(buf);
}
return owner.hashCode();
}
/** Returns the value of the cached tile. */
public Raster getTile() {
return tile;
}
/** Returns the owner of the cached tile. */
public RenderedImage getOwner() {
return (RenderedImage) owner.get();
}
/** Returns the current time stamp */
public long getTileTimeStamp() {
return timeStamp;
}
/** Returns the tileCacheMetric object */
public Object getTileCacheMetric() {
return tileCacheMetric;
}
/** Returns the tile memory size */
public long getTileSize() {
return tileSize;
}
/**
* Returns information about the status of the tile
*/
public int getAction() {
return action.valueAction();
}
/** Sets the status of the tile */
public void setAction(Actions newAction) {
action = newAction;
}
/** Sets the timestamp to the new current value */
public void updateTileTimeStamp() {
timeStamp = System.currentTimeMillis();
}
}