⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cachefilewithcache.java

📁 这是一个基于java编写的torrent的P2P源码
💻 JAVA
📖 第 1 页 / 共 3 页
字号:
	
		throws CacheFileManagerException
	{
		if ( manager.isCacheEnabled()){
							
			if (TRACE)
				Logger.log(new LogEvent(torrent, LOGID, "flushCache: " + getName()
						+ ", rel = " + release_entries + ", min = " + minumum_to_release));
			
			flushCache( file_start_position, -1, release_entries, minumum_to_release, 0, -1 );
		}
	}
	
		// this is the flush method used by the public methods directly (as opposed to those use when reading, writing etc)
		// and it is the place that pending exceptions are checked for. We don't want to check for this in the internal
		// logic for flushing as we need to be able to flush from files that have a pending error to clear the cache
		// state
	
	protected void
	flushCachePublic(
		boolean				release_entries,
		long				minumum_to_release )
	
		throws CacheFileManagerException
	{
		checkPendingException();
		
		flushCache(0, release_entries, minumum_to_release );
	}
	
	protected void
	flushOldDirtyData(
		long	oldest_dirty_time,
		long	min_chunk_size )
	
		throws CacheFileManagerException
	{
		if ( manager.isCacheEnabled()){
			
			if (TRACE)
				Logger.log(new LogEvent(torrent, LOGID, "flushOldDirtyData: "
						+ getName()));

			flushCache( 0, -1, false, -1, oldest_dirty_time, min_chunk_size );
		}
	}
	
	protected void
	flushOldDirtyData(
		long	oldest_dirty_time )
	
		throws CacheFileManagerException
	{
		flushOldDirtyData( oldest_dirty_time, -1 );
	}
	
	protected long
	getBytesInCache(
		long	offset,
		long	length )
	{
		try{
			this_mon.enter();
			
			long	result	= 0;
			
			Iterator	it = cache.iterator();
			
			long	start_pos	= offset;
			long	end_pos		= offset + length;
			
			while( it.hasNext()){
			
				CacheEntry	entry = (CacheEntry)it.next();
				
				long	this_start 		= entry.getFilePosition();
				int		entry_length	= entry.getLength();
				
				long	this_end	= this_start + entry_length;
				
				if ( this_end <= start_pos ){
					
					continue;
				}
				
				if ( end_pos <= this_start ){
					
					break;
				}
				
				long	bit_start	= start_pos<this_start?this_start:start_pos;
				long	bit_end		= end_pos>=this_end?this_end:end_pos;

				result	+= bit_end - bit_start;
			}
			
			return( result );
			
		}finally{
			
			this_mon.exit();
		}
	}
	
		// support methods
	
	protected void
	checkPendingException()
	
		throws CacheFileManagerException
	{
		if ( pending_exception != null ){
			
			throw( pending_exception );
		}
	}
	
	protected void
	setPendingException(
		CacheFileManagerException	e )
	{
		pending_exception	= e;
	}

	protected String
	getName()
	{
		return( file.getName());
	}
	
	protected FMFile
	getFMFile()
	{
		return( file );
	}
	
		// public methods
	
	public boolean
	exists()
	{
		return( file.exists());
	}
	
	public void
	moveFile(
		File		new_file )
	
		throws CacheFileManagerException
	{
		try{
			flushCachePublic( true, -1 );
			
			file.moveFile( new_file );
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
		}	
	}
	
	public void
	setAccessMode(
		int		mode )
	
		throws CacheFileManagerException
	{
		try{
			this_mon.enter();
			
			if ( access_mode != mode ){
				
				flushCachePublic( false, -1 );
			}
							
			file.setAccessMode( mode==CF_READ?FMFile.FM_READ:FMFile.FM_WRITE );
			
			access_mode	= mode;

		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
			
		}finally{
			
			this_mon.exit();
		}
	}
	
	public int
	getAccessMode()
	{
		return( access_mode );
	}
	
	public void
	setStorageType(
		int		type )
	
		throws CacheFileManagerException
	{
		try{
			this_mon.enter();
			
			if ( getStorageType() != type ){
				
				flushCachePublic( false, -1 );
			}
			
			file.setStorageType( type==CT_COMPACT?FMFile.FT_COMPACT:FMFile.FT_LINEAR );
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
			
		}finally{
			
			this_mon.exit();
		}		
	}
	
	public int
	getStorageType()
	{
		return( file.getStorageType()==FMFile.FT_COMPACT?CT_COMPACT:CT_LINEAR );
	}
	
	public void
	ensureOpen(
		String	reason )

		throws CacheFileManagerException
	{
		try{
				// no cache flush required here
			
			file.ensureOpen( reason );
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
		}	
	}

	public long
	getLength()
	
		throws CacheFileManagerException
	{
		
			// not sure of the difference between "size" and "length" here. Old code
			// used to use "size" so I'm going to carry on for the moment in case
			// there is some weirdness here
		
		try{
				// bug found here with "incremental creation" failing with lots of hash
				// fails. Caused by the reported length not taking into account the cache
				// entries that have yet to be flushed.			
			
			if ( manager.isCacheEnabled()){
				
				try{
					this_mon.enter();
			
					long	physical_size = file.getLength();

					Iterator	it = cache.iterator();
					
						// last entry is furthest down the file
					
					while( it.hasNext()){
					
						CacheEntry	entry = (CacheEntry)it.next();
					
						if ( !it.hasNext()){
							
							long	entry_file_position 	= entry.getFilePosition();
							int		entry_length			= entry.getLength();

							long	logical_size = entry_file_position + entry_length;
							
							if ( logical_size > physical_size ){
								
								physical_size	= logical_size;								
							}
						}
					}
					
					return( physical_size );

				}finally{
					
					this_mon.exit();
				}
			}else{
				
				return( file.getLength());
			}
						
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
			
			return( 0 );
		}
	}
	
	public long
	compareLength(
		long	compare_to )
	
		throws CacheFileManagerException
	{
		try{
				// we can optimise this if the file's already big enough as cache entries can
				// only make it bigger
			
			long	physical_length = file.getLength();
			
			long	res = physical_length - compare_to;
			
			if ( res >= 0 ){
				
				return( res );
			}
			
			return( getLength() - compare_to );
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
			
			return( 0 );
		}
	}
	
	public void
	setLength(
		long		length )
	
		throws CacheFileManagerException
	{
		try{
			
				// flush in case length change will invalidate cache data (unlikely but possible) 
			
			flushCachePublic( true, -1 );
			
			file.setLength( length );
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
		}
	}
	
	public void
	read(
		DirectByteBuffer[]	buffers,
		long				position,
		short				policy )
	
		throws CacheFileManagerException
	{
		for (int i=0;i<buffers.length;i++){
			
			DirectByteBuffer	buffer = buffers[i];
			
			int	len = buffer.remaining( DirectByteBuffer.SS_CACHE );
			
			try{
				read( buffer, position, policy );
				
				position += len;
				
			}catch( CacheFileManagerException e ){
				
				throw( new CacheFileManagerException( this, e.getMessage(), e, i ));
			}
		}
	}
	
	public void
	read(
		DirectByteBuffer	buffer,
		long				position,
		short				policy )
	
		throws CacheFileManagerException
	{
		boolean	read_cache 	= ( policy & CP_READ_CACHE ) != 0;
		boolean	flush		= ( policy & CP_FLUSH ) != 0;
				
		if ( flush ){
			
			int	file_buffer_position	= buffer.position(DirectByteBuffer.SS_CACHE);
			int	file_buffer_limit		= buffer.limit(DirectByteBuffer.SS_CACHE);
			
			int	read_length	= file_buffer_limit - file_buffer_position;
					
			flushCache( position, read_length, false, -1, 0, -1 );
		}
		
		readCache( buffer, position, false, !read_cache );
	}
		
	public void
	write(
		DirectByteBuffer	buffer,
		long				position )
	
		throws CacheFileManagerException
	{
		writeCache( buffer, position, false );
	}
	
	public void
	write(
		DirectByteBuffer[]	buffers,
		long				position )
	
		throws CacheFileManagerException
	{
		for (int i=0;i<buffers.length;i++){
			
			DirectByteBuffer	buffer = buffers[i];
			
			int	len = buffer.remaining( DirectByteBuffer.SS_CACHE );
			
			try{
				write( buffer, position );
			
				position += len;
				
			}catch( CacheFileManagerException e ){
				
				throw( new CacheFileManagerException( this, e.getMessage(), e, i ));
			}
		}
	}
	
	public void
	writeAndHandoverBuffer(
		DirectByteBuffer	buffer,
		long				position )
	
		throws CacheFileManagerException
	{
		writeCache( buffer, position, true );
	}
	
	public void
	writeAndHandoverBuffers(
		DirectByteBuffer[]	buffers,
		long				position )
	
		throws CacheFileManagerException
	{
		for (int i=0;i<buffers.length;i++){
			
			DirectByteBuffer	buffer = buffers[i];
			
			int	len = buffer.remaining( DirectByteBuffer.SS_CACHE );
			
			try{
				writeAndHandoverBuffer( buffer, position );
			
				position += len;
				
			}catch( CacheFileManagerException e ){
				
				throw( new CacheFileManagerException( this, e.getMessage(), e, i ));
			}
		}
	}
	
	public void
	flushCache()
	
		throws CacheFileManagerException
	{
		try{
			flushCachePublic( false, -1 );
			
			file.flush();
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
		}
	}
	
	public void
	clearCache()
	
		throws CacheFileManagerException
	{
		flushCachePublic(true, -1);
	}
	
	public void
	close()
	
		throws CacheFileManagerException
	{
			// we've got to always close the file here, even if the flush fails
		
		boolean	fm_file_closed = false;
		
		try{
			flushCachePublic( true, -1 );
			
			file.close();
			
			fm_file_closed	= true;
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);
			
		}finally{
			
			if ( !fm_file_closed ){
				
				try{
					file.close();
					
				}catch( Throwable e ){
					
						// we're already on our way out via exception, no need to
						// throw a new one

				}
			}
			
			manager.closeFile( this );
		}
	}
	
	public void
	delete()
	
		throws CacheFileManagerException
	{
		try{
			
			file.delete();
			
		}catch( FMFileManagerException e ){
			
			manager.rethrow(this,e);			
		}
	}
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -