I have a table with 4 string columns in database, each row represent blocked user or group.
referrer | ip | userAgent | email
By group I mean that one of the columns (any) can have wild card (asterisk) which mean "block all of them"
for example this row
www.google.com | 127.0.0.2 | * | yahoo.com
Means that each user request with "google.com" as referrer, "127.0.0.2" asIP & "yahoo.com" as email, need to be blocked without consider UserAgent because it has wild card
The following code works in O(n) complexity, which is good enough for a small size table but my table contains over million rows
class BlacklistEntry {
private String referrer, ip, userAgent, email;
private static List<BlacklistEntry> cache = new ArrayList<>();
BlacklistEntry(String referrer, String ip, String userAgent, String email) {
this.referrer = referrer;
this.ip = ip;
this.userAgent = userAgent;
this.email = email;
}
private static boolean isBlacklisted(String ref, String ip, String ue, String email) {
final String MATCH_ALL = "*";
return cache.stream()
.filter(e ->
(MATCH_ALL.equals(e.getReferrer()) || e.getReferrer().equals(ref)) &&
(MATCH_ALL.equals(e.getIp()) || e.getIp().equals(ip)) &&
(MATCH_ALL.equals(e.getUserAgent()) || e.getUserAgent().equals(ue)) &&
(MATCH_ALL.equals(e.getEmail()) || e.getEmail().equals(email)))
.findFirst()
.isPresent();
}
public String getReferrer() {
return referrer;
}
public void setReferrer(String referrer) {
this.referrer = referrer;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getUserAgent() {
return userAgent;
}
public void setUserAgent(String userAgent) {
this.userAgent = userAgent;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public static void main(String[] args) {
cache.add(new BlacklistEntry("google.com", "127.0.0.2", "Mozilla", "yahoo.com"));
cache.add(new BlacklistEntry("r1.com", "127.0.0.3", "Mozilla", "*"));
cache.add(new BlacklistEntry("r2.com", "127.0.0.4", "Mozilla", "yahoo.com"));
System.out.println(isBlacklisted("r2.com", "127.0.0.4", "Mozilla", "yahoo.com"));
System.out.println(isBlacklisted("r1.com", "127.0.0.3", "Mozilla", "sould be true"));
System.out.println(isBlacklisted("*", "127.0.0.3", "*", "*"));
}
}
Is there something better than O(n) ? should I consider using Lucene ?