Untitled

 avatar
unknown
java
13 days ago
4.4 kB
5
Indexable
@Getter
public final class ArenaCache {

    public static final String KEY = "arcade_arena_cache";

    private final Executor executor = Executors.newSingleThreadExecutor();
    private final Cache<String, ArenaGson> cache = Caffeine.newBuilder().build();
    private final List<ArenaGson> sortedArenas = Collections.synchronizedList(new ArrayList<>());

    private final JedisDB jedisDB;
    private final JedisPool jedisPool;

    public ArenaCache(JedisDB jedisDB) {
        this.jedisDB = jedisDB;
        this.jedisPool = jedisDB.createPool();
    }

    public Optional<ArenaGson> getFirst(int typeId, int playersAdd) {
        for (ArenaGson arena : sortedArenas) {
            if (arena.getMode().typeId() == typeId && arena.getMaxPlayers() - arena.getPlayers() - playersAdd >= 0) {
                return Optional.of(arena);
            }
        }
        return Optional.empty();
    }

    public Optional<ArenaGson> getFirst(String server, int gameId, int playersAdd) {
        for (ArenaGson arena : sortedArenas) {
            if (arena.getServerName().equals(server)
                    && arena.getGameId() == gameId
                    && arena.getMaxPlayers() - arena.getPlayers() - playersAdd >= 0) {
                return Optional.of(arena);
            }
        }
        return Optional.empty();
    }

    public Set<ArenaGson> getArenasByServer(String serverKey) {
        return getArenas()
                .stream()
                .filter(arena -> arena.getServerKey().equals(serverKey))
                .collect(Collectors.toSet());
    }

    public Optional<ArenaGson> getArena(String serverName, int gameId) {
        return getArena(ArenaGson.key(serverName, gameId));
    }

    public Optional<ArenaGson> getArena(String key) {
        return Optional.ofNullable(cache.getIfPresent(key));
    }

    public Set<String> keySet() {
        return cache.asMap().keySet();
    }

    public Collection<ArenaGson> getArenas() {
        return cache.asMap().values();
    }

    public void sort() {
        sortedArenas.sort(ArenaGsonComparator.INSTANCE);
    }

    public void cache(ArenaGson arena) {
        cache.put(arena.getKey(), arena);
        sortedArenas.add(arena);
        sort();
    }

    public void remove(String key) {
        ArenaGson gson = cache.getIfPresent(key);
        if (gson != null) {
            sortedArenas.remove(gson);
            sort();
        }
        cache.invalidate(key);
    }

    public void clear() {
        cache.invalidateAll();
        cache.cleanUp();
        sortedArenas.clear();
    }

    public void deSyncArena(String key) {
        remove(key);
        if (isConnected()) {
            executor.execute(() -> {
                try (Jedis jedis = jedisPool.getResource()) {
                    jedis.hdel(KEY, key);
                    jedisDB.getWriter().wrapAndWriteToAll(MessageWrapper.TypeCase.ARENA_UPDATE,
                            MessageArenaUpdate.newBuilder()
                                    .setKey(key)
                                    .build());
                }
            });
        }
    }

    public void syncArena(ArenaGson arena) {
        String key = arena.getKey();
        Validate.notNull(cache.getIfPresent(key), "Arena isn't cached yet. couldn't sync!");

        if (isConnected()) {
            CompletableFuture.runAsync(() -> {
                try (Jedis jedis = jedisPool.getResource()) {
                    jedis.hset(KEY, key, GsonSerializer.ARENA.toJson(arena)); // update arena
                }
            }, executor).whenComplete((u, thr) -> {
                jedisDB.getWriter().wrapAndWriteToAll(MessageWrapper.TypeCase.ARENA_UPDATE, MessageArenaUpdate.newBuilder()
                        .setKey(key)
                        .build());
            });
        }
    }

    public void syncAll() {
        if (isConnected()) {
            executor.execute(this::syncAll0);
        }
    }

    private void syncAll0() {
        try (Jedis jedis = jedisPool.getResource()) {
            jedis.hgetAll(KEY).forEach((arenaKey, arenaStr) -> cache(GsonSerializer.ARENA.fromJson(arenaStr, ArenaGson.class)));
        }
    }

    private boolean isConnected() {
        return jedisDB.getProtobufSubscriber().isConnected();
    }
}
Editor is loading...
Leave a Comment