-
Notifications
You must be signed in to change notification settings - Fork 29
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Kill SQL cache ( Hibernate soon ™️ )
- Loading branch information
Showing
7 changed files
with
217 additions
and
1,110 deletions.
There are no files selected for viewing
166 changes: 63 additions & 103 deletions
166
src/main/java/no/stelar7/api/l4j8/basic/cache/CacheProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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
113
src/main/java/no/stelar7/api/l4j8/basic/cache/MemoryCacheProvider.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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()); | ||
} | ||
} | ||
} | ||
} |
Oops, something went wrong.