rdresumehandler.java
来自「Azureus is a powerful, full-featured, cr」· Java 代码 · 共 784 行 · 第 1/2 页
JAVA
784 行
writer_and_checker.checkPiece(
i,
new CheckPieceResultHandler()
{
public void
processResult(
int piece_number,
int result,
Object user_data )
{
LGLogger.log(0, 0, LGLogger.INFORMATION, "Piece #" + piece_number + (result==CheckPieceResultHandler.OP_SUCCESS?" passed":" failed") + " re-check.");
pending_checks_sem.release();
}
},
null );
pending_check_num++;
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
}
while( pending_check_num > 0 ){
pending_checks_sem.reserve();
pending_check_num--;
}
//dump the newly built resume data to the disk/torrent
if ( bOverallContinue && !resume_data_complete ){
try{
dumpResumeDataToDisk(false, false);
}catch( Exception e ){
Debug.out( "Failed to dump initial resume data to disk" );
}
}
}finally{
// System.out.println( "Check of '" + disk_manager.getDownloadManager().getDisplayName() + "' completed in " + (System.currentTimeMillis() - start));
}
}
public void
dumpResumeDataToDisk(
boolean savePartialPieces,
boolean force_recheck )
throws Exception
{
// if file caching is enabled then this is an important time to ensure that the cache is
// flushed as we are going to record details about the accuracy of written data.
// First build the resume map from the data (as updates can still be goin on)
// Then, flush the cache. This means that on a successful flush the built resume
// data matches at least the valid state of the data
// Then update the torrent
DiskManagerFileInfo[] files = disk_manager.getFiles();
if ( !useFastResume ){
// flush cache even if resume disable
for (int i=0;i<files.length;i++){
files[i].flushCache();
}
return;
}
boolean was_complete = isTorrentResumeDataComplete(
download_manager_state,
disk_manager.getDownloadManager().getTorrentSaveDir(),
disk_manager.getDownloadManager().getTorrentSaveFile());
DiskManagerPiece[] pieces = disk_manager.getPieces();
//build the piece byte[]
byte[] resumeData = new byte[pieces.length];
if ( !force_recheck ){
for (int i = 0; i < resumeData.length; i++) {
if ( pieces[i].getDone()){
resumeData[i] = (byte)1;
}else{
resumeData[i] = (byte)0;
}
}
}
Map resumeMap = new HashMap();
Map resumeDirectory = new HashMap();
// We *really* shouldn't be using a localised string as a Map key (see bug 869749)
// currently fixed by mangling such that decode works
// System.out.println( "writing resume data: key = " + ByteFormatter.nicePrint(path));
String resume_key =
torrent.isSimpleTorrent()?
disk_manager.getDownloadManager().getTorrentSaveDir():
disk_manager.getDownloadManager().getTorrentSaveDirAndFile();
resume_key = getCanonicalResumeKey( resume_key );
resumeMap.put(resume_key, resumeDirectory);
resumeDirectory.put("resume data", resumeData);
Map partialPieces = new HashMap();
if ( savePartialPieces && !force_recheck ){
for (int i = 0; i < pieces.length; i++) {
DiskManagerPiece piece = pieces[i];
// save the partial pieces for any pieces that have not yet been completed
// and are in-progress (i.e. have at least one block downloaded)
boolean[] downloaded = piece.getWritten();
if (( !piece.getDone()) && piece.getCompleteCount() > 0 && downloaded != null ){
List blocks = new ArrayList();
for (int j = 0; j < downloaded.length; j++) {
if (downloaded[j]){
blocks.add(new Long(j));
}
}
partialPieces.put("" + i, blocks);
}
}
resumeDirectory.put("blocks", partialPieces);
}
// savePartialPieces has overloaded meanings. It also implies that the download
// is stopping, as opposed to this being an interim resume data save, and therefore
// that the resume data should be set as "valid". Being valid has the meaning that
// blocks marked as not-done will *not* be checked when the torrent is restarted
// to see if they are actually complete.
// TODO: fix this up!!!!
resumeDirectory.put("valid", new Long( force_recheck?0:(savePartialPieces?1:0)));
for (int i=0;i<files.length;i++){
files[i].flushCache();
}
// OK, we've got valid resume data and flushed the cache
download_manager_state.setResumeData( resumeMap );
boolean is_complete =
isTorrentResumeDataComplete(
download_manager_state,
disk_manager.getDownloadManager().getTorrentSaveDir(),
disk_manager.getDownloadManager().getTorrentSaveFile());
if ( was_complete && is_complete ){
// no change, no point in writing
}else{
download_manager_state.save();
}
}
/**
* data_dir must be the parent folder for a simple torrent or the *actual* folder for non-simple
* @param torrent
* @param data_dir
*/
public static void
setTorrentResumeDataComplete(
DownloadManagerState download_manager_state,
String resume_key )
{
TOTorrent torrent = download_manager_state.getTorrent();
resume_key = getCanonicalResumeKey( resume_key );
int piece_count = torrent.getNumberOfPieces();
byte[] resumeData = new byte[piece_count];
for (int i = 0; i < resumeData.length; i++) {
resumeData[i] = (byte)1;
}
Map resumeMap = new HashMap();
Map resumeDirectory = new HashMap();
// We *really* shouldn't be using a localised string as a Map key (see bug 869749)
// currently fixed by mangling such that decode works
resumeMap.put(resume_key, resumeDirectory);
resumeDirectory.put("resume data", resumeData);
Map partialPieces = new HashMap();
resumeDirectory.put("blocks", partialPieces);
resumeDirectory.put("valid", new Long(1));
download_manager_state.setResumeData( resumeMap );
}
public static void
setTorrentResumeDataNearlyComplete(
DownloadManagerState download_manager_state,
String torrent_save_dir,
String torrent_save_file )
{
// backwards compatability, resume data key is the dir
TOTorrent torrent = download_manager_state.getTorrent();
String resume_key = torrent.isSimpleTorrent()?
torrent_save_dir:
(torrent_save_dir + File.separator + torrent_save_file );
resume_key = getCanonicalResumeKey( resume_key );
long piece_count = torrent.getNumberOfPieces();
byte[] resumeData = new byte[(int)piece_count];
for (int i = 0; i < resumeData.length; i++) {
resumeData[i] = (byte)1;
}
// randomly clear some pieces
for (int i=0;i<3;i++){
int piece_num = (int)(Math.random()*piece_count);
resumeData[piece_num]= 0;
}
Map resumeMap = new HashMap();
Map resumeDirectory = new HashMap();
// We *really* shouldn't be using a localised string as a Map key (see bug 869749)
// currently fixed by mangling such that decode works
resumeMap.put(resume_key, resumeDirectory);
resumeDirectory.put("resume data", resumeData);
Map partialPieces = new HashMap();
resumeDirectory.put("blocks", partialPieces);
resumeDirectory.put("valid", new Long(0));
download_manager_state.setResumeData( resumeMap );
}
public static boolean
isTorrentResumeDataComplete(
DownloadManagerState download_manager_state,
String torrent_save_dir,
String torrent_save_file )
{
TOTorrent torrent = download_manager_state.getTorrent();
// backwards compatability, resume data key is the dir
String resume_key = torrent.isSimpleTorrent()?
torrent_save_dir:
(torrent_save_dir + File.separator + torrent_save_file );
// System.out.println( "resume key = " + resume_key );
resume_key = getCanonicalResumeKey( resume_key );
try{
int piece_count = torrent.getNumberOfPieces();
Map resumeMap = download_manager_state.getResumeData();
if (resumeMap != null) {
// see bug 869749 for explanation of this mangling
String mangled_path;
try{
mangled_path = new String(resume_key.getBytes(Constants.DEFAULT_ENCODING),Constants.BYTE_ENCODING);
}catch( Throwable e ){
Debug.printStackTrace( e );
mangled_path = resume_key;
}
Map resumeDirectory = (Map)resumeMap.get(mangled_path);
if ( resumeDirectory == null ){
// unfortunately, if the torrent hasn't been saved and restored then the
// mangling with not yet have taken place. So we have to also try the
// original key (see 878015)
resumeDirectory = (Map)resumeMap.get(resume_key);
}
if (resumeDirectory != null) {
byte[] resume_data = (byte[])resumeDirectory.get("resume data");
Map blocks = (Map)resumeDirectory.get("blocks");
boolean valid = ((Long)resumeDirectory.get("valid")).intValue() == 1;
// any partial pieced -> not complete
if ( blocks == null || blocks.size() > 0 ){
return( false );
}
if ( valid && resume_data.length == piece_count ){
for (int i=0;i<resume_data.length;i++){
if ( resume_data[i] == 0 ){
// missing piece
return( false );
}
}
return( true );
}
}
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
return( false );
}
protected static String
getCanonicalResumeKey(
String resume_key )
{
try{
resume_key = new File( resume_key).getCanonicalFile().toString();
}catch( Throwable e ){
Debug.printStackTrace( e );
}
return( resume_key );
}
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?