Skip to content
This repository was archived by the owner on Apr 7, 2019. It is now read-only.

Commit

Permalink
use ehcache
Browse files Browse the repository at this point in the history
  • Loading branch information
naturefreshmilk committed Jul 17, 2018
1 parent fc518ee commit 24c0153
Show file tree
Hide file tree
Showing 9 changed files with 156 additions and 24 deletions.
8 changes: 8 additions & 0 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -137,6 +137,14 @@
<version>1.1.1</version>
</dependency>

<!-- Caching -->

<dependency>
<groupId>org.ehcache</groupId>
<artifactId>ehcache</artifactId>
<version>3.5.2</version>
</dependency>

</dependencies>

<build>
Expand Down
34 changes: 17 additions & 17 deletions src/main/java/io/rudin/minetest/tileserver/TileRenderer.java
Original file line number Diff line number Diff line change
Expand Up @@ -101,25 +101,25 @@ public byte[] render(int tileX, int tileY, int zoom) throws IllegalArgumentExcep

long start = System.currentTimeMillis();

Integer count = ctx
.select(DSL.count())
.from(BLOCKS)
.where(
BLOCKS.POSX.ge(Math.min(x1, x2))
.and(BLOCKS.POSX.le(Math.max(x1, x2)))
.and(BLOCKS.POSZ.ge(Math.min(z1, z2)))
.and(BLOCKS.POSZ.le(Math.max(z1, z2)))
.and(yCondition)
)
.fetchOne(DSL.count());
Result<BlocksRecord> firstResult = ctx
.selectFrom(BLOCKS)
.where(
BLOCKS.POSX.ge(Math.min(x1, x2))
.and(BLOCKS.POSX.le(Math.max(x1, x2)))
.and(BLOCKS.POSZ.ge(Math.min(z1, z2)))
.and(BLOCKS.POSZ.le(Math.max(z1, z2)))
.and(yCondition)
)
.limit(1)
.fetch();

long diff = System.currentTimeMillis() - start;

if (diff > 250 && cfg.logQueryPerformance()){
logger.warn("white-count-query took {} ms", diff);
}

