package com.comphenix.xp.history; import java.util.concurrent.TimeUnit; import org.bukkit.Location; import org.bukkit.event.block.BlockPlaceEvent; import com.google.common.cache.Cache; import com.google.common.cache.CacheBuilder; import com.google.common.cache.CacheLoader; /** * A simple memory-based history service. * * @author Kristian */ public class MemoryService implements HistoryService { public static final String NAME = "MEMORY"; // Maximum number of block changes to store private static final int MAXIMUM_SIZE = 1000; private Cache<Location, String> cache; /** * Constructs a simple memory-based history. * @param maximumSize - maximum number of block changes to store. * @param timeout - number of seconds until a location is removed from the history. */ public MemoryService(int maximumSize, int timeout) { cache = CacheBuilder.newBuilder() .maximumSize(maximumSize) .expireAfterWrite(timeout, TimeUnit.SECONDS) .build(new CacheLoader<Location, String>() { @Override public String load(Location arg0) throws Exception { throw new RuntimeException("Impossible to load unknown value."); } }); } /** * Constructs a simple memory-based history. * @param timeout - number of seconds until a location is removed from the history. */ public MemoryService(int timeout) { this(MAXIMUM_SIZE, timeout); } @Override public String getServiceName() { return NAME; } /** * Called by ExperienceBlockListener when a block has been placed by a plyer. * @param event - even to be notified about. */ public void onBlockPlaceEvent(BlockPlaceEvent event) { if (event.getPlayer() != null && event.getBlock() != null) { // Store this cache.asMap().put(event.getBlock().getLocation(), event.getPlayer().getName()); } } @Override public Boolean hasPlayerHistory(Location blockLocation) throws HistoryException { // See if a player has updated a certain block before return cache.asMap().containsKey(blockLocation); } @Override public LookupSpeed getLookupSpeed() { return LookupSpeed.FAST; } @Override public boolean hasFalsePositives() { return false; } @Override public boolean hasFalseNegatives() { // Only a fraction of all block changes are stored in memory. return true; } }