/*
* File : TRHostConfigImpl.java
* Created : 06-Nov-2003
* By : parg
*
* Azureus - a Java Bittorrent client
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details ( see the LICENSE file ).
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/
package org.gudy.azureus2.core3.tracker.host.impl;
/**
* @author parg
*
*/
import java.util.*;
import java.io.*;
import java.text.*;
import org.gudy.azureus2.core3.config.*;
import org.gudy.azureus2.core3.util.*;
import org.gudy.azureus2.core3.torrent.*;
import org.gudy.azureus2.core3.tracker.host.*;
public class
TRHostConfigImpl
{
public static final String LOG_FILE_NAME = "tracker.log";
public static final long BACKUP_RETENTION_PERIOD = 7*24*60*60*1000L;
private TRHostImpl host;
private AEMonitor save_lock_mon = new AEMonitor( "TRHostConfig:SL" );
private String log_dir;
private volatile boolean loading = false;
private volatile boolean save_outstanding = false;
private Map saved_stats = new HashMap();
private AEMonitor this_mon = new AEMonitor( "TRHostConfig" );
protected
TRHostConfigImpl(
TRHostImpl _host )
{
host = _host;
log_dir = SystemProperties.getUserPath();
}
protected void
loadConfig(
TRHostTorrentFinder finder )
{
try{
this_mon.enter();
loading = true;
Map map = FileUtil.readResilientConfigFile("tracker.config");
List torrents = (List) map.get("torrents");
if (torrents == null){
return;
}
Iterator iter = torrents.iterator();
while (iter.hasNext()) {
Map t_map = (Map) iter.next();
Long persistent_l = (Long)t_map.get("persistent");
boolean persistent = persistent_l==null || persistent_l.longValue() == 1;
Long passive_l = (Long)t_map.get("passive");
boolean passive = passive_l!=null && passive_l.longValue() == 1;
Long dateadded_l = (Long)t_map.get("dateadded");
long date_added = dateadded_l==null?SystemTime.getCurrentTime():dateadded_l.longValue();
byte[] hash = (byte[])t_map.get("hash");
if ( persistent ){
int state = ((Long)t_map.get("status")).intValue();
if ( state == TRHostTorrent.TS_FAILED ){
state = TRHostTorrent.TS_STOPPED;
}
TOTorrent torrent = finder.lookupTorrent( hash );
if ( torrent == null && passive ){
byte[] file_b = (byte[])t_map.get( "torrent_file" );
if ( file_b != null ){
try{
File file = new File( new String( file_b, Constants.BYTE_ENCODING ));
torrent = TorrentUtils.readFromFile( file, true, true );
}catch( Throwable e ){
// torrent might have been deleted, don't barf out errors
// Debug.printStackTrace( e );
}
}
}
if ( torrent != null ){
TRHostTorrent ht = host.addTorrent( torrent, state, true, passive, date_added );
if ( ht instanceof TRHostTorrentHostImpl ){
TRHostTorrentHostImpl hth = (TRHostTorrentHostImpl)ht;
recoverStats( hth, t_map );
}
}else{
if ( COConfigurationManager.getBooleanParameter( "Tracker Public Enable")){
host.addExternalTorrent( hash, state, date_added );
}
}
}else{
// store stats for later
saved_stats.put( new HashWrapper( hash ), t_map );
}
}
}catch (Exception e) {
Debug.printStackTrace( e );
}finally{
loading = false;
this_mon.exit();
}
}
protected void
recoverStats(
TRHostTorrentHostImpl host_torrent )
{
try{
HashWrapper hash = host_torrent.getTorrent().getHashWrapper();
Map t_map = (Map)saved_stats.get( hash );
if ( t_map != null ){
saved_stats.remove( hash );
recoverStats( host_torrent, t_map );
}
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
private void
recoverStats(
TRHostTorrentHostImpl host_torrent,
Map t_map )
{
long completed = 0;
long announces = 0;
long scrapes = 0;
long total_up = 0;
long total_down = 0;
long bytes_in = 0;
long bytes_out = 0;
Long dateadded_l = (Long)t_map.get("dateadded");
long date_added = dateadded_l==null?SystemTime.getCurrentTime():dateadded_l.longValue();
Map s_map = (Map)t_map.get( "stats" );
if ( s_map != null ){
completed = ((Long)s_map.get( "completed")).longValue();
announces = ((Long)s_map.get( "announces")).longValue();
total_up = ((Long)s_map.get( "uploaded")).longValue();
total_down = ((Long)s_map.get( "downloaded")).longValue();
Long scrapes_l = (Long)s_map.get( "scrapes" );
if ( scrapes_l != null ){
scrapes = scrapes_l.longValue();
}
Long bytes_in_l = (Long)s_map.get( "bytesin" );
if ( bytes_in_l != null ){
bytes_in = bytes_in_l.longValue();
}
Long bytes_out_l = (Long)s_map.get( "bytesout" );
if ( bytes_out_l != null ){
bytes_out = bytes_out_l.longValue();
}
}
host_torrent.setStartOfDayValues( date_added, completed, announces, scrapes, total_up, total_down, bytes_in, bytes_out );
}
protected void
saveConfig(
boolean immediate )
{
if( loading ){
return;
}
if ( immediate || save_outstanding ){
save_outstanding = false;
try{
Map map = new HashMap();
List list = new ArrayList();
TRHostTorrent[] torrents = host.getTorrents();
List stats_entries = new ArrayList();
Set added = new HashSet();
for (int i = 0; i < torrents.length; i++){
try{
TRHostTorrent torrent = (TRHostTorrent)torrents[i];
added.add( torrent.getTorrent().getHashWrapper());
StringBuffer stats_entry = new StringBuffer(2048);
byte[] hash = torrent.getTorrent().getHash();
byte[] name = torrent.getTorrent().getName();
int status = torrent.getStatus();
long completed = torrent.getCompletedCount();
long announces = torrent.getAnnounceCount();
long scrapes = torrent.getScrapeCount();
long uploaded = torrent.getTotalUploaded();
long downloaded = torrent.getTotalDownloaded();
long bytes_in = torrent.getTotalBytesIn();
long bytes_out = torrent.getTotalBytesOut();
long date_added = torrent.getDateAdded();
int seed_count = torrent.getSeedCount();
int non_seed_count = torrent.getLeecherCount();
Map t_map = new HashMap();
t_map.put("persistent",new Long(torrent.isPersistent()?1:0));
t_map.put("passive",new Long(torrent.isPassive()?1:0));
if ( torrent.isPassive()){
try{
String file = TorrentUtils.getTorrentFileName( torrent.getTorrent());
t_map.put( "torrent_file", file.getBytes( Constants.BYTE_ENCODING ));
}catch( Throwable e ){
Debug.printStackTrace(e);
}
}
t_map.put("hash", hash );
t_map.put("dateadded", new Long(date_added));
t_map.put("status", new Long(status ));
list.add(t_map);
Map s_map = new HashMap();
t_map.put( "stats", s_map );
s_map.put( "completed", new Long(completed));
s_map.put( "announces", new Long(announces));
s_map.put( "scrapes", new Long(scrapes));
s_map.put( "uploaded", new Long(uploaded));
s_map.put( "downloaded", new Long(downloaded));
s_map.put( "bytesin", new Long(bytes_in));
s_map.put( "bytesout", new Long(bytes_out));
stats_entry.append( new String(name, Constants.DEFAULT_ENCODING ));
stats_entry.append(",");
stats_entry.append( ByteFormatter.nicePrint(hash,true));
stats_entry.append(",");
stats_entry.append(status);
stats_entry.append(",");
stats_entry.append(seed_count);
stats_entry.append(",");
stats_entry.append(non_seed_count);
stats_entry.append(",");
stats_entry.append(completed);
stats_entry.append(",");
stats_entry.append(announces);
stats_entry.append(",");
stats_entry.append(scrapes);
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtc(uploaded));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtc(downloaded));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtcPerSec(torrent.getAverageUploaded()));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtcPerSec(torrent.getAverageDownloaded()));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtc( torrent.getTotalLeft()));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtc( bytes_in ));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtc( bytes_out ));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtcPerSec(torrent.getAverageBytesIn()));
stats_entry.append(",");
stats_entry.append(DisplayFormatters.formatByteCountToKiBEtcPerSec(torrent.getAverageBytesOut()));
stats_entry.append( "\r\n");
stats_entries.add( stats_entry );
}catch( TOTorrentException e ){
Debug.printStackTrace( e );
}
}
// now save any non-recovered stats for a while in case the torrent
// gets re-added in the near future
Iterator it = saved_stats.keySet().iterator();
long now = SystemTime.getCurrentTime();
while ( it.hasNext()){
HashWrapper hash = (HashWrapper)it.next();
if ( added.contains( hash )){
continue;
}
Map t_map = (Map)saved_stats.get( hash );
Long backup = (Long)t_map.get("backup_time");
if ( backup == null ){
backup = new Long( now );
t_map.put( "backup_time", backup );
}
if ( now - backup.longValue() < BACKUP_RETENTION_PERIOD ){
list.add( t_map );
added.add( hash );
}
}
map.put("torrents", list);
try{
save_lock_mon.enter();
FileUtil.writeResilientConfigFile( "tracker.config", map );
if ( COConfigurationManager.getBooleanParameter( "Tracker Log Enable") &&
stats_entries.size() > 0 ){
try{
String timeStamp = "["+new SimpleDateFormat("dd-MMM-yyyy HH:mm:ss").format(new Date())+"] ";
PrintWriter pw = null;
File file_name = new File( log_dir.concat(File.separator).concat(LOG_FILE_NAME) );
try{
pw = new PrintWriter(new FileWriter( file_name, true ));
for (int i=0;i<stats_entries.size();i++){
StringBuffer stats_entry = (StringBuffer)stats_entries.get(i);
String str = timeStamp + stats_entry.toString();
pw.print( str );
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}finally{
if ( pw != null ){
try{
pw.close();
}catch( Throwable e ){
}
}
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}finally{
save_lock_mon.exit();
}
}catch( Throwable e ){
Debug.printStackTrace( e );
}
}
}
protected void
saveRequired()
{
save_outstanding = true;
}
}
|