if (count == 0) {
if (firstResult.isEmpty()) {
logger.debug("Fail-fast, got zero mapblock count for x={}-{} z={}-{}", x1,x2, z1,z2);

byte[] data = WhiteTile.getPNG();
Expand Down Expand Up @@ -293,15 +293,15 @@ public BufferedImage renderImage(int tileX, int tileY, int zoom) throws IllegalA
start = now;


Integer count = ctx
.select(DSL.count())
.from(BLOCKS)
Result<BlocksRecord> countList = ctx
.selectFrom(BLOCKS)
.where(
BLOCKS.POSX.eq(mapblockX)
.and(BLOCKS.POSZ.eq(mapblockZ))
.and(yCondition)
)
.fetchOne(DSL.count());
.limit(1)
.fetch();

now = System.currentTimeMillis();
long timingZeroCountCheck = now - start;
Expand All @@ -314,7 +314,7 @@ public BufferedImage renderImage(int tileX, int tileY, int zoom) throws IllegalA

long timingRender = 0;

if (count > 0) {
if (!countList.isEmpty()) {


blockRenderer.render(mapblockX, mapblockZ, graphics, 16);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,10 @@ public interface TileServerConfig extends Config {
@DefaultValue("2")
int playerUpdateInterval();

@Key("tile.route.reentrycount")
@DefaultValue("5000")
int tileRouteReentryCount();

/*
Logging stuff
*/
Expand All @@ -67,12 +71,13 @@ public interface TileServerConfig extends Config {
*/

@Key("tile.cache.impl")
@DefaultValue("FILE")
@DefaultValue("EHCACHE")
CacheType tileCacheType();

enum CacheType {
DATABASE,
FILE
FILE,
EHCACHE
}

@Key("tiles.directory")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -119,6 +119,12 @@ public void run() {
int count = blocks.size();
int invalidatedTiles = 0;

long diff = start - System.currentTimeMillis();

if (diff > 1000 && cfg.logQueryPerformance()){
logger.warn("updated-tiles-query took {} ms", diff);
}

if (blocks.size() == LIMIT) {
logger.warn("Got max-blocks ({}) from update-queue", LIMIT);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

public class DBModule extends AbstractModule {

public DBModule(TileServerConfig cfg) throws Exception {
public DBModule(TileServerConfig cfg) {
this.cfg = cfg;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ public void executeEnd(ExecuteContext ctx) {
super.executeEnd(ctx);
if (watch.split() > 5_000_000_000L)
logger.warn(
"Slow SQL",
"Slow SQL: " + ctx.sql(),
new SQLPerformanceWarning());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,14 @@
import io.rudin.minetest.tileserver.service.EventBus;
import io.rudin.minetest.tileserver.service.TileCache;
import io.rudin.minetest.tileserver.service.impl.DatabaseTileCache;
import io.rudin.minetest.tileserver.service.impl.EHTileCache;
import io.rudin.minetest.tileserver.service.impl.EventBusImpl;
import io.rudin.minetest.tileserver.service.impl.FileTileCache;
import org.jooq.util.jaxb.Database;

public class ServiceModule extends AbstractModule {

public ServiceModule(TileServerConfig cfg) throws Exception {
public ServiceModule(TileServerConfig cfg) {
this.cfg = cfg;
}

Expand All @@ -30,10 +31,13 @@ protected void configure() {

if (cfg.tileCacheType() == TileServerConfig.CacheType.DATABASE)
bind(TileCache.class).to(DatabaseTileCache.class);

else if (cfg.tileCacheType() == TileServerConfig.CacheType.EHCACHE)
bind(TileCache.class).to(EHTileCache.class);

else
bind(TileCache.class).to(FileTileCache.class);

//bind(TileCache.class).to(FileTileCache.class);
bind(EventBus.class).to(EventBusImpl.class);
bind(ColorTable.class).toProvider(ColorTableProvider.class);
bind(ExecutorService.class).toProvider(ExecutorProvider.class);
Expand Down
19 changes: 18 additions & 1 deletion src/main/java/io/rudin/minetest/tileserver/route/TileRoute.java
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
import java.util.concurrent.atomic.AtomicInteger;

@Singleton
public class TileRoute implements Route {
Expand All @@ -25,12 +26,18 @@ public class TileRoute implements Route {
public TileRoute(TileRenderer renderer, TileServerConfig cfg, TileCache cache) {
this.renderer = renderer;
this.cache = cache;
this.cfg = cfg;
}

private final TileRenderer renderer;

private final TileCache cache;

private final TileServerConfig cfg;

//TODO: proper rate limit
private final AtomicInteger entryCount = new AtomicInteger();

@Override
public Object handle(Request req, Response res) throws Exception {
res.header("Content-Type", "image/png");
Expand All @@ -46,7 +53,17 @@ public Object handle(Request req, Response res) throws Exception {

logger.debug("Rendering tile @ {}/{} zoom: {}", x,y,z);

return renderer.render(x, y, z);
try {
while (entryCount.get() > cfg.tileRouteReentryCount()){
Thread.sleep(50);
}

entryCount.incrementAndGet();
return renderer.render(x, y, z);

} finally {
entryCount.decrementAndGet();
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
package io.rudin.minetest.tileserver.service.impl;

import io.rudin.minetest.tileserver.config.TileServerConfig;
import io.rudin.minetest.tileserver.service.TileCache;
import org.ehcache.Cache;
import org.ehcache.PersistentCacheManager;
import org.ehcache.config.builders.CacheConfigurationBuilder;
import org.ehcache.config.builders.CacheManagerBuilder;
import org.ehcache.config.builders.ResourcePoolsBuilder;
import org.ehcache.config.units.EntryUnit;
import org.ehcache.config.units.MemoryUnit;

import javax.inject.Inject;
import javax.inject.Singleton;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStream;

@Singleton
public class EHTileCache implements TileCache {

@Inject
public EHTileCache(TileServerConfig cfg){
this.cfg = cfg;
this.timestampMarker = new File(cfg.tileDirectory(), "timestampmarker-ehcache");

if (!timestampMarker.isFile()){
try (OutputStream output = new FileOutputStream(timestampMarker)){
output.write(0x00);
} catch (Exception e){
throw new IllegalArgumentException("could not create timestamp marker!", e);
}

timestampMarker.setLastModified(0);
}


PersistentCacheManager persistentCacheManager = CacheManagerBuilder.newCacheManagerBuilder()
.with(CacheManagerBuilder.persistence(new File(cfg.tileDirectory(), "ehcache")))
.withCache("cache",
CacheConfigurationBuilder.newCacheConfigurationBuilder(String.class, byte[].class,
ResourcePoolsBuilder.newResourcePoolsBuilder()
.heap(10, MemoryUnit.MB)
.offheap(50, MemoryUnit.MB)
.disk(10, MemoryUnit.GB, true)
)
).build(true);

cache = persistentCacheManager.getCache("cache", String.class, byte[].class);

Runtime.getRuntime().addShutdownHook(new Thread(persistentCacheManager::close));
}

private final File timestampMarker;

private final TileServerConfig cfg;

private final Cache<String, byte[]> cache;

private String getKey(int x, int y, int z){
//TODO: long key
return x + "/" + y + "/" + z;
}


@Override
public void put(int x, int y, int z, byte[] data) throws IOException {
cache.put(getKey(x,y,z), data);
timestampMarker.setLastModified(System.currentTimeMillis());
}

@Override
public byte[] get(int x, int y, int z) throws IOException {
return cache.get(getKey(x,y,z));
}

@Override
public boolean has(int x, int y, int z) {
return cache.containsKey(getKey(x,y,z));
}

@Override
public void remove(int x, int y, int z) {
cache.remove(getKey(x,y,z));
}

@Override
public long getLatestTimestamp() {
return timestampMarker.lastModified();
}
}

0 comments on commit 24c0153

Please sign in to comment.