Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 24 additions & 7 deletions src/main/java/ua_parser/CachingParser.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,15 +14,19 @@
* the need to parse the same useragent over and over again.
*
* This class introduces a very simple LRU cache to reduce the number of times
* the parsing is actually done.
* the parsing is actually done. The default cache size is 1000 and can be
* configured as object creation.
*
* Note: The object handles one cache per parsing method - be carefull when using big sizes.
*
* @author Niels Basjes
*
*/
public class CachingParser extends Parser {

// TODO: Make configurable
private static final int CACHE_SIZE = 1000;
private static final String INVALID_CACHE_SIZE_ERROR_MESSAGE = "Invalid cache size provided - Should be greater than 0";

private int cacheSize = 1000;

private Map<String, Client> cacheClient = null;
private Map<String, UserAgent> cacheUserAgent = null;
Expand All @@ -39,6 +43,19 @@ public CachingParser(InputStream regexYaml) {
super(regexYaml);
}

public CachingParser(int cacheSize) throws IOException {
super();
assert cacheSize > 0: INVALID_CACHE_SIZE_ERROR_MESSAGE;
this.cacheSize = cacheSize;
}

public CachingParser(InputStream regexYaml, int cacheSize) {
super(regexYaml);
assert cacheSize > 0: INVALID_CACHE_SIZE_ERROR_MESSAGE;
this.cacheSize = cacheSize;
}


// ------------------------------------------

@Override
Expand All @@ -47,7 +64,7 @@ public Client parse(String agentString) {
return null;
}
if (cacheClient == null) {
cacheClient = new LRUMap<>(CACHE_SIZE);
cacheClient = new LRUMap<>(cacheSize);
}
Client client = cacheClient.get(agentString);
if (client != null) {
Expand All @@ -66,7 +83,7 @@ public UserAgent parseUserAgent(String agentString) {
return null;
}
if (cacheUserAgent == null) {
cacheUserAgent = new LRUMap<>(CACHE_SIZE);
cacheUserAgent = new LRUMap<>(cacheSize);
}
UserAgent userAgent = cacheUserAgent.get(agentString);
if (userAgent != null) {
Expand All @@ -85,7 +102,7 @@ public Device parseDevice(String agentString) {
return null;
}
if (cacheDevice == null) {
cacheDevice = new LRUMap<>(CACHE_SIZE);
cacheDevice = new LRUMap<>(cacheSize);
}
Device device = cacheDevice.get(agentString);
if (device != null) {
Expand All @@ -105,7 +122,7 @@ public OS parseOS(String agentString) {
}

if (cacheOS == null) {
cacheOS = new LRUMap<>(CACHE_SIZE);
cacheOS = new LRUMap<>(cacheSize);
}
OS os = cacheOS.get(agentString);
if (os != null) {
Expand Down
10 changes: 10 additions & 0 deletions src/test/java/ua_parser/CachingParserTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,16 @@ Parser parserFromStringConfig(String configYamlAsString) throws Exception {
return new CachingParser(yamlInput);
}

@Test
public void testCachingParserCorrectSizeInit() throws Exception {
parser = new CachingParser(10);
}

@Test (expected = java.lang.AssertionError.class)
public void testCachingParserIncorrectSizeInit() throws Exception{
parser = new CachingParser(0);
}

@Test
public void testCachedParseUserAgent() {
super.testParseUserAgent();
Expand Down