diff --git a/htroot/AccessTracker_p.java b/htroot/AccessTracker_p.java index ffc9453ab..85c01ec40 100644 --- a/htroot/AccessTracker_p.java +++ b/htroot/AccessTracker_p.java @@ -28,10 +28,10 @@ import java.util.ArrayList; import java.util.ConcurrentModificationException; import java.util.Date; import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.Locale; import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; import java.util.TreeSet; import java.util.Map.Entry; import java.text.SimpleDateFormat; @@ -40,23 +40,25 @@ import de.anomic.http.server.RequestHeader; import de.anomic.net.natLib; import de.anomic.search.QueryParams; import de.anomic.search.Switchboard; +import de.anomic.server.serverAccessTracker; import de.anomic.server.serverCore; import de.anomic.server.serverObjects; import de.anomic.server.serverSwitch; +import de.anomic.server.serverAccessTracker.Track; import de.anomic.yacy.yacySeed; public class AccessTracker_p { private static SimpleDateFormat SimpleFormatter = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss", Locale.US); - - private static final SortedMap treemapclone(final SortedMap m) { - final TreeMap accessClone = new TreeMap(); - try { - accessClone.putAll(m); - } catch (final ConcurrentModificationException e) {} - return accessClone; + + private static final List listclone(final List m) { + final List accessClone = new LinkedList(); + try { + accessClone.addAll(m); + } catch (final ConcurrentModificationException e) {} + return accessClone; } - + public static serverObjects respond(final RequestHeader header, final serverObjects post, final serverSwitch env) { final Switchboard sb = (Switchboard) env; @@ -72,17 +74,17 @@ public class AccessTracker_p { if (page == 0) { final Iterator i = sb.accessHosts(); String host; - SortedMap access; + List access; int entCount = 0; try { while ((entCount < maxCount) && (i.hasNext())) { host = i.next(); access = sb.accessTrack(host); prop.putHTML("page_list_" + entCount + "_host", host); - prop.putNum("page_list_" + entCount + "_countSecond", access.tailMap(Long.valueOf(System.currentTimeMillis() - 1000)).size()); - prop.putNum("page_list_" + entCount + "_countMinute", access.tailMap(Long.valueOf(System.currentTimeMillis() - 1000 * 60)).size()); - prop.putNum("page_list_" + entCount + "_count10Minutes", access.tailMap(Long.valueOf(System.currentTimeMillis() - 1000 * 60 * 10)).size()); - prop.putNum("page_list_" + entCount + "_countHour", access.tailMap(Long.valueOf(System.currentTimeMillis() - 1000 * 60 * 60)).size()); + prop.putNum("page_list_" + entCount + "_countSecond", serverAccessTracker.tailList(access, Long.valueOf(System.currentTimeMillis() - 1000)).size()); + prop.putNum("page_list_" + entCount + "_countMinute", serverAccessTracker.tailList(access, Long.valueOf(System.currentTimeMillis() - 1000 * 60)).size()); + prop.putNum("page_list_" + entCount + "_count10Minutes", serverAccessTracker.tailList(access, Long.valueOf(System.currentTimeMillis() - 1000 * 60 * 10)).size()); + prop.putNum("page_list_" + entCount + "_countHour", serverAccessTracker.tailList(access, Long.valueOf(System.currentTimeMillis() - 1000 * 60 * 60)).size()); entCount++; } } catch (final ConcurrentModificationException e) {} // we don't want to synchronize this @@ -102,18 +104,18 @@ public class AccessTracker_p { if (page == 1) { String host = (post == null) ? "" : post.get("host", ""); int entCount = 0; - SortedMap access; - Map.Entry entry; + List access; + Track entry; if (host.length() > 0) { access = sb.accessTrack(host); if (access != null) { try { - final Iterator> ii = treemapclone(access).entrySet().iterator(); + final Iterator ii = listclone(access).iterator(); while (ii.hasNext()) { entry = ii.next(); prop.putHTML("page_list_" + entCount + "_host", host); - prop.put("page_list_" + entCount + "_date", SimpleFormatter.format(new Date((entry.getKey()).longValue()))); - prop.putHTML("page_list_" + entCount + "_path", entry.getValue()); + prop.put("page_list_" + entCount + "_date", SimpleFormatter.format(new Date(entry.getTime()))); + prop.putHTML("page_list_" + entCount + "_path", entry.getPath()); entCount++; } } catch (final ConcurrentModificationException e) {} // we don't want to synchronize this @@ -124,12 +126,12 @@ public class AccessTracker_p { while ((entCount < maxCount) && (i.hasNext())) { host = i.next(); access = sb.accessTrack(host); - final Iterator> ii = treemapclone(access).entrySet().iterator(); + final Iterator ii = listclone(access).iterator(); while (ii.hasNext()) { entry = ii.next(); prop.putHTML("page_list_" + entCount + "_host", host); - prop.put("page_list_" + entCount + "_date", SimpleFormatter.format(new Date((entry.getKey()).longValue()))); - prop.putHTML("page_list_" + entCount + "_path", entry.getValue()); + prop.put("page_list_" + entCount + "_date", SimpleFormatter.format(new Date(entry.getTime()))); + prop.putHTML("page_list_" + entCount + "_path", entry.getPath()); entCount++; } } diff --git a/source/de/anomic/server/serverAccessTracker.java b/source/de/anomic/server/serverAccessTracker.java index 7ce7226c1..215f23820 100644 --- a/source/de/anomic/server/serverAccessTracker.java +++ b/source/de/anomic/server/serverAccessTracker.java @@ -22,9 +22,9 @@ package de.anomic.server; import java.util.HashMap; import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; import java.util.Map; -import java.util.SortedMap; -import java.util.TreeMap; import java.util.concurrent.ConcurrentHashMap; import net.yacy.kelondro.logging.Log; @@ -36,14 +36,29 @@ public class serverAccessTracker { private final long maxTrackingTime; private final int maxTrackingCount; private final int maxHostCount; - private final ConcurrentHashMap> accessTracker; // mappings from requesting host to an ArrayList of serverTrack-entries + private final ConcurrentHashMap> accessTracker; // mappings from requesting host to an ArrayList of serverTrack-entries private long lastCleanup; + public static class Track { + private long time; + private String path; + public Track(long time, String path) { + this.time = time; + this.path = path; + } + public long getTime() { + return this.time; + } + public String getPath() { + return this.path; + } + } + public serverAccessTracker(long maxTrackingTime, int maxTrackingCount, int maxTrackingHostCount) { this.maxTrackingTime = maxTrackingTime; this.maxTrackingCount = maxTrackingCount; this.maxHostCount = maxTrackingHostCount; - this.accessTracker = new ConcurrentHashMap>(); + this.accessTracker = new ConcurrentHashMap>(); } /* @@ -54,18 +69,18 @@ public class serverAccessTracker { if (System.currentTimeMillis() - this.lastCleanup < cleanupCycle) return; // clear entries which had no entry for the maxTrackingTime time - final Iterator>> i = accessTracker.entrySet().iterator(); - SortedMap track; + final Iterator>> i = accessTracker.entrySet().iterator(); + List track; while (i.hasNext()) { track = i.next().getValue(); - if (track.tailMap(Long.valueOf(System.currentTimeMillis() - maxTrackingTime)).isEmpty()) { + if (tailList(track, Long.valueOf(System.currentTimeMillis() - maxTrackingTime)).isEmpty()) { // all entries are too old. delete the whole track i.remove(); } else { // check if the maxTrackingCount is exceeded while (track.size() > this.maxTrackingCount) { // delete the oldest entries - track.remove(track.firstKey()); + track.remove(0); } } } @@ -78,39 +93,47 @@ public class serverAccessTracker { this.lastCleanup = System.currentTimeMillis(); } + + public static List tailList(List timeList, long time) { + List t = new LinkedList(); + for (Track l: timeList) if (l.getTime() > time) t.add(l); + return t; + } - private SortedMap clearTooOldAccess(final SortedMap access) { + private List clearTooOldAccess(final List access) { try { - return access.tailMap(Long.valueOf(System.currentTimeMillis() - maxTrackingTime)); + return tailList(access, Long.valueOf(System.currentTimeMillis() - maxTrackingTime)); } catch (IllegalArgumentException e) { Log.logException(e); - return new TreeMap(); + return new LinkedList(); } } public void track(final String host, String accessPath) { // check storage size - if (System.currentTimeMillis() - this.lastCleanup > cleanupCycle) { - cleanupAccessTracker(); - this.lastCleanup = System.currentTimeMillis(); + if (System.currentTimeMillis() - this.lastCleanup > cleanupCycle) synchronized (this) { + if (System.currentTimeMillis() - this.lastCleanup > cleanupCycle) { + cleanupAccessTracker(); + this.lastCleanup = System.currentTimeMillis(); + } } // learn that a specific host has accessed a specific path if (accessPath == null) accessPath="NULL"; - SortedMap track = accessTracker.get(host); - if (track == null) track = new TreeMap(); + List track = accessTracker.get(host); + if (track == null) track = new LinkedList(); synchronized (track) { - track.put(Long.valueOf(System.currentTimeMillis()), accessPath); + track.add(new Track(System.currentTimeMillis(), accessPath)); // write back to tracker accessTracker.put(host, clearTooOldAccess(track)); } } - public SortedMap accessTrack(final String host) { + public List accessTrack(final String host) { // returns mapping from Long(accesstime) to path - SortedMap access = accessTracker.get(host); + List access = accessTracker.get(host); if (access == null) return null; // clear too old entries synchronized (access) { @@ -128,7 +151,7 @@ public class serverAccessTracker { public Iterator accessHosts() { // returns an iterator of hosts in tracker (String) - final HashMap> accessTrackerClone = new HashMap>(); + final HashMap> accessTrackerClone = new HashMap>(); accessTrackerClone.putAll(accessTracker); return accessTrackerClone.keySet().iterator(); } diff --git a/source/de/anomic/server/serverSwitch.java b/source/de/anomic/server/serverSwitch.java index f1863d4bd..e7661d1c3 100644 --- a/source/de/anomic/server/serverSwitch.java +++ b/source/de/anomic/server/serverSwitch.java @@ -27,8 +27,8 @@ import java.net.InetAddress; import java.util.ArrayList; import java.util.HashMap; import java.util.Iterator; +import java.util.List; import java.util.Map; -import java.util.SortedMap; import java.util.TreeMap; import net.yacy.kelondro.logging.Log; @@ -37,6 +37,7 @@ import net.yacy.kelondro.util.FileUtils; import net.yacy.kelondro.workflow.BusyThread; import net.yacy.kelondro.workflow.WorkflowThread; +import de.anomic.server.serverAccessTracker.Track; import de.anomic.server.serverCore.Session; public class serverSwitch { @@ -531,7 +532,7 @@ public class serverSwitch { this.accessTracker.track(host, accessPath); } - public SortedMap accessTrack(String host) { + public List accessTrack(String host) { return this.accessTracker.accessTrack(host); }