/*******************************************************************************
* Copyright © 2005, 2013 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*
*******************************************************************************/
package org.eclipse.edt.ide.core.internal.io;
import java.util.HashMap;
import java.util.Iterator;
import org.eclipse.core.runtime.IPath;
import org.eclipse.edt.compiler.internal.core.utils.ReadWriteMonitor;
import org.eclipse.edt.compiler.internal.io.IOBuffer;
/**
* @author svihovec
*
*/
public class IOBufferPool {
private static final int MAX_NUMBER_OF_BUFFERS = 10000;
private ReadWriteMonitor poolMonitor = new ReadWriteMonitor();
private HashMap bufferMap = new HashMap();
private HashMap monitorMap = new HashMap();
private IIOBufferReaderFactory readerFactory;
private IIOBufferWriterFactory writerFactory;
public IOBufferPool(IIOBufferReaderFactory readerFactory, IIOBufferWriterFactory writerFactory){
this.readerFactory = readerFactory;
this.writerFactory = writerFactory;
}
public Object get(IPath bufferPath, String key){
Object value = null;
poolMonitor.enterRead();
try{
IOBuffer buffer = getBuffer(bufferPath);
ReadWriteMonitor bufferMonitor = (ReadWriteMonitor)monitorMap.get(bufferPath);
bufferMonitor.enterRead();
try{
value = buffer.get(key);
}finally{
bufferMonitor.exitRead();
}
}finally{
poolMonitor.exitRead();
}
requestCleanup();
return value;
}
public void put(IPath bufferPath, String key, Object value){
poolMonitor.enterRead();
try{
IOBuffer buffer = getBuffer(bufferPath);
ReadWriteMonitor bufferMonitor = (ReadWriteMonitor)monitorMap.get(bufferPath);
bufferMonitor.enterWrite();
try{
buffer.put(key, value);
}finally{
bufferMonitor.exitWrite();
}
}finally{
poolMonitor.exitRead();
}
requestCleanup();
}
public void remove(IPath bufferPath, String key){
poolMonitor.enterRead();
try{
IOBuffer buffer = getBuffer(bufferPath);
ReadWriteMonitor bufferMonitor = (ReadWriteMonitor)monitorMap.get(bufferPath);
bufferMonitor.enterWrite();
try{
buffer.remove(key);
}finally{
bufferMonitor.exitWrite();
}
}finally{
poolMonitor.exitRead();
}
requestCleanup();
}
public void remove(IPath bufferPath){
poolMonitor.enterRead();
try{
removeBuffer(bufferPath);
}finally{
poolMonitor.exitRead();
}
}
public void flush(){
cleanup();
}
private synchronized IOBuffer getBuffer(IPath bufferPath){
IOBuffer buffer = (IOBuffer)bufferMap.get(bufferPath);
if(buffer == null){
buffer = new IOBuffer(readerFactory.getReader(bufferPath), writerFactory.getWriter(bufferPath));
bufferMap.put(bufferPath, buffer);
monitorMap.put(bufferPath, new ReadWriteMonitor());
}
return buffer;
}
private synchronized void removeBuffer(IPath bufferPath){
IOBuffer buffer = (IOBuffer)bufferMap.get(bufferPath);
if(buffer != null){
bufferMap.remove(bufferPath);
monitorMap.remove(bufferPath);
}
}
private synchronized void requestCleanup() {
if(bufferMap.size() > MAX_NUMBER_OF_BUFFERS){
cleanup();
}
}
private void cleanup(){
try{
poolMonitor.enterWrite();
for (Iterator iter = bufferMap.keySet().iterator(); iter.hasNext();) {
Object key = iter.next();
IOBuffer buffer = (IOBuffer)bufferMap.get(key);
buffer.writeCache();
}
}finally{
clearMembers();
poolMonitor.exitWrite();
}
}
public void clear(){
poolMonitor.enterWrite();
try{
clearMembers();
}finally{
poolMonitor.exitWrite();
}
}
private void clearMembers(){
bufferMap.clear();
monitorMap.clear();
}
}