📄 cachefilewithcache.java
字号:
break;
}
}
}
}
if ( multi_block_start != -1 ){
boolean skip_chunk = false;
if ( min_chunk_size != -1 ){
if ( release_entries ){
Debug.out( "CacheFile: can't use min chunk with release option" );
}else{
skip_chunk = multi_block_next - multi_block_start < min_chunk_size;
}
}
if ( skip_chunk ){
if ( TRACE ){
LGLogger.log( "flushCache: skipping " + multi_block_entries.size() + " entries, [" + multi_block_start + "," + multi_block_next + "] as too small" );
}
}else{
multiBlockFlush(
multi_block_entries,
multi_block_start,
multi_block_next,
release_entries );
}
}
if ( last_failure != null ){
if ( last_failure instanceof CacheFileManagerException ){
throw((CacheFileManagerException)last_failure );
}
throw( new CacheFileManagerException( "cache flush failed", last_failure ));
}
}finally{
this_mon.exit();
}
}
protected void
multiBlockFlush(
List multi_block_entries,
long multi_block_start,
long multi_block_next,
boolean release_entries )
throws CacheFileManagerException
{
boolean write_ok = false;
try{
if ( TRACE ){
LGLogger.log( "multiBlockFlush: writing " + multi_block_entries.size() + " entries, [" + multi_block_start + "," + multi_block_next + "," + release_entries + "]" );
}
DirectByteBuffer[] buffers = new DirectByteBuffer[ multi_block_entries.size()];
long expected_per_entry_write = 0;
for (int i=0;i<buffers.length;i++){
CacheEntry entry = (CacheEntry)multi_block_entries.get(i);
// sanitity check - we should always be flushing entire entries
DirectByteBuffer buffer = entry.getBuffer();
if ( buffer.limit(DirectByteBuffer.SS_CACHE) - buffer.position(DirectByteBuffer.SS_CACHE) != entry.getLength()){
throw( new CacheFileManagerException( "flush: inconsistent entry length, position wrong" ));
}
expected_per_entry_write += entry.getLength();
buffers[i] = buffer;
}
long expected_overall_write = multi_block_next - multi_block_start;
if ( expected_per_entry_write != expected_overall_write ){
throw( new CacheFileManagerException( "flush: inconsistent write length, entrys = " + expected_per_entry_write + " overall = " + expected_overall_write ));
}
getFMFile().write( buffers, multi_block_start );
manager.fileBytesWritten( expected_overall_write );
write_ok = true;
}catch( FMFileManagerException e ){
throw( new CacheFileManagerException( "flush fails", e ));
}finally{
for (int i=0;i<multi_block_entries.size();i++){
CacheEntry entry = (CacheEntry)multi_block_entries.get(i);
if ( release_entries ){
manager.releaseCacheSpace( entry );
}else{
entry.resetBufferPosition();
if ( write_ok ){
entry.setClean();
}
}
}
}
}
protected void
flushCache(
long file_start_position,
boolean release_entries,
long minumum_to_release )
throws CacheFileManagerException
{
if ( manager.isCacheEnabled()){
if ( TRACE ){
LGLogger.log( "flushCache: " + getName() + ", rel = " + release_entries + ", min = " + minumum_to_release );
}
flushCache( file_start_position, -1, release_entries, minumum_to_release, 0, -1 );
}
}
protected void
flushCache(
boolean release_entries,
long minumum_to_release )
throws CacheFileManagerException
{
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 ){
LGLogger.log( "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 String
getName()
{
return( file.getFile().toString());
}
protected FMFile
getFMFile()
{
return( file );
}
protected TOTorrentFile
getTorrentFile()
{
return( torrent_file );
}
// public methods
public File
getFile()
{
return( file.getFile());
}
public void
moveFile(
File new_file )
throws CacheFileManagerException
{
try{
flushCache( true, -1 );
file.moveFile( new_file );
}catch( FMFileManagerException e ){
manager.rethrow(e);
}
}
public void
setAccessMode(
int mode )
throws CacheFileManagerException
{
try{
if ( getAccessMode() != mode ){
flushCache( false, -1 );
}
file.setAccessMode( mode==CF_READ?FMFile.FM_READ:FMFile.FM_WRITE );
}catch( FMFileManagerException e ){
manager.rethrow(e);
}
}
public int
getAccessMode()
{
return( file.getAccessMode()==FMFile.FM_READ?CF_READ:CF_WRITE );
}
public void
ensureOpen()
throws CacheFileManagerException
{
try{
// no cache flush required here
file.ensureOpen();
}catch( FMFileManagerException e ){
manager.rethrow(e);
}
}
public long
getLength()
throws CacheFileManagerException
{
try{
// 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
return( file.getSize());
}catch( FMFileManagerException e ){
manager.rethrow(e);
return( 0 );
}
}
public void
setLength(
long length )
throws CacheFileManagerException
{
try{
// flush in case length change will invalidate cache data (unlikely but possible)
flushCache( true, -1 );
file.setLength( length );
}catch( FMFileManagerException e ){
manager.rethrow(e);
}
}
public void
read(
DirectByteBuffer buffer,
long position )
throws CacheFileManagerException
{
readCache( buffer, position, false );
}
public void
write(
DirectByteBuffer buffer,
long position )
throws CacheFileManagerException
{
writeCache( buffer, position, false );
}
public void
writeAndHandoverBuffer(
DirectByteBuffer buffer,
long position )
throws CacheFileManagerException
{
writeCache( buffer, position, true );
}
public void
flushCache()
throws CacheFileManagerException
{
flushCache( false, -1 );
}
public void
clearCache()
throws CacheFileManagerException
{
flushCache(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{
flushCache( true, -1 );
file.close();
fm_file_closed = true;
}catch( FMFileManagerException e ){
manager.rethrow(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
Debug.printStackTrace( e );
}
}
manager.closeFile( this );
}
}
public void
setFileOffset(
int _file_offset )
{
file_offset = _file_offset;
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -