@ -38,9 +38,9 @@ public class serverAccessTracker {
private long lastCleanup ;
private long lastCleanup ;
public static class Track {
public static class Track {
private long time ;
private final long time ;
private String path ;
private final String path ;
public Track ( long time , String path ) {
public Track ( final long time , final String path ) {
this . time = time ;
this . time = time ;
this . path = path ;
this . path = path ;
}
}
@ -52,7 +52,7 @@ public class serverAccessTracker {
}
}
}
}
public serverAccessTracker ( long maxTrackingTime , int maxTrackingCount , int maxTrackingHostCount ) {
public serverAccessTracker ( final long maxTrackingTime , final int maxTrackingCount , final int maxTrackingHostCount ) {
this . maxTrackingTime = maxTrackingTime ;
this . maxTrackingTime = maxTrackingTime ;
this . maxTrackingCount = maxTrackingCount ;
this . maxTrackingCount = maxTrackingCount ;
this . maxHostCount = maxTrackingHostCount ;
this . maxHostCount = maxTrackingHostCount ;
@ -68,7 +68,7 @@ public class serverAccessTracker {
this . lastCleanup = System . currentTimeMillis ( ) ;
this . lastCleanup = System . currentTimeMillis ( ) ;
// clear entries which had no entry for the maxTrackingTime time
// clear entries which had no entry for the maxTrackingTime time
final Iterator < Map . Entry < String , ConcurrentLinkedQueue < Track > > > i = accessTracker. entrySet ( ) . iterator ( ) ;
final Iterator < Map . Entry < String , ConcurrentLinkedQueue < Track > > > i = this . accessTracker. entrySet ( ) . iterator ( ) ;
ConcurrentLinkedQueue < Track > track ;
ConcurrentLinkedQueue < Track > track ;
while ( i . hasNext ( ) ) {
while ( i . hasNext ( ) ) {
track = i . next ( ) . getValue ( ) ;
track = i . next ( ) . getValue ( ) ;
@ -81,16 +81,16 @@ public class serverAccessTracker {
while ( track . size ( ) > this . maxTrackingCount ) try {
while ( track . size ( ) > this . maxTrackingCount ) try {
// delete the oldest entries
// delete the oldest entries
track . remove ( ) ;
track . remove ( ) ;
} catch ( NoSuchElementException e ) { break ; } // concurrency may cause that the track is already empty
} catch ( final NoSuchElementException e ) { break ; } // concurrency may cause that the track is already empty
}
}
}
}
// if there are more entries left than maxTrackingCount, delete some.
// if there are more entries left than maxTrackingCount, delete some.
while ( accessTracker. size ( ) > this . maxHostCount ) {
while ( this . accessTracker. size ( ) > this . maxHostCount ) {
// delete just any
// delete just any
String key = accessTracker. keys ( ) . nextElement ( ) ;
final String key = this . accessTracker. keys ( ) . nextElement ( ) ;
if ( key = = null ) break ; // may occur because of concurrency effects
if ( key = = null ) break ; // may occur because of concurrency effects
accessTracker. remove ( key ) ;
this . accessTracker. remove ( key ) ;
}
}
}
}
@ -100,20 +100,21 @@ public class serverAccessTracker {
* @param delta the time delta from now to the past where the access times shall be computed
* @param delta the time delta from now to the past where the access times shall be computed
* @return the number of accesses to the host in the given time span
* @return the number of accesses to the host in the given time span
* /
* /
public int latestAccessCount ( final String host , long delta ) {
public int latestAccessCount ( final String host , final long delta ) {
Collection < Track > timeList = accessTrack ( host ) ;
final Collection < Track > timeList = accessTrack ( host ) ;
if ( timeList = = null ) return 0 ;
if ( timeList = = null ) return 0 ;
long time = System . currentTimeMillis ( ) - delta ;
final long time = System . currentTimeMillis ( ) - delta ;
int c = 0 ;
int c = 0 ;
for ( Track l : timeList ) if ( l ! = null & & l . getTime ( ) > time ) c + + ;
for ( final Track l : timeList ) if ( l ! = null & & l . getTime ( ) > time ) c + + ;
return c ;
return c ;
}
}
private void clearTooOldAccess ( final ConcurrentLinkedQueue < Track > access ) {
private void clearTooOldAccess ( final ConcurrentLinkedQueue < Track > access ) {
Long time = Long . valueOf ( System . currentTimeMillis ( ) - maxTrackingTime ) ;
final long time = System . currentTimeMillis ( ) - this . maxTrackingTime ;
Iterator < Track > e = access . iterator ( ) ;
final Iterator < Track > e = access . iterator ( ) ;
Track l ;
Track l ;
while ( e . hasNext ( ) ) {
int max = access . size ( ) ; // ensure termination
while ( e . hasNext ( ) & & max - - > 0 ) {
l = e . next ( ) ;
l = e . next ( ) ;
if ( l . getTime ( ) < = time ) e . remove ( ) ;
if ( l . getTime ( ) < = time ) e . remove ( ) ;
}
}
@ -127,12 +128,12 @@ public class serverAccessTracker {
// learn that a specific host has accessed a specific path
// learn that a specific host has accessed a specific path
if ( accessPath = = null ) accessPath = "NULL" ;
if ( accessPath = = null ) accessPath = "NULL" ;
ConcurrentLinkedQueue < Track > track = accessTracker. get ( host ) ;
ConcurrentLinkedQueue < Track > track = this . accessTracker. get ( host ) ;
if ( track = = null ) {
if ( track = = null ) {
track = new ConcurrentLinkedQueue < Track > ( ) ;
track = new ConcurrentLinkedQueue < Track > ( ) ;
track . add ( new Track ( System . currentTimeMillis ( ) , accessPath ) ) ;
track . add ( new Track ( System . currentTimeMillis ( ) , accessPath ) ) ;
// add to tracker
// add to tracker
accessTracker. put ( host , track ) ;
this . accessTracker. put ( host , track ) ;
} else {
} else {
track . add ( new Track ( System . currentTimeMillis ( ) , accessPath ) ) ;
track . add ( new Track ( System . currentTimeMillis ( ) , accessPath ) ) ;
clearTooOldAccess ( track ) ;
clearTooOldAccess ( track ) ;
@ -142,12 +143,12 @@ public class serverAccessTracker {
public Collection < Track > accessTrack ( final String host ) {
public Collection < Track > accessTrack ( final String host ) {
// returns mapping from Long(accesstime) to path
// returns mapping from Long(accesstime) to path
ConcurrentLinkedQueue < Track > access = accessTracker. get ( host ) ;
final ConcurrentLinkedQueue < Track > access = this . accessTracker. get ( host ) ;
if ( access = = null ) return null ;
if ( access = = null ) return null ;
// clear too old entries
// clear too old entries
clearTooOldAccess ( access ) ;
clearTooOldAccess ( access ) ;
if ( access . isEmpty ( ) ) {
if ( access . isEmpty ( ) ) {
accessTracker. remove ( host ) ;
this . accessTracker. remove ( host ) ;
}
}
return access ;
return access ;
}
}
@ -155,7 +156,7 @@ public class serverAccessTracker {
public Iterator < String > accessHosts ( ) {
public Iterator < String > accessHosts ( ) {
// returns an iterator of hosts in tracker (String)
// returns an iterator of hosts in tracker (String)
final Map < String , ConcurrentLinkedQueue < Track > > accessTrackerClone = new ConcurrentHashMap < String , ConcurrentLinkedQueue < Track > > ( ) ;
final Map < String , ConcurrentLinkedQueue < Track > > accessTrackerClone = new ConcurrentHashMap < String , ConcurrentLinkedQueue < Track > > ( ) ;
accessTrackerClone . putAll ( accessTracker) ;
accessTrackerClone . putAll ( this . accessTracker) ;
return accessTrackerClone . keySet ( ) . iterator ( ) ;
return accessTrackerClone . keySet ( ) . iterator ( ) ;
}
}
}
}