mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2025-03-11 22:31:05 +01:00
Added RegionQueryCache, which will be used to for cached regions-contain-point lookups.
This commit is contained in:
parent
5e75bf36c3
commit
2c7767f89f
@ -0,0 +1,99 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* This file is a part of WorldGuard.
|
||||||
|
* Copyright (c) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (c) the WorldGuard team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.bukkit;
|
||||||
|
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.World;
|
||||||
|
import org.bukkit.block.Block;
|
||||||
|
import org.bukkit.entity.Entity;
|
||||||
|
import org.bukkit.event.Event;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldguard.protection.ApplicableRegionSet;
|
||||||
|
import com.sk89q.worldguard.protection.GlobalRegionManager;
|
||||||
|
import com.sk89q.worldguard.protection.RegionQueryCache;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An implementation of {@link RegionQueryCache} for Bukkit. This implementation is
|
||||||
|
* thread-safe.
|
||||||
|
*/
|
||||||
|
public class BukkitRegionQueryCache extends RegionQueryCache {
|
||||||
|
|
||||||
|
private final WorldGuardPlugin plugin;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Construct the cache with the given plugin instance.
|
||||||
|
*
|
||||||
|
* @param plugin plugin instance
|
||||||
|
*/
|
||||||
|
public BukkitRegionQueryCache(WorldGuardPlugin plugin) {
|
||||||
|
this.plugin = plugin;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an {@link ApplicableRegionSet} for a given location. The result may have been
|
||||||
|
* temporarily cached for the given event, or null if region protection has
|
||||||
|
* been disabled for the the world of the given location.
|
||||||
|
*
|
||||||
|
* @param event the event to cache against
|
||||||
|
* @param location the location to check
|
||||||
|
* @return the set, or null if region protection is disabled for the given location
|
||||||
|
*/
|
||||||
|
public ApplicableRegionSet lookup(Event event, Location location) {
|
||||||
|
World world = location.getWorld();
|
||||||
|
Vector vector = BukkitUtil.toVector(location);
|
||||||
|
|
||||||
|
ConfigurationManager config = plugin.getGlobalStateManager();
|
||||||
|
WorldConfiguration worldConfig = config.get(world);
|
||||||
|
GlobalRegionManager regionManager = plugin.getGlobalRegionManager();
|
||||||
|
|
||||||
|
if (!worldConfig.useRegions) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return get(event).lookup(regionManager.get(world), vector);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an {@link ApplicableRegionSet} for a given block. The result may have been
|
||||||
|
* temporarily cached for the given event, or null if region protection has
|
||||||
|
* been disabled for the the world of the given block.
|
||||||
|
*
|
||||||
|
* @param event the event to cache against
|
||||||
|
* @param block the block to check
|
||||||
|
* @return the set, or null if region protection is disabled for the given block
|
||||||
|
*/
|
||||||
|
public ApplicableRegionSet lookup(Event event, Block block) {
|
||||||
|
return lookup(event, block.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an {@link ApplicableRegionSet} for a given entity. The result may have been
|
||||||
|
* temporarily cached for the given event, or null if region protection has
|
||||||
|
* been disabled for the the world of the given entity.
|
||||||
|
*
|
||||||
|
* @param event the event to cache against
|
||||||
|
* @param entity the entity to check
|
||||||
|
* @return the set, or null if region protection is disabled for the given entity
|
||||||
|
*/
|
||||||
|
public ApplicableRegionSet lookup(Event event, Entity entity) {
|
||||||
|
return lookup(event, entity.getLocation());
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,62 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* This file is a part of WorldGuard.
|
||||||
|
* Copyright (c) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (c) the WorldGuard team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection;
|
||||||
|
|
||||||
|
import java.util.WeakHashMap;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* To facilitate performing regions-containing-point lookups from multiple stack frames
|
||||||
|
* but within the same context (the same event), a cache is important in preventing the
|
||||||
|
* need for redundant lookups made for the same point. This class serves as such a cache.
|
||||||
|
* <p>
|
||||||
|
* A key needs to be selected to store cache entries against. The best key is one that
|
||||||
|
* is highly temporal, and would represent a certain "snapshot in time," such as
|
||||||
|
* an event object. The event objects are indexed in this class using weak references,
|
||||||
|
* and they will be removed by the garbage collector automatically. Because it
|
||||||
|
* <em>is</em> a weak reference, the key object needs to be held somewhere with a strong
|
||||||
|
* reference until the "snapshot" ends.
|
||||||
|
* <p>
|
||||||
|
* This class is abstract because implementing class should provide methods to check
|
||||||
|
* against a standard key object. This cache itself is thread-safe.
|
||||||
|
*/
|
||||||
|
public abstract class RegionQueryCache {
|
||||||
|
|
||||||
|
private final WeakHashMap<Object, RegionQueryCacheEntry> cache =
|
||||||
|
new WeakHashMap<Object, RegionQueryCacheEntry>();
|
||||||
|
|
||||||
|
public RegionQueryCache() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the {@link RegionQueryCacheEntry} object that will cache the
|
||||||
|
* {@link ApplicableRegionSet}s for this context.
|
||||||
|
*
|
||||||
|
* @param key a standard key to store by
|
||||||
|
* @return an existing QueryCacheEntry or a new one
|
||||||
|
*/
|
||||||
|
protected synchronized RegionQueryCacheEntry get(Object key) {
|
||||||
|
RegionQueryCacheEntry entry = cache.get(key);
|
||||||
|
if (entry == null) {
|
||||||
|
entry = new RegionQueryCacheEntry();
|
||||||
|
cache.put(key, entry);
|
||||||
|
}
|
||||||
|
return entry;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,76 @@
|
|||||||
|
// $Id$
|
||||||
|
/*
|
||||||
|
* This file is a part of WorldGuard.
|
||||||
|
* Copyright (c) sk89q <http://www.sk89q.com>
|
||||||
|
* Copyright (c) the WorldGuard team and contributors
|
||||||
|
*
|
||||||
|
* This program is free software: you can redistribute it and/or modify it under the
|
||||||
|
* terms of the GNU Lesser General Public License as published by the Free Software
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but WITHOUT ANY
|
||||||
|
* WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License along with
|
||||||
|
* this program. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.sk89q.worldguard.protection;
|
||||||
|
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
import com.sk89q.worldedit.BlockVector;
|
||||||
|
import com.sk89q.worldedit.Vector;
|
||||||
|
import com.sk89q.worldguard.protection.managers.RegionManager;
|
||||||
|
import com.sk89q.worldguard.protection.regions.ProtectedRegion;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An object to cache a list of {@link ApplicableRegionSet}s. This class is
|
||||||
|
* thread-safe.
|
||||||
|
*
|
||||||
|
* @see RegionQueryCache
|
||||||
|
*/
|
||||||
|
public class RegionQueryCacheEntry {
|
||||||
|
|
||||||
|
private final Map<BlockVector, ApplicableRegionSet> cachedPoints =
|
||||||
|
new HashMap<BlockVector, ApplicableRegionSet>();
|
||||||
|
|
||||||
|
RegionQueryCacheEntry() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an {@link ApplicableRegionSet} for a given point. If a lookup already has
|
||||||
|
* been performed, a cached result will be returned.
|
||||||
|
*
|
||||||
|
* @param manager the manager
|
||||||
|
* @param location the location to lookup
|
||||||
|
* @return the applicable region set
|
||||||
|
*/
|
||||||
|
public synchronized ApplicableRegionSet lookup(RegionManager manager, Vector location) {
|
||||||
|
BlockVector hashableLocation = location.toBlockVector();
|
||||||
|
ApplicableRegionSet set = cachedPoints.get(hashableLocation);
|
||||||
|
if (set == null) {
|
||||||
|
set = manager.getApplicableRegions(location);
|
||||||
|
cachedPoints.put(hashableLocation, set);
|
||||||
|
}
|
||||||
|
return set;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an {@link ApplicableRegionSet} for a given region. This method does not yet
|
||||||
|
* cache results.
|
||||||
|
*
|
||||||
|
* @param manager
|
||||||
|
* the manager
|
||||||
|
* @param region
|
||||||
|
* the area to lookup
|
||||||
|
* @return the applicable region set
|
||||||
|
*/
|
||||||
|
public synchronized ApplicableRegionSet lookup(RegionManager manager,
|
||||||
|
ProtectedRegion region) {
|
||||||
|
return manager.getApplicableRegions(region);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user