| Index: src/org/adblockplus/android/AdblockPlus.java |
| =================================================================== |
| --- a/src/org/adblockplus/android/AdblockPlus.java |
| +++ b/src/org/adblockplus/android/AdblockPlus.java |
| @@ -23,7 +23,14 @@ |
| import java.io.IOException; |
| import java.io.InputStream; |
| import java.io.InputStreamReader; |
| +import java.util.ArrayList; |
| import java.util.Calendar; |
| +import java.util.Collections; |
| +import java.util.HashSet; |
| +import java.util.LinkedHashMap; |
| +import java.util.List; |
| +import java.util.Map; |
| +import java.util.Set; |
| import java.util.TimeZone; |
| import java.util.regex.Pattern; |
| @@ -84,6 +91,25 @@ |
| private ABPEngine abpEngine; |
| private static AdblockPlus instance; |
| + |
| + private static class ReferrerMappingCache extends LinkedHashMap<String, Set<String>> |
| + { |
| + private static final long serialVersionUID = 1L; |
| + private static final int MAX_SIZE = 2; |
|
Felix Dahlke
2013/11/27 12:19:33
Note that I've set this to 5000, not 2. I'd rather
Wladimir Palant
2013/11/27 12:59:01
I think that "how much memory can we sacrifice" is
Felix Dahlke
2013/11/27 13:38:59
I think we're still not on the same page here. IMO
|
| + |
| + public ReferrerMappingCache() |
| + { |
| + super(MAX_SIZE, 0.75f, true); |
|
Wladimir Palant
2013/11/27 12:59:01
I think that the first parameter should be MAX_SIZ
Felix Dahlke
2013/11/27 13:38:59
Done.
|
| + } |
| + |
| + @Override |
| + protected boolean removeEldestEntry(Map.Entry<String, Set<String>> eldest) |
| + { |
| + return size() > MAX_SIZE; |
| + } |
| + }; |
| + |
| + private ReferrerMappingCache referrerMapping = new ReferrerMappingCache(); |
| /** |
| * Returns pointer to itself (singleton pattern). |
| @@ -338,6 +364,9 @@ |
| */ |
| public boolean matches(String url, String query, String referrer, String accept) |
| { |
| + if (referrer != null) |
| + recordReferrer(url, referrer); |
| + |
| if (!filteringEnabled) |
| return false; |
| @@ -368,7 +397,48 @@ |
| if (!"".equals(query)) |
| url = url + "?" + query; |
| - return abpEngine.matches(url, contentType, referrer); |
| + final List<List<String>> referrerChains = referrer != null |
| + ? buildReferrerChains(referrer) |
| + : Collections.singletonList(Collections.<String>emptyList()); |
| + for (List<String> referrerChain : referrerChains) |
| + { |
| + Log.d("Referrer chain", url + ": " + referrerChain.toString()); |
| + String[] referrerChainArray = referrerChain.toArray(new String[referrerChain.size()]); |
| + if (abpEngine.matches(url, contentType, referrerChainArray)) |
| + return true; |
| + } |
| + return false; |
| + } |
| + |
| + private void recordReferrer(String url, String referrer) |
| + { |
| + if (!referrerMapping.containsKey(url)) |
| + referrerMapping.put(url, new HashSet<String>()); |
| + Set<String> referrers = referrerMapping.get(url); |
| + referrers.add(referrer); |
| + } |
| + |
| + private List<List<String>> buildReferrerChains(String url) |
| + { |
| + List<List<String>> referrerChains = new ArrayList<List<String>>(); |
| + Set<String> referrers = referrerMapping.get(url); |
| + if (referrers == null) |
| + { |
| + List<String> referrerChain = new ArrayList<String>(); |
| + referrerChain.add(url); |
| + referrerChains.add(referrerChain); |
| + return referrerChains; |
| + } |
| + |
| + for (String referrer : referrers) { |
| + List<List<String>> currentReferrerChains = buildReferrerChains(referrer); |
| + for (List<String> referrerChain : currentReferrerChains) |
| + { |
| + referrerChain.add(0, url); |
| + referrerChains.add(referrerChain); |
| + } |
| + } |
| + return referrerChains; |
| } |
| /** |