FileDocCategorySizeDatePackage
FMFileManagerImpl.javaAPI DocAzureus 3.0.3.48280Tue Mar 21 03:12:54 GMT 2006com.aelitis.azureus.core.diskmanager.file.impl

FMFileManagerImpl

public class FMFileManagerImpl extends Object implements FMFileManager
author
parg

Fields Summary
public static final boolean
DEBUG
protected static FMFileManagerImpl
singleton
protected static AEMonitor
class_mon
protected LinkedHashMap
map
protected AEMonitor
map_mon
protected HashMap
links
protected AEMonitor
links_mon
protected boolean
limited
protected int
limit_size
protected AESemaphore
close_queue_sem
protected List
close_queue
protected AEMonitor
close_queue_mon
protected List
files
protected AEMonitor
files_mon
Constructors Summary
protected FMFileManagerImpl()

	
	 
	
	
		limit_size = COConfigurationManager.getIntParameter( "File Max Open" );
		
		limited		= limit_size > 0;
	
		if ( DEBUG ){
			
			System.out.println( "FMFileManager::init: limit = " + limit_size );
			
			files = new ArrayList();
		}
		
		map	= new LinkedHashMap( limit_size, (float)0.75, true );	// ACCESS order selected - this means oldest

		if ( limited ){
			
			close_queue_sem	= new AESemaphore("FMFileManager::closeqsem");
			
			close_queue		= new LinkedList();
			
			Thread	t = new AEThread("FMFileManager::closeQueueDispatcher")
				{
					public void
					runSupport()
					{
						closeQueueDispatch();
					}
				};
			
			t.setDaemon(true);
			
			t.start();
		}
	
Methods Summary
protected voidcloseFile(FMFileLimited file)

		if ( DEBUG ){
			System.out.println( "FMFileManager::closeFile: " + file.getName());
		}

		try{
			close_queue_mon.enter();
			
			close_queue.add( file );
			
		}finally{
			
			close_queue_mon.exit();
		}
		
		close_queue_sem.release();
	
protected voidcloseQueueDispatch()

		while(true){
			
			if ( DEBUG ){
				
				close_queue_sem.reserve(1000);
				
			}else{
				
				close_queue_sem.reserve();
			}
			
			FMFileLimited	file = null;
			
			try{
				close_queue_mon.enter();
			
				if ( close_queue.size() > 0 ){
					
					file = (FMFileLimited)close_queue.remove(0);

					if ( DEBUG ){
						
						System.out.println( "FMFileManager::closeQ: " + file.getName() + ", rem = " + close_queue.size());
					}
				}
			}finally{
				
				close_queue_mon.exit();
			}
			
			if ( file != null ){
				
				try{
					file.close(false);
				
				}catch( Throwable e ){
				
					Debug.printStackTrace( e );
				}
			}
			
			if ( DEBUG ){
				
				try{
					files_mon.enter();
					
					int	open = 0;
					
					for (int i=0;i<files.size();i++){

						FMFileLimited	f = (FMFileLimited)files.get(i);
						
						if ( f.isOpen()){
							
							open++;
						}
					}
					
					System.out.println( "INFO: files = " + files.size() + ", open = " + open );
					
				}finally{
					
					files_mon.exit();
				}
			}
		}
	
public FMFilecreateFile(FMFileOwner owner, java.io.File file, int type)

		FMFile	res;
		
		if ( AEDiagnostics.USE_DUMMY_FILE_DATA ){
			
			res = new FMFileTestImpl( owner, this, file, type );
			
		}else{
		
			if ( limited ){
	
				res = new FMFileLimited( owner, this, file, type );
				
			}else{
				
				res = new FMFileUnlimited( owner, this, file, type );
			}
		}
			
		if (DEBUG){
			
			try{
				files_mon.enter();
			
				files.add( res );
				
			}finally{
				
				files_mon.exit();
			}
		}
		
		return( res );
	
