// Created by plusminus on 17:58:57 - 25.09.2008
package org.osmdroid.tileprovider;

import java.util.concurrent.locks.ReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock;

import org.osmdroid.tileprovider.constants.OpenStreetMapTileProviderConstants;

import android.graphics.drawable.Drawable;

/**
 * 
 * @author Nicolas Gramlich
 * 
 */
public final class MapTileCache implements OpenStreetMapTileProviderConstants {
	// ===========================================================
	// Constants
	// ===========================================================

	// ===========================================================
	// Fields
	// ===========================================================

	protected LRUMapTileCache mCachedTiles;

	private final ReadWriteLock mReadWriteLock = new ReentrantReadWriteLock();

	// ===========================================================
	// Constructors
	// ===========================================================

	public MapTileCache() {
		this(CACHE_MAPTILECOUNT_DEFAULT);
	}

	/**
	 * @param aMaximumCacheSize
	 *            Maximum amount of MapTiles to be hold within.
	 */
	public MapTileCache(final int aMaximumCacheSize) {
		this.mCachedTiles = new LRUMapTileCache(aMaximumCacheSize);
	}

	// ===========================================================
	// Getter & Setter
	// ===========================================================

	public void ensureCapacity(final int aCapacity) {
		mReadWriteLock.readLock().lock();
		try {
			mCachedTiles.ensureCapacity(aCapacity);
		} finally {
			mReadWriteLock.readLock().unlock();
		}
	}

	public Drawable getMapTile(final MapTile aTile) {
		mReadWriteLock.readLock().lock();
		try {
			return this.mCachedTiles.get(aTile);
		} finally {
			mReadWriteLock.readLock().unlock();
		}
	}

	public void putTile(final MapTile aTile, final Drawable aDrawable) {
		if (aDrawable != null) {
			mReadWriteLock.writeLock().lock();
			try {
				this.mCachedTiles.put(aTile, aDrawable);
			} finally {
				mReadWriteLock.writeLock().unlock();
			}
		}
	}

	// ===========================================================
	// Methods from SuperClass/Interfaces
	// ===========================================================

	// ===========================================================
	// Methods
	// ===========================================================

	public boolean containsTile(final MapTile aTile) {
		mReadWriteLock.readLock().lock();
		try {
			return this.mCachedTiles.containsKey(aTile);
		} finally {
			mReadWriteLock.readLock().unlock();
		}
	}

	public void clear() {
		mReadWriteLock.writeLock().lock();
		try {
			this.mCachedTiles.clear();
		} finally {
			mReadWriteLock.writeLock().unlock();
		}
	}

	// ===========================================================
	// Inner and Anonymous Classes
	// ===========================================================
}

@@ -85,119 +85,8 @@
 %0D%0A%0D%0A
-import java.util.concurrent.locks.ReadWriteLock;%0D%0Aimport java.util.concurrent.locks.ReentrantReadWriteLock;%0D%0A%0D%0A
 impo
@@ -678,87 +678,8 @@
 %0D%0A%0D%0A
-%09private final ReadWriteLock mReadWriteLock = new ReentrantReadWriteLock();%0D%0A%0D%0A
 %09// 
@@ -1330,48 +1330,35 @@
 %0D%0A%09%09
-mReadWriteLock.readLock().lock();%0D%0A%09%09try
+synchronized (mCachedTiles)
  %7B%0D%0A
@@ -1405,63 +1405,8 @@
 );%0D%0A
-%09%09%7D finally %7B%0D%0A%09%09%09mReadWriteLock.readLock().unlock();%0D%0A
 %09%09%7D%0D
@@ -1470,48 +1470,35 @@
 %0D%0A%09%09
-mReadWriteLock.readLock().lock();%0D%0A%09%09try
+synchronized (mCachedTiles)
  %7B%0D%0A
@@ -1542,63 +1542,8 @@
 );%0D%0A
-%09%09%7D finally %7B%0D%0A%09%09%09mReadWriteLock.readLock().unlock();%0D%0A
 %09%09%7D%0D
@@ -1655,50 +1655,35 @@
 %0A%09%09%09
-mReadWriteLock.writeLock().lock();%0D%0A%09%09%09try
+synchronized (mCachedTiles)
  %7B%0D%0A
@@ -1732,66 +1732,8 @@
 );%0D%0A
-%09%09%09%7D finally %7B%0D%0A%09%09%09%09mReadWriteLock.writeLock().unlock();%0D%0A
 %09%09%09%7D
@@ -2121,48 +2121,35 @@
 %0D%0A%09%09
-mReadWriteLock.readLock().lock();%0D%0A%09%09try
+synchronized (mCachedTiles)
  %7B%0D%0A
@@ -2204,224 +2204,99 @@
 %0A%09%09%7D
- finally %7B%0D%0A%09%09%09mReadWriteLock.readLock().unlock();%0D%0A%09%09%7D%0D%0A%09%7D%0D%0A%0D%0A%09public void clear() %7B%0D%0A%09%09mReadWriteLock.writeLock().lock();%0D%0A%09%09try %7B%0D%0A%09%09%09this.mCachedTiles.clear();%0D%0A%09%09%7D finally %7B%0D%0A%09%09%09mReadWriteLock.writeLock().unlock
+%0D%0A%09%7D%0D%0A%0D%0A%09public void clear() %7B%0D%0A%09%09synchronized (mCachedTiles) %7B%0D%0A%09%09%09this.mCachedTiles.clear
 ();%0D

Replace ReentrantReadWriteLock with simple synchronization blocks in MapTileCache. After doing profiling we found that the ReentrantReadWriteLock is expensive compared to a simple thread lock especially since each operation within the critical section is so short.