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
|
@Override
|
||||||
public char[] get(CharBlocks blocks, int layer, boolean aggressive) {
|
public char[] get(CharBlocks blocks, int layer, boolean aggressive) {
|
||||||
synchronized (this) {
|
synchronized (blocks.sectionLocks[layer]) {
|
||||||
char[] arr = blocks.blocks[layer];
|
char[] arr = blocks.blocks[layer];
|
||||||
if (arr == null) {
|
if (arr == null) {
|
||||||
arr = blocks.blocks[layer] = blocks.update(layer, null, aggressive);
|
arr = blocks.blocks[layer] = blocks.update(layer, null, aggressive);
|
||||||
@ -67,6 +67,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
};
|
};
|
||||||
public char[][] blocks;
|
public char[][] blocks;
|
||||||
public Section[] sections;
|
public Section[] sections;
|
||||||
|
public Object[] sectionLocks;
|
||||||
protected int minSectionPosition;
|
protected int minSectionPosition;
|
||||||
protected int maxSectionPosition;
|
protected int maxSectionPosition;
|
||||||
protected int sectionCount;
|
protected int sectionCount;
|
||||||
@ -80,8 +81,10 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
this.sectionCount = maxSectionPosition - minSectionPosition + 1;
|
this.sectionCount = maxSectionPosition - minSectionPosition + 1;
|
||||||
blocks = new char[sectionCount][];
|
blocks = new char[sectionCount][];
|
||||||
sections = new Section[sectionCount];
|
sections = new Section[sectionCount];
|
||||||
|
sectionLocks = new Object[sectionCount];
|
||||||
for (int i = 0; i < sectionCount; i++) {
|
for (int i = 0; i < sectionCount; i++) {
|
||||||
sections[i] = empty;
|
sections[i] = empty;
|
||||||
|
sectionLocks[i] = new Object();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -99,12 +102,14 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public synchronized boolean trim(boolean aggressive, int layer) {
|
public boolean trim(boolean aggressive, int layer) {
|
||||||
boolean result = true;
|
boolean result = true;
|
||||||
if (!sections[layer].isFull() && blocks[layer] != null) {
|
synchronized (sectionLocks[layer]) {
|
||||||
blocks[layer] = null;
|
if (!sections[layer].isFull() && blocks[layer] != null) {
|
||||||
} else {
|
blocks[layer] = null;
|
||||||
result = false;
|
} else {
|
||||||
|
result = false;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
@ -117,12 +122,14 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void reset(int layer) {
|
public void reset(int layer) {
|
||||||
layer -= minSectionPosition;
|
layer -= minSectionPosition;
|
||||||
sections[layer] = empty;
|
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) {
|
if (data == null) {
|
||||||
return new char[4096];
|
return new char[4096];
|
||||||
}
|
}
|
||||||
@ -142,7 +149,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
@Override
|
@Override
|
||||||
public char[] load(int layer) {
|
public char[] load(int layer) {
|
||||||
layer -= minSectionPosition;
|
layer -= minSectionPosition;
|
||||||
synchronized (sections[layer]) {
|
synchronized (sectionLocks[layer]) {
|
||||||
return sections[layer].get(this, layer);
|
return sections[layer].get(this, layer);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -208,7 +215,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
return sections[layer].get(this, layer, index);
|
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 {
|
ArrayIndexOutOfBoundsException {
|
||||||
layer -= minSectionPosition;
|
layer -= minSectionPosition;
|
||||||
sections[layer].set(this, layer, index, value);
|
sections[layer].set(this, layer, index, value);
|
||||||
@ -231,7 +238,7 @@ public abstract class CharBlocks implements IBlocks {
|
|||||||
return section[index];
|
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;
|
get(blocks, layer)[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -331,13 +331,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
sectionCount += diff;
|
sectionCount += diff;
|
||||||
char[][] tmpBlocks = new char[sectionCount][];
|
char[][] tmpBlocks = new char[sectionCount][];
|
||||||
Section[] tmpSections = new Section[sectionCount];
|
Section[] tmpSections = new Section[sectionCount];
|
||||||
|
Object[] tmpSectionLocks = new Object[sectionCount];
|
||||||
System.arraycopy(blocks, 0, tmpBlocks, diff, blocks.length);
|
System.arraycopy(blocks, 0, tmpBlocks, diff, blocks.length);
|
||||||
System.arraycopy(sections, 0, tmpSections, diff, sections.length);
|
System.arraycopy(sections, 0, tmpSections, diff, sections.length);
|
||||||
|
System.arraycopy(sectionLocks, 0, tmpSectionLocks, diff, sections.length);
|
||||||
for (int i = 0; i < diff; i++) {
|
for (int i = 0; i < diff; i++) {
|
||||||
tmpSections[i] = empty;
|
tmpSections[i] = empty;
|
||||||
|
tmpSectionLocks[i] = new Object();
|
||||||
}
|
}
|
||||||
blocks = tmpBlocks;
|
blocks = tmpBlocks;
|
||||||
sections = tmpSections;
|
sections = tmpSections;
|
||||||
|
sectionLocks = tmpSectionLocks;
|
||||||
minSectionPosition = layer;
|
minSectionPosition = layer;
|
||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
|
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
|
||||||
@ -359,13 +363,17 @@ public class CharSetBlocks extends CharBlocks implements IChunkSet {
|
|||||||
sectionCount += diff;
|
sectionCount += diff;
|
||||||
char[][] tmpBlocks = new char[sectionCount][];
|
char[][] tmpBlocks = new char[sectionCount][];
|
||||||
Section[] tmpSections = new Section[sectionCount];
|
Section[] tmpSections = new Section[sectionCount];
|
||||||
|
Object[] tmpSectionLocks = new Object[sectionCount];
|
||||||
System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
|
System.arraycopy(blocks, 0, tmpBlocks, 0, blocks.length);
|
||||||
System.arraycopy(sections, 0, tmpSections, 0, sections.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++) {
|
for (int i = sectionCount - diff; i < sectionCount; i++) {
|
||||||
tmpSections[i] = empty;
|
tmpSections[i] = empty;
|
||||||
|
tmpSectionLocks[i] = new Object();
|
||||||
}
|
}
|
||||||
blocks = tmpBlocks;
|
blocks = tmpBlocks;
|
||||||
sections = tmpSections;
|
sections = tmpSections;
|
||||||
|
sectionLocks = tmpSectionLocks;
|
||||||
maxSectionPosition = layer;
|
maxSectionPosition = layer;
|
||||||
if (biomes != null) {
|
if (biomes != null) {
|
||||||
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
|
BiomeType[] tmpBiomes = new BiomeType[sectionCount * 64];
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren