/* This code is part of Freenet. It is distributed under the GNU General
* Public License, version 2 (or at your option any later version). See
* http://www.gnu.org/ for further details of the GPL. */
package freenet.client;
import java.io.Serializable;
import java.util.HashSet;
import freenet.keys.FreenetURI;
/**
* @author amphibian (Matthew Toseland)
*
* Object passed down a full fetch, including all the recursion.
* Used, at present, for detecting archive fetch loops, hence the
* name.
*
* WARNING: Changing non-transient members on classes that are Serializable can result in
* restarting downloads or losing uploads.
*/
public class ArchiveContext implements Serializable {
private static final long serialVersionUID = 1L;
private HashSet<FreenetURI> soFar;
final int maxArchiveLevels;
final long maxArchiveSize;
public ArchiveContext(long maxArchiveSize, int max) {
this.maxArchiveLevels = max;
this.maxArchiveSize = maxArchiveSize;
}
protected ArchiveContext() {
// For serialization.
maxArchiveLevels = 0;
maxArchiveSize = 0;
}
/**
* Check for a loop.
*
* The URI provided is expected to be a reasonably unique identifier for the archive.
*/
public synchronized void doLoopDetection(FreenetURI key) throws ArchiveFailureException {
if(soFar == null) {
soFar = new HashSet<FreenetURI>();
}
if(soFar.size() > maxArchiveLevels)
throw new ArchiveFailureException(ArchiveFailureException.TOO_MANY_LEVELS);
FreenetURI uri = key;
if(!soFar.add(uri)) {
throw new ArchiveFailureException(ArchiveFailureException.ARCHIVE_LOOP_DETECTED);
}
}
public synchronized void clear() {
soFar = null;
}
}