Skip to content

Commit

Permalink
Clean cache code
Browse files Browse the repository at this point in the history
Kill SQL cache ( Hibernate soon ™️ )
  • Loading branch information
stelar7 committed Aug 7, 2017
1 parent 22089a3 commit 8c18886
Show file tree
Hide file tree
Showing 7 changed files with 217 additions and 1,110 deletions.
166 changes: 63 additions & 103 deletions src/main/java/no/stelar7/api/l4j8/basic/cache/CacheProvider.java
Original file line number Diff line number Diff line change
@@ -1,150 +1,110 @@
package no.stelar7.api.l4j8.basic.cache;

import no.stelar7.api.l4j8.basic.constants.api.URLEndpoint;
import no.stelar7.api.l4j8.pojo.match.Match;
import no.stelar7.api.l4j8.pojo.summoner.Summoner;

import java.time.*;
import java.util.*;
import java.util.Map.Entry;
import java.util.Optional;
import java.util.concurrent.*;

public abstract class CacheProvider
{

long timeToLive = -1;

public abstract void store(URLEndpoint clazz, Object obj);
/**
* Stores the obj in the type cache
*
* @param type the endpoint to store the cache in
* @param obj the object to store
*/
public abstract void store(URLEndpoint type, Object obj);

/**
* Returns data from the cache if found, otherwise Optional.empty();
*
* @param type the endpoint to get data from
* @param data the data to look for
* @return return type depends on the endpoint called
*/
public abstract Optional<?> get(URLEndpoint type, Object... data);

/**
* Empties the entire cache for that endpoint
*
* @param type the endpoint
*/
public abstract void clear(URLEndpoint type);

/**
* Removes any old items frcm the cache
*/
public abstract void clearOldCache();

protected CacheProvider(long timeToLive)
private ScheduledExecutorService clearService = Executors.newScheduledThreadPool(1);
private ScheduledFuture<?> clearTask;
protected long timeToLive;

public long getTimeToLive()
{
return timeToLive;
}

/**
* Returns the count of items in the cache
*
* @return long
*/
public abstract long getSize();


/**
* Sets the timeout for caches
*
* @param timeToLive how long they should live
*/
public void setTimeToLive(long timeToLive)
{
this.timeToLive = timeToLive;

if (timeToLive > 0)
{
ScheduledExecutorService clearService = Executors.newScheduledThreadPool(1);
clearService.scheduleAtFixedRate(this::clearOldCache, timeToLive, timeToLive, TimeUnit.SECONDS);
clearTask = clearService.scheduleAtFixedRate(this::clearOldCache, timeToLive, timeToLive, TimeUnit.SECONDS);
} else
{
if (clearTask != null)
{
clearTask.cancel(false);
}
}
}

public static final CacheProvider EMPTY = new CacheProvider(-1)
public static class EmptyProvider extends CacheProvider
{
@Override
public void store(URLEndpoint clazz, Object obj) { /*void cache*/}
public static final EmptyProvider INSTANCE = new EmptyProvider();

@Override
public Optional<?> get(URLEndpoint type, Object... data)
private EmptyProvider()
{
return Optional.empty();
// Hide public constructor
}

@Override
public void clear(URLEndpoint type)
{/*void*/}

@Override
public void clearOldCache()
{/*void*/}
};


public static final CacheProvider MEMORY = new CacheProvider(3600)
{
private Map<Summoner, LocalDateTime> summoners = new HashMap<>();
private Map<Match, LocalDateTime> matches = new HashMap<>();

@Override
public void store(URLEndpoint type, Object obj)
{
switch (type)
{
case V3_SUMMONER_BY_ACCOUNT:
case V3_SUMMONER_BY_NAME:
case V3_SUMMONER_BY_ID:
summoners.put((Summoner) obj, LocalDateTime.now());
break;
case V3_MATCH:
matches.put((Match) obj, LocalDateTime.now());
break;
default:
break;
}
}
public void store(URLEndpoint clazz, Object obj) { /*void cache*/}

@Override
public Optional<?> get(URLEndpoint type, Object... data)
{
switch (type)
{
case V3_SUMMONER_BY_ACCOUNT:
return summoners.keySet().stream().filter(s -> s.getPlatform().equals(data[0])).filter(s -> data[1].equals(s.getAccountId())).findFirst();
case V3_SUMMONER_BY_NAME:
return summoners.keySet().stream().filter(s -> s.getPlatform().equals(data[0])).filter(s -> data[1].equals(s.getName())).findFirst();
case V3_SUMMONER_BY_ID:
return summoners.keySet().stream().filter(s -> s.getPlatform().equals(data[0])).filter(s -> data[1].equals(s.getSummonerId())).findFirst();
case V3_MATCH:
return matches.keySet().stream().filter(m -> m.getPlatform().equals(data[0])).filter(m -> data[1].equals(m.getMatchId())).findFirst();
default:
break;
}

return Optional.empty();
}

@Override
public void clear(URLEndpoint type)
{
switch (type)
{
case V3_SUMMONER_BY_ACCOUNT:
case V3_SUMMONER_BY_NAME:
case V3_SUMMONER_BY_ID:
summoners.clear();
break;
case V3_MATCH:
matches.clear();
break;
default:
break;
}
}
{/*void*/}

@Override
public void clearOldCache()
{
long livingCount = matches.size();

clearOldCache(summoners);
clearOldCache(matches);

System.out.println("killed caches: " + (livingCount - matches.size()));
}
{/*void*/}

private void clearOldCache(Map<?, LocalDateTime> data)
@Override
public long getSize()
{
List<Entry<?, LocalDateTime>> list = new ArrayList<>(data.entrySet());
list.sort(Comparator.comparing(Entry::getValue));

for (Entry<?, LocalDateTime> entry : list)
{
long life = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli() - entry.getValue().toInstant(ZoneOffset.UTC).toEpochMilli();

if (timeToLive < life)
{
data.remove(entry.getKey());
}
}
return 0;
}
};

public long getTimeToLive()
{
return timeToLive;
}
}
113 changes: 113 additions & 0 deletions src/main/java/no/stelar7/api/l4j8/basic/cache/MemoryCacheProvider.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
package no.stelar7.api.l4j8.basic.cache;

