package com.limegroup.gnutella.spam; /** * An abstract Token class, we are using this for the common age() & getAge() classes */ public abstract class AbstractToken implements Token { /* Number of LW sessions since this token has been created */ protected byte _age; /* Used to cache getImportance() */ protected transient double _importance = Double.NaN; AbstractToken() { _age = 0; } /** * implements interface <tt>Token</tt> */ public void incrementAge() { if (_age < Byte.MAX_VALUE) { synchronized (this) { ++_age; } // Mark _importance to be lazily calculated when needed _importance = Double.NaN; } } /** * implements interface <tt>Token</tt> */ public double getImportance() { // Avoid race conditions by using a local variable double importance = _importance; if (importance == Double.NaN) { // This implements -1 * Gregorio's original misnamed "age()" method. // Store bad ratings longer than good ratings since our filter relies // mostly on bad ratings. importance = (_age * -100.0 * (0.1 + Math.pow(1.0 - getRating(), 0.1))); _importance = importance; } return importance; } /** * implements interface <tt>Comparable</tt> */ public int compareTo(Object o) { // This may throw a class cast exception, // copying the Java 1.5 semantics of Comparable Token t = (Token) o; // First, sort by importance double importanceDelta = this.getImportance() - t.getImportance(); // Sort low importance first if (importanceDelta < 0.0) return -1; if (importanceDelta > 0.0) return 1; // Then, sort by type int typeDelta = this.getType() - t.getType(); if (typeDelta != 0) return typeDelta; // Finally, sort by hashCode to reduce ambiguity return this.hashCode() - t.hashCode(); } }