📄 externalseedreaderimpl.java
字号:
*/
public int
readBytes(
int max )
{
// permission to read a bunch of bytes
// we're out of step here due to multiple threads so we have to report what
// has already happened and prepare for what will
int res = 0;
synchronized( rate_sem ){
if ( rate_bytes_read > 0 ){
res = rate_bytes_read;
if ( res > max ){
res = max;
}
rate_bytes_read -= res;
}
int rem = max - res;
if ( rem > rate_bytes_permitted ){
if ( rate_bytes_permitted == 0 ){
rate_sem.release();
}
rate_bytes_permitted = rem;
}
}
return( res );
}
public int
getPermittedBytes()
throws ExternalSeedException
{
synchronized( rate_sem ){
if ( rate_bytes_permitted > 0 ){
return( rate_bytes_permitted );
}
}
if ( !rate_sem.reserve( 1000 )){
return( 1 ); // one byte a sec to check for connection liveness
}
return( rate_bytes_permitted );
}
public void
reportBytesRead(
int num )
{
synchronized( rate_sem ){
rate_bytes_read += num;
rate_bytes_permitted -= num;
if ( rate_bytes_permitted < 0 ){
rate_bytes_permitted = 0;
}
}
}
public int
getPercentDoneOfCurrentIncomingRequest()
{
ExternalSeedReaderRequest cr = current_request;
if ( cr == null ){
return( 0 );
}
return( cr.getPercentDoneOfCurrentIncomingRequest());
}
public int
getMaximumNumberOfRequests()
{
if ( getRequestCount() == 0 ){
return((int)(( getPieceGroupSize() * torrent.getPieceSize() ) / PeerReadRequest.NORMAL_REQUEST_SIZE ));
}else{
return( 0 );
}
}
public void
calculatePriorityOffsets(
PeerManager peer_manager,
int[] base_priorities )
{
try{
Piece[] pieces = peer_manager.getPieces();
int piece_group_size = getPieceGroupSize();
int[] contiguous_best_pieces = new int[piece_group_size];
int[] contiguous_highest_pri = new int[piece_group_size];
Arrays.fill( contiguous_highest_pri, -1 );
int contiguous = 0;
int contiguous_best_pri = -1;
int max_contiguous = 0;
int max_free_reqs = 0;
int max_free_reqs_piece = -1;
for (int i=0;i<pieces.length;i++){
Piece piece = pieces[i];
if ( piece.isFullyAllocatable()){
contiguous++;
int base_pri = base_priorities[i];
if ( base_pri > contiguous_best_pri ){
contiguous_best_pri = base_pri;
}
for (int j=0;j<contiguous && j<contiguous_highest_pri.length;j++){
if ( contiguous_best_pri > contiguous_highest_pri[j] ){
contiguous_highest_pri[j] = contiguous_best_pri;
contiguous_best_pieces[j] = i - j;
}
if ( j+1 > max_contiguous ){
max_contiguous = j+1;
}
}
}else{
contiguous = 0;
contiguous_best_pri = -1;
if ( max_contiguous == 0 ){
int free_reqs = piece.getAllocatableRequestCount();
if ( free_reqs > max_free_reqs ){
max_free_reqs = free_reqs;
max_free_reqs_piece = i;
}
}
}
}
if ( max_contiguous == 0 ){
if ( max_free_reqs_piece >= 0 ){
priority_offsets = new int[ (int)getTorrent().getPieceCount()];
priority_offsets[max_free_reqs_piece] = 10000;
}else{
priority_offsets = null;
}
}else{
priority_offsets = new int[ (int)getTorrent().getPieceCount()];
int start_piece = contiguous_best_pieces[max_contiguous-1];
for (int i=start_piece;i<start_piece+max_contiguous;i++){
priority_offsets[i] = 10000 - (i-start_piece);
}
}
}catch( Throwable e ){
Debug.printStackTrace(e);
priority_offsets = null;
}
}
protected abstract int
getPieceGroupSize();
protected abstract boolean
getRequestCanSpanPieces();
public int[]
getPriorityOffsets()
{
return( priority_offsets );
}
protected int
selectRequests(
List requests )
{
long next_start = -1;
int last_piece_number = -1;
for (int i=0;i<requests.size();i++){
PeerReadRequest request = (PeerReadRequest)requests.get(i);
int this_piece_number = request.getPieceNumber();
if ( last_piece_number != -1 && last_piece_number != this_piece_number ){
if ( !getRequestCanSpanPieces()){
return( i );
}
}
long this_start = this_piece_number * torrent.getPieceSize() + request.getOffset();
if ( next_start != -1 && this_start != next_start ){
return(i);
}
next_start = this_start + request.getLength();
last_piece_number = this_piece_number;
}
return( requests.size());
}
protected abstract void
readData(
ExternalSeedReaderRequest request )
throws ExternalSeedException;
protected void
processRequests(
List requests )
{
boolean ok = false;
ExternalSeedReaderRequest request = new ExternalSeedReaderRequest( this, requests );
active_read_request = request;
try{
current_request = request;
readData( request );
ok = true;
}catch( ExternalSeedException e ){
if ( e.isPermanentFailure()){
permanent_fail = true;
}
status = "Failed: " + Debug.getNestedExceptionMessage(e);
request.failed();
}catch( Throwable e ){
status = "Failed: " + Debug.getNestedExceptionMessage(e);
request.failed();
}finally{
active_read_request = null;
if ( ok ){
last_failed_read = 0;
consec_failures = 0;
}else{
last_failed_read = getSystemTime();
consec_failures++;
}
}
}
public void
addRequests(
List new_requests )
{
try{
requests_mon.enter();
if ( !active ){
Debug.out( "request added when not active!!!!" );
}
for (int i=0;i<new_requests.size();i++){
requests.add( new_requests.get(i));
request_sem.release();
}
if ( request_thread == null ){
plugin.getPluginInterface().getUtilities().createThread(
"RequestProcessor",
new Runnable()
{
public void
run()
{
processRequests();
}
});
}
}finally{
requests_mon.exit();
}
}
public void
cancelRequest(
PeerReadRequest request )
{
try{
requests_mon.enter();
if ( requests.contains( request ) && !request.isCancelled()){
request.cancel();
}
}finally{
requests_mon.exit();
}
}
public void
cancelAllRequests()
{
try{
requests_mon.enter();
for (int i=0;i<requests.size();i++){
PeerReadRequest request = (PeerReadRequest)requests.get(i);
if ( !request.isCancelled()){
request.cancel();
}
}
if ( active_read_request != null ){
active_read_request.cancel();
}
}finally{
requests_mon.exit();
}
}
public int
getRequestCount()
{
try{
requests_mon.enter();
return( requests.size());
}finally{
requests_mon.exit();
}
}
public List
getExpiredRequests()
{
List res = null;
try{
requests_mon.enter();
for (int i=0;i<requests.size();i++){
PeerReadRequest request = (PeerReadRequest)requests.get(i);
if ( request.isExpired()){
if ( res == null ){
res = new ArrayList();
}
res.add( request );
}
}
}finally{
requests_mon.exit();
}
return( res );
}
public List
getRequests()
{
List res = null;
try{
requests_mon.enter();
res = new ArrayList( requests );
}finally{
requests_mon.exit();
}
return( res );
}
protected void
informComplete(
PeerReadRequest request,
byte[] buffer )
{
PooledByteBuffer pool_buffer = plugin.getPluginInterface().getUtilities().allocatePooledByteBuffer( buffer );
for (int i=0;i<listeners.size();i++){
try{
((ExternalSeedReaderListener)listeners.get(i)).requestComplete( request, pool_buffer );
}catch( Throwable e ){
e.printStackTrace();
}
}
}
protected void
informCancelled(
PeerReadRequest request )
{
for (int i=0;i<listeners.size();i++){
try{
((ExternalSeedReaderListener)listeners.get(i)).requestCancelled( request );
}catch( Throwable e ){
e.printStackTrace();
}
}
}
protected void
informFailed(
PeerReadRequest request )
{
for (int i=0;i<listeners.size();i++){
try{
((ExternalSeedReaderListener)listeners.get(i)).requestFailed( request );
}catch( Throwable e ){
e.printStackTrace();
}
}
}
public void
addListener(
ExternalSeedReaderListener l )
{
listeners.add( l );
}
public void
removeListener(
ExternalSeedReaderListener l )
{
listeners.remove( l );
}
protected int
getIntParam(
Map map,
String name,
int def )
{
Object obj = map.get(name);
if ( obj instanceof Long ){
return(((Long)obj).intValue());
}
return( def );
}
protected boolean
getBooleanParam(
Map map,
String name,
boolean def )
{
return( getIntParam( map, name, def?1:0) != 0 );
}
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -