mirror of
https://github.com/EngineHub/WorldGuard.git
synced 2024-09-06 20:38:08 +02:00
Don't use the region chunk has table until a threshold.
This commit is contained in:
parent
95052546a5
commit
f57afb2944
@ -51,8 +51,14 @@
|
|||||||
*/
|
*/
|
||||||
public class ChunkHashTable implements ConcurrentRegionIndex {
|
public class ChunkHashTable implements ConcurrentRegionIndex {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of regions required before this hash table kicks in.
|
||||||
|
*/
|
||||||
|
private static final int CACHE_THRESHOLD = 5;
|
||||||
|
|
||||||
private ListeningExecutorService executor = createExecutor();
|
private ListeningExecutorService executor = createExecutor();
|
||||||
private LongHashTable<ChunkState> states = new LongHashTable<ChunkState>();
|
@Nullable
|
||||||
|
private LongHashTable<ChunkState> states;
|
||||||
private final RegionIndex index;
|
private final RegionIndex index;
|
||||||
private final Object lock = new Object();
|
private final Object lock = new Object();
|
||||||
@Nullable
|
@Nullable
|
||||||
@ -79,35 +85,23 @@ private ListeningExecutorService createExecutor() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a state object at the given position.
|
* Get a state object at the given position, returning an entry only
|
||||||
|
* if one exists.
|
||||||
*
|
*
|
||||||
* @param position the position
|
* @param position the position
|
||||||
* @param create true to create an entry if one does not exist
|
* @return a chunk state object, or {@code null}
|
||||||
* @return a chunk state object, or {@code null} (only if {@code create} is false)
|
|
||||||
*/
|
*/
|
||||||
@Nullable
|
@Nullable
|
||||||
private ChunkState get(Vector2D position, boolean create) {
|
private ChunkState get(Vector2D position) {
|
||||||
ChunkState state;
|
LongHashTable<ChunkState> states = this.states;
|
||||||
synchronized (lock) {
|
|
||||||
state = states.get(position.getBlockX(), position.getBlockZ());
|
|
||||||
if (state == null && create) {
|
|
||||||
state = new ChunkState(position);
|
|
||||||
states.put(position.getBlockX(), position.getBlockZ(), state);
|
|
||||||
executor.submit(new EnumerateRegions(position));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return state;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
if (states != null) {
|
||||||
* Get a state at the given position or create a new entry if one does
|
synchronized (lock) {
|
||||||
* not exist.
|
return states.get(position.getBlockX(), position.getBlockZ());
|
||||||
*
|
}
|
||||||
* @param position the position
|
} else {
|
||||||
* @return a state
|
return null;
|
||||||
*/
|
}
|
||||||
private ChunkState getOrCreate(Vector2D position) {
|
|
||||||
return get(position, true);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -118,22 +112,30 @@ private void rebuild() {
|
|||||||
ListeningExecutorService previousExecutor = executor;
|
ListeningExecutorService previousExecutor = executor;
|
||||||
LongHashTable<ChunkState> previousStates = states;
|
LongHashTable<ChunkState> previousStates = states;
|
||||||
|
|
||||||
previousExecutor.shutdownNow();
|
if (index.size() > CACHE_THRESHOLD) {
|
||||||
states = new LongHashTable<ChunkState>();
|
previousExecutor.shutdownNow();
|
||||||
executor = createExecutor();
|
|
||||||
|
|
||||||
List<Vector2D> positions = new ArrayList<Vector2D>();
|
states = new LongHashTable<ChunkState>();
|
||||||
for (ChunkState state : previousStates.values()) {
|
executor = createExecutor();
|
||||||
Vector2D position = state.getPosition();
|
|
||||||
positions.add(position);
|
if (previousStates != null) {
|
||||||
states.put(position.getBlockX(), position.getBlockZ(), new ChunkState(position));
|
List<Vector2D> positions = new ArrayList<Vector2D>();
|
||||||
|
|
||||||
|
for (ChunkState state : previousStates.values()) {
|
||||||
|
Vector2D position = state.getPosition();
|
||||||
|
positions.add(position);
|
||||||
|
states.put(position.getBlockX(), position.getBlockZ(), new ChunkState(position));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!positions.isEmpty()) {
|
||||||
|
executor.submit(new EnumerateRegions(positions));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
lastState = null;
|
||||||
|
} else {
|
||||||
|
states = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!positions.isEmpty()) {
|
|
||||||
executor.submit(new EnumerateRegions(positions));
|
|
||||||
}
|
|
||||||
|
|
||||||
lastState = null;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -159,7 +161,19 @@ public boolean awaitCompletion(long timeout, TimeUnit unit) throws InterruptedEx
|
|||||||
@Override
|
@Override
|
||||||
public void bias(Vector2D chunkPosition) {
|
public void bias(Vector2D chunkPosition) {
|
||||||
checkNotNull(chunkPosition);
|
checkNotNull(chunkPosition);
|
||||||
getOrCreate(chunkPosition);
|
|
||||||
|
if (states != null) {
|
||||||
|
synchronized (lock) {
|
||||||
|
if (states != null) {
|
||||||
|
ChunkState state = states.get(chunkPosition.getBlockX(), chunkPosition.getBlockZ());
|
||||||
|
if (state == null) {
|
||||||
|
state = new ChunkState(chunkPosition);
|
||||||
|
states.put(chunkPosition.getBlockX(), chunkPosition.getBlockZ(), state);
|
||||||
|
executor.submit(new EnumerateRegions(chunkPosition));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@ -175,10 +189,12 @@ public void biasAll(Collection<Vector2D> chunkPositions) {
|
|||||||
public void forget(Vector2D chunkPosition) {
|
public void forget(Vector2D chunkPosition) {
|
||||||
checkNotNull(chunkPosition);
|
checkNotNull(chunkPosition);
|
||||||
synchronized (lock) {
|
synchronized (lock) {
|
||||||
states.remove(chunkPosition.getBlockX(), chunkPosition.getBlockZ());
|
if (states != null) {
|
||||||
ChunkState state = lastState;
|
states.remove(chunkPosition.getBlockX(), chunkPosition.getBlockZ());
|
||||||
if (state != null && state.getPosition().getBlockX() == chunkPosition.getBlockX() && state.getPosition().getBlockZ() == chunkPosition.getBlockZ()) {
|
ChunkState state = lastState;
|
||||||
lastState = null;
|
if (state != null && state.getPosition().getBlockX() == chunkPosition.getBlockX() && state.getPosition().getBlockZ() == chunkPosition.getBlockZ()) {
|
||||||
|
lastState = null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -238,7 +254,7 @@ public void applyContaining(Vector position, Predicate<ProtectedRegion> consumer
|
|||||||
int chunkZ = position.getBlockZ() >> 4;
|
int chunkZ = position.getBlockZ() >> 4;
|
||||||
|
|
||||||
if (state == null || state.getPosition().getBlockX() != chunkX || state.getPosition().getBlockZ() != chunkZ) {
|
if (state == null || state.getPosition().getBlockX() != chunkX || state.getPosition().getBlockZ() != chunkZ) {
|
||||||
state = get(new Vector2D(chunkX, chunkZ), false);
|
state = get(new Vector2D(chunkX, chunkZ));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (state != null && state.isLoaded()) {
|
if (state != null && state.isLoaded()) {
|
||||||
@ -301,7 +317,7 @@ private EnumerateRegions(List<Vector2D> positions) {
|
|||||||
@Override
|
@Override
|
||||||
public void run() {
|
public void run() {
|
||||||
for (Vector2D position : positions) {
|
for (Vector2D position : positions) {
|
||||||
ChunkState state = get(position, false);
|
ChunkState state = get(position);
|
||||||
|
|
||||||
if (state != null) {
|
if (state != null) {
|
||||||
List<ProtectedRegion> regions = new ArrayList<ProtectedRegion>();
|
List<ProtectedRegion> regions = new ArrayList<ProtectedRegion>();
|
||||||
|
Loading…
Reference in New Issue
Block a user