import no.stelar7.api.l4j8.basic.constants.api.URLEndpoint;
import no.stelar7.api.l4j8.pojo.match.Match;
import no.stelar7.api.l4j8.pojo.summoner.Summoner;

import java.time.*;
import java.util.*;
import java.util.Map.Entry;

public class MemoryCacheProvider extends CacheProvider
{
private Map<Summoner, LocalDateTime> summoners = new HashMap<>();
private Map<Match, LocalDateTime> matches = new HashMap<>();

/**
* Creates a memory cache, where items expire after ttl seconds
*
* @param ttl the amount of time to keep cached items (in seconds)
*/
public MemoryCacheProvider(long ttl)
{
setTimeToLive(ttl);
}

@Override
public void store(URLEndpoint type, Object obj)
{
switch (type)
{
case V3_SUMMONER_BY_ACCOUNT:
case V3_SUMMONER_BY_NAME:
case V3_SUMMONER_BY_ID:
summoners.put((Summoner) obj, LocalDateTime.now());
break;
case V3_MATCH:
matches.put((Match) obj, LocalDateTime.now());
break;
default:
break;
}
}

@Override
public Optional<?> get(URLEndpoint type, Object... data)
{
switch (type)
{
case V3_SUMMONER_BY_ACCOUNT:
return summoners.keySet().stream().filter(s -> s.getPlatform().equals(data[0])).filter(s -> data[1].equals(s.getAccountId())).findFirst();
case V3_SUMMONER_BY_NAME:
return summoners.keySet().stream().filter(s -> s.getPlatform().equals(data[0])).filter(s -> data[1].equals(s.getName())).findFirst();
case V3_SUMMONER_BY_ID:
return summoners.keySet().stream().filter(s -> s.getPlatform().equals(data[0])).filter(s -> data[1].equals(s.getSummonerId())).findFirst();
case V3_MATCH:
return matches.keySet().stream().filter(m -> m.getPlatform().equals(data[0])).filter(m -> data[1].equals(m.getMatchId())).findFirst();
default:
break;
}

return Optional.empty();
}

@Override
public void clear(URLEndpoint type)
{
switch (type)
{
case V3_SUMMONER_BY_ACCOUNT:
case V3_SUMMONER_BY_NAME:
case V3_SUMMONER_BY_ID:
summoners.clear();
break;
case V3_MATCH:
matches.clear();
break;
default:
break;
}
}

@Override
public void clearOldCache()
{
clearOldCache(summoners);
clearOldCache(matches);
}

@Override
public long getSize()
{
long size = 0;
size += summoners.size();
size += matches.size();
return size;
}

private void clearOldCache(Map<?, LocalDateTime> data)
{
List<Entry<?, LocalDateTime>> list = new ArrayList<>(data.entrySet());
list.sort(Comparator.comparing(Entry::getValue));

for (Entry<?, LocalDateTime> entry : list)
{
long life = LocalDateTime.now().toInstant(ZoneOffset.UTC).toEpochMilli() - entry.getValue().toInstant(ZoneOffset.UTC).toEpochMilli();

if (timeToLive < life)
{
data.remove(entry.getKey());
}
}
}
}
Loading

0 comments on commit 8c18886

Please sign in to comment.