protected voidgenerate(IndentWriter writer)

		writer.println( "FMFileManager slots" );
		
		try{
			writer.indent();
			
			try{
				map_mon.enter();
							
				Iterator it = map.keySet().iterator();
					
				while( it.hasNext()){
					
					FMFileLimited	file = (FMFileLimited)it.next();
					
					writer.println( file.getString());
				}
							
			}finally{
				
				map_mon.exit();
			}
		}finally{
			
			writer.exdent();
		}
	
protected static voidgenerateEvidence(IndentWriter writer)

		getSingleton();
		
		singleton.generate( writer );
	
public java.io.FilegetFileLink(org.gudy.azureus2.core3.torrent.TOTorrent torrent, java.io.File file)

		try{
			links_mon.enter();
			
			CaseSensitiveFileMap	links_entry = getLinksEntry( torrent );

			File	res = (File)links_entry.get( file );
			
			if ( res == null ){
				
				res = file;
			}
			
			// System.out.println( "getLink:" + file + " -> " + res );
			
			return( res );
			
		}finally{
			
			links_mon.exit();
		}
	
protected com.aelitis.azureus.core.util.CaseSensitiveFileMapgetLinksEntry(org.gudy.azureus2.core3.torrent.TOTorrent torrent)

		Object	links_key;
		
		try{
			
			links_key = torrent.getHashWrapper();
			
		}catch( Throwable e ){
			
			Debug.printStackTrace(e);
			
			links_key	= "";
		}
		
		CaseSensitiveFileMap	links_entry = (CaseSensitiveFileMap)links.get( links_key );
		
		if ( links_entry == null ){
			
			links_entry	= new CaseSensitiveFileMap();
			
			links.put( links_key, links_entry );
		}
		
		return( links_entry );
	
public static FMFileManagergetSingleton()

	
	
	  
	
	
		try{
			class_mon.enter();
		
			if ( singleton == null ){
				
				singleton = new FMFileManagerImpl();
			}
			
			return( singleton );
			
		}finally{
			
			class_mon.exit();
		}
	
protected voidgetSlot(FMFileLimited file)

			// must close the oldest file outside sync block else we'll get possible deadlock
		
		FMFileLimited	oldest_file = null;
		
		try{
			map_mon.enter();
		
			if (DEBUG ){
				System.out.println( "FMFileManager::getSlot: " + file.getName() +", map_size = " + map.size());
			}
			
			if ( map.size() >= limit_size ){
				
				Iterator it = map.keySet().iterator();
				
				oldest_file = (FMFileLimited)it.next();
				
				it.remove();
			}
			
			map.put( file, file );
			
		}finally{
			
			map_mon.exit();
		}
		
		if ( oldest_file != null ){
			
			closeFile( oldest_file );			

		}
	
protected voidreleaseSlot(FMFileLimited file)

		if ( DEBUG ){
			System.out.println( "FMFileManager::releaseSlot: " + file.getName());
		}
		
		try{
			map_mon.enter();
			
			map.remove( file );
			
		}finally{
			
			map_mon.exit();
		}
	
public voidsetFileLinks(org.gudy.azureus2.core3.torrent.TOTorrent torrent, com.aelitis.azureus.core.util.CaseSensitiveFileMap new_links)

		try{
			links_mon.enter();
			
			CaseSensitiveFileMap	links_entry = getLinksEntry( torrent );
			
			Iterator	it = new_links.keySetIterator();
			
			while( it.hasNext()){
				
				File	source 	= (File)it.next();
				File	target	= (File)new_links.get(source);
				
				// System.out.println( "setLink:" + source + " -> " + target );
				
				if ( target != null ){
					
					links_entry.put( source, target );
				}else{
					
					links_entry.remove( source );
				}
			}
		}finally{
			
			links_mon.exit();
		}
	
protected voidusedSlot(FMFileLimited file)

	
		if ( DEBUG ){
			System.out.println( "FMFileManager::usedSlot: " + file.getName());
		}
		
		try{
			map_mon.enter();
		
				// only update if already present - might not be due to delay in
				// closing files
			
			if ( map.containsKey( file )){
				
				map.put( file, file );		// update MRU
			}
		}finally{
			
			map_mon.exit();
		}