geforkt von Mirrors/FastAsyncWorldEdit
Use an object array for synchronising on internal chunk sections rather than the sections array itself.
- Synchronising on full sections synchronises on the global FULL instance (bad) - Synchronising on empty sections synchronises on the local empty instance (bad) - Leads to needless thread locking, and raises the possibility of cyclic locks considerably
Dieser Commit ist enthalten in:
Ursprung
e989a4ebb0
Commit
f10dbe7387
Binäre Datei nicht angezeigt.
@ -40,7 +40,7 @@ public abstract class CharBlocks implements IBlocks {
|
||||
|
||||
@Override
|
||||
public char[] get(CharBlocks blocks, int layer, boolean aggressive) {
|
||||
synchronized (this) {
|
||||
synchronized (blocks.sectionLocks[layer]) {
|
||||
char[] arr = blocks.blocks[layer];
|
||||
if (arr == null) {
|
||||
arr = blocks.blocks[layer] = blocks.update(layer, null, aggressive);
|
||||
@ -67,6 +67,7 @@ public abstract class CharBlocks implements IBlocks {
|
||||
};
|
||||
public char[][] blocks;
|
||||
public Section[] sections;
|
||||
public Object[] sectionLocks;
|
||||
protected int minSectionPosition;
|
||||
protected int maxSectionPosition;
|
||||
protected int sectionCount;
|
||||
@ -80,8 +81,10 @@ public abstract class CharBlocks implements IBlocks {
|
||||
this.sectionCount = maxSectionPosition - minSectionPosition + 1;
|
||||
blocks = new char[sectionCount][];
|
||||
sections = new Section[sectionCount];
|
||||
sectionLocks = new Object[sectionCount];
|
||||
for (int i = 0; i < sectionCount; i++) {
|
||||
sections[i] = empty;
|
||||
sectionLocks[i] = new Object();
|
||||
}
|
||||
}
|
||||
|
||||
@ -99,13 +102,15 @@ public abstract class CharBlocks implements IBlocks {
|
||||
}
|
||||
|
||||
@Override
|
||||
public synchronized boolean trim(boolean aggressive, int layer) {
|
||||
public boolean trim(boolean aggressive, int layer) {
|
||||
boolean result = true;
|
||||
synchronized (sectionLocks[layer]) {
|
||||
if (!sections[layer].isFull() && blocks[layer] != null) {
|
||||
blocks[layer] = null;
|
||||
} else {
|
||||
result = false;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -117,12 +122,14 @@ public abstract class CharBlocks implements IBlocks {
|
||||
return null;
|
||||
}
|
||||
|
||||
public synchronized void reset(int layer) {
|
||||
public void reset(int layer) {
|
||||
layer -= minSectionPosition;
|
||||
synchronized (sectionLocks[layer]) {
|
||||
sections[layer] = empty;
|
||||
}
|
||||
}
|
||||
|
||||
public synchronized char[] update(int layer, char[] data, boolean aggressive) {
|
||||
public char[] update(int layer, char[] data, boolean aggressive) {
|
||||
if (data == null) {
|
||||
return new char[4096];
|
||||
}
|
||||
@ -142,7 +149,7 @@ public abstract class CharBlocks implements IBlocks {
|
||||
@Override
|
||||
public char[] load(int layer) {
|
||||
layer -= minSectionPosition;
|
||||
synchronized (sections[layer]) {
|
||||
synchronized (sectionLocks[layer]) {
|
||||
return sections[layer].get(this, layer);
|
||||
}
|
||||
}
|
||||
@ -208,7 +215,7 @@ public abstract class CharBlocks implements IBlocks {
|
||||
return sections[layer].get(this, layer, index);
|
||||
}
|
||||
|
||||
public synchronized final void set(int layer, int index, char value) throws
|
||||
public final void set(int layer, int index, char value) throws
|
||||
ArrayIndexOutOfBoundsException {
|
||||
layer -= minSectionPosition;
|
||||
sections[layer].set(this, layer, index, value);
|
||||
@ -231,7 +238,7 @@ public abstract class CharBlocks implements IBlocks {
|
||||
return section[index];
|
||||
}
|
||||
|
||||
public final void set(CharBlocks blocks, int layer, int index, char value) {
|
||||
public final synchronized void set(CharBlocks blocks, int layer, int index, char value) {
|
||||
get(blocks, layer)[index] = value;
|
||||
}
|
||||
|
||||
|
@ -331,13 +331,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
sectionCount += diff;
|
||||
char[][] tmpBlocks = new char[sectionCount][];
|
||||
Section[] tmpSections = new Section[sectionCount];
|
||||
Object[] tmpSectionLocks = new Object[sectionCount];
|
||||
System.arraycopy(blocks, 0, tmpBlocks, diff, blocks.length);
|
||||
System.arraycopy(sections, 0, tmpSections, diff, sections.length);
|
||||
System.arraycopy(sectionLocks, 0, tmpSectionLocks, diff, sections.length);
|
||||
for (int i = 0; i < diff; i++) {
|
||||
tmpSections[i] = empty;
|
||||
tmpSectionLocks[i] = new Object();
|
||||
}
|
||||
blocks = tmpBlocks;
|
||||
sections = tmpSections;
|
||||
sectionLocks = tmpSectionLocks;
|
||||
minSectionPosition = layer;
|
||||
if (biomes != null) {
|
||||
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
|
||||
@ -359,13 +363,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
||||
sectionCount += diff;
|
||||
char[][] tmpBlocks = new char[sectionCount][];
|
||||
Section[] tmpSections = new Section[sectionCount];
|
||||
Object[] tmpSectionLocks = new Object[sectionCount];
|
||||
System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
|
||||
System.arraycopy(sections, 0, tmpSections, 0, sections.length);
|
||||
System.arraycopy(sectionLocks, 0, tmpSectionLocks, 0, sections.length);
|
||||
for (int i = sectionCount - diff; i < sectionCount; i++) {
|
||||
tmpSections[i] = empty;
|
||||
tmpSectionLocks[i] = new Object();
|
||||
}
|
||||
blocks = tmpBlocks;
|
||||
sections = tmpSections;
|
||||
sectionLocks = tmpSectionLocks;
|
||||
maxSectionPosition = layer;
|
||||
if (biomes != null) {
|
||||
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
|
||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren