mirror of
https://github.com/PaperMC/Paper.git
synced 2024-11-29 19:52:55 +01:00
Use compact memory format for uniform chunk section data.
Many chunk sections contain parts of their data that are the same for every block they contain. In these cases we can save memory by saving a single value instead of an array of 4096 copies of that value. Block light and block data are most likely to be uniform followed closely by sky light data. Block ids are far less likely to be uniform but give the largest saving when they are. Because of this we use a compact format for every part of the chunk. Memory saved from this technique will vary based on the world but seems to be about 50% on normal Minecraft generated chunks.
This commit is contained in:
parent
5adbab524d
commit
6364f59ac4
1 changed files with 272 additions and 59 deletions
|
@ -1,5 +1,7 @@
|
||||||
package net.minecraft.server;
|
package net.minecraft.server;
|
||||||
|
|
||||||
|
import java.util.Arrays; // CraftBukkit
|
||||||
|
|
||||||
public class ChunkSection {
|
public class ChunkSection {
|
||||||
|
|
||||||
private int yPos;
|
private int yPos;
|
||||||
|
@ -10,34 +12,83 @@ public class ChunkSection {
|
||||||
private NibbleArray blockData;
|
private NibbleArray blockData;
|
||||||
private NibbleArray emittedLight;
|
private NibbleArray emittedLight;
|
||||||
private NibbleArray skyLight;
|
private NibbleArray skyLight;
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
private byte compactId;
|
||||||
|
private byte compactExtId;
|
||||||
|
private byte compactData;
|
||||||
|
private byte compactEmitted;
|
||||||
|
private byte compactSky;
|
||||||
|
|
||||||
|
// Pre-generated (read-only!) NibbleArrays for every possible value, used for chunk saving
|
||||||
|
private static NibbleArray[] compactPregen = new NibbleArray[16];
|
||||||
|
static {
|
||||||
|
for (int i = 0; i < 16; i++) {
|
||||||
|
compactPregen[i] = expandCompactNibble((byte) i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static NibbleArray expandCompactNibble(byte value) {
|
||||||
|
byte[] data = new byte[2048];
|
||||||
|
Arrays.fill(data, (byte) (value | (value << 4)));
|
||||||
|
return new NibbleArray(data, 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean canBeCompact(byte[] array) {
|
||||||
|
byte value = array[0];
|
||||||
|
for (int i = 1; i < array.length; i++) {
|
||||||
|
if (value != array[i]) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
public ChunkSection(int i, boolean flag) {
|
public ChunkSection(int i, boolean flag) {
|
||||||
this.yPos = i;
|
this.yPos = i;
|
||||||
|
/* CraftBukkit - Start as null, using compact storage
|
||||||
this.blockIds = new byte[4096];
|
this.blockIds = new byte[4096];
|
||||||
this.blockData = new NibbleArray(this.blockIds.length, 4);
|
this.blockData = new NibbleArray(this.blockIds.length, 4);
|
||||||
this.emittedLight = new NibbleArray(this.blockIds.length, 4);
|
this.emittedLight = new NibbleArray(this.blockIds.length, 4);
|
||||||
if (flag) {
|
if (flag) {
|
||||||
this.skyLight = new NibbleArray(this.blockIds.length, 4);
|
this.skyLight = new NibbleArray(this.blockIds.length, 4);
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
if (!flag) {
|
||||||
|
this.compactSky = -1;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
}
|
}
|
||||||
|
|
||||||
// CraftBukkit start
|
// CraftBukkit start
|
||||||
public ChunkSection(int y, boolean flag, byte[] blkIds, byte[] extBlkIds) {
|
public ChunkSection(int y, boolean flag, byte[] blkIds, byte[] extBlkIds) {
|
||||||
this.yPos = y;
|
this.yPos = y;
|
||||||
this.blockIds = blkIds;
|
this.setIdArray(blkIds);
|
||||||
if (extBlkIds != null) {
|
if (extBlkIds != null) {
|
||||||
this.extBlockIds = new NibbleArray(extBlkIds, 4);
|
this.setExtendedIdArray(new NibbleArray(extBlkIds, 4));
|
||||||
}
|
}
|
||||||
this.blockData = new NibbleArray(this.blockIds.length, 4);
|
if (!flag) {
|
||||||
this.emittedLight = new NibbleArray(this.blockIds.length, 4);
|
this.compactSky = -1;
|
||||||
if (flag) {
|
|
||||||
this.skyLight = new NibbleArray(this.blockIds.length, 4);
|
|
||||||
}
|
}
|
||||||
this.recalcBlockCounts();
|
this.recalcBlockCounts();
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
public Block getTypeId(int i, int j, int k) {
|
public Block getTypeId(int i, int j, int k) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.blockIds == null) {
|
||||||
|
int id = this.compactId;
|
||||||
|
if (this.extBlockIds == null) {
|
||||||
|
id |= this.compactExtId << 8;
|
||||||
|
} else {
|
||||||
|
id |= this.extBlockIds.a(i, j, k) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Block.e(id); // Should be getBlockForId
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
int l = this.blockIds[j << 8 | k << 4 | i] & 255;
|
int l = this.blockIds[j << 8 | k << 4 | i] & 255;
|
||||||
|
|
||||||
if (this.extBlockIds != null) {
|
if (this.extBlockIds != null) {
|
||||||
|
@ -48,13 +99,12 @@ public class ChunkSection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setTypeId(int i, int j, int k, Block block) {
|
public void setTypeId(int i, int j, int k, Block block) {
|
||||||
int l = this.blockIds[j << 8 | k << 4 | i] & 255;
|
// CraftBukkit start - Compact storage
|
||||||
|
Block block1 = this.getTypeId(i, j, k);
|
||||||
if (this.extBlockIds != null) {
|
if (block == block1) {
|
||||||
l |= this.extBlockIds.a(i, j, k) << 8;
|
return;
|
||||||
}
|
}
|
||||||
|
// CraftBukkit end
|
||||||
Block block1 = Block.e(l);
|
|
||||||
|
|
||||||
if (block1 != Blocks.AIR) {
|
if (block1 != Blocks.AIR) {
|
||||||
--this.nonEmptyBlockCount;
|
--this.nonEmptyBlockCount;
|
||||||
|
@ -72,10 +122,17 @@ public class ChunkSection {
|
||||||
|
|
||||||
int i1 = Block.b(block);
|
int i1 = Block.b(block);
|
||||||
|
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.blockIds == null) {
|
||||||
|
this.blockIds = new byte[4096];
|
||||||
|
Arrays.fill(this.blockIds, this.compactId);
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
|
|
||||||
this.blockIds[j << 8 | k << 4 | i] = (byte) (i1 & 255);
|
this.blockIds[j << 8 | k << 4 | i] = (byte) (i1 & 255);
|
||||||
if (i1 > 255) {
|
if (i1 > 255) {
|
||||||
if (this.extBlockIds == null) {
|
if (this.extBlockIds == null) {
|
||||||
this.extBlockIds = new NibbleArray(this.blockIds.length, 4);
|
this.extBlockIds = expandCompactNibble(this.compactExtId); // CraftBukkit - Compact storage
|
||||||
}
|
}
|
||||||
|
|
||||||
this.extBlockIds.a(i, j, k, (i1 & 3840) >> 8);
|
this.extBlockIds.a(i, j, k, (i1 & 3840) >> 8);
|
||||||
|
@ -85,10 +142,23 @@ public class ChunkSection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getData(int i, int j, int k) {
|
public int getData(int i, int j, int k) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.blockData == null) {
|
||||||
|
return this.compactData;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.blockData.a(i, j, k);
|
return this.blockData.a(i, j, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setData(int i, int j, int k, int l) {
|
public void setData(int i, int j, int k, int l) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.blockData == null) {
|
||||||
|
if (this.compactData == l) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.blockData = expandCompactNibble(this.compactData);
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.blockData.a(i, j, k, l);
|
this.blockData.a(i, j, k, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,71 +175,151 @@ public class ChunkSection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSkyLight(int i, int j, int k, int l) {
|
public void setSkyLight(int i, int j, int k, int l) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.skyLight == null) {
|
||||||
|
if (this.compactSky == l) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.skyLight = expandCompactNibble(this.compactSky);
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.skyLight.a(i, j, k, l);
|
this.skyLight.a(i, j, k, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSkyLight(int i, int j, int k) {
|
public int getSkyLight(int i, int j, int k) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.skyLight == null) {
|
||||||
|
return this.compactSky;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.skyLight.a(i, j, k);
|
return this.skyLight.a(i, j, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmittedLight(int i, int j, int k, int l) {
|
public void setEmittedLight(int i, int j, int k, int l) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.emittedLight == null) {
|
||||||
|
if (this.compactEmitted == l) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.emittedLight = expandCompactNibble(this.compactEmitted);
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.emittedLight.a(i, j, k, l);
|
this.emittedLight.a(i, j, k, l);
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getEmittedLight(int i, int j, int k) {
|
public int getEmittedLight(int i, int j, int k) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.emittedLight == null) {
|
||||||
|
return this.compactEmitted;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.emittedLight.a(i, j, k);
|
return this.emittedLight.a(i, j, k);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void recalcBlockCounts() {
|
public void recalcBlockCounts() {
|
||||||
// CraftBukkit start - Optimize for speed
|
// CraftBukkit start - Optimize for speed
|
||||||
byte[] blkIds = this.blockIds;
|
|
||||||
int cntNonEmpty = 0;
|
int cntNonEmpty = 0;
|
||||||
int cntTicking = 0;
|
int cntTicking = 0;
|
||||||
if (this.extBlockIds == null) { // No extended block IDs? Don't waste time messing with them
|
|
||||||
for (int off = 0; off < blkIds.length; off++) {
|
if (this.blockIds == null) {
|
||||||
int l = blkIds[off] & 0xFF;
|
int id = this.compactId;
|
||||||
if (l > 0) {
|
if (this.extBlockIds == null) {
|
||||||
if (Block.e(l) == null) {
|
id |= this.compactExtId << 8;
|
||||||
blkIds[off] = 0;
|
if (id > 0) {
|
||||||
|
Block block = Block.e(id); // Should be getBlockForId
|
||||||
|
if (block == null) {
|
||||||
|
this.compactId = 0;
|
||||||
|
this.compactExtId = 0;
|
||||||
} else {
|
} else {
|
||||||
++cntNonEmpty;
|
cntNonEmpty = 4096;
|
||||||
if (Block.e(l).isTicking()) {
|
if (block.isTicking()) {
|
||||||
++cntTicking;
|
cntTicking = 4096;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
byte[] ext = this.extBlockIds.a;
|
||||||
|
for (int off = 0, off2 = 0; off < 4096;) {
|
||||||
|
byte extid = ext[off2];
|
||||||
|
int l = (id & 0xFF) | ((extid & 0xF) << 8); // Even data
|
||||||
|
if (l > 0) {
|
||||||
|
Block block = Block.e(l); // Should be getBlockForId
|
||||||
|
if (block == null) {
|
||||||
|
this.compactId = 0;
|
||||||
|
ext[off2] &= 0xF0;
|
||||||
|
} else {
|
||||||
|
++cntNonEmpty;
|
||||||
|
if (block.isTicking()) {
|
||||||
|
++cntTicking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off++;
|
||||||
|
l = (id & 0xFF) | ((extid & 0xF0) << 4); // Odd data
|
||||||
|
if (l > 0) {
|
||||||
|
Block block = Block.e(l); // Should be getBlockForId
|
||||||
|
if (block == null) {
|
||||||
|
this.compactId = 0;
|
||||||
|
ext[off2] &= 0x0F;
|
||||||
|
} else {
|
||||||
|
++cntNonEmpty;
|
||||||
|
if (block.isTicking()) {
|
||||||
|
++cntTicking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off++;
|
||||||
|
off2++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
byte[] ext = this.extBlockIds.a;
|
byte[] blkIds = this.blockIds;
|
||||||
for (int off = 0, off2 = 0; off < blkIds.length;) {
|
if (this.extBlockIds == null) { // No extended block IDs? Don't waste time messing with them
|
||||||
byte extid = ext[off2];
|
for (int off = 0; off < blkIds.length; off++) {
|
||||||
int l = (blkIds[off] & 0xFF) | ((extid & 0xF) << 8); // Even data
|
int l = blkIds[off] & 0xFF;
|
||||||
if (l > 0) {
|
if (l > 0) {
|
||||||
if (Block.e(l) == null) {
|
if (Block.e(l) == null) {
|
||||||
blkIds[off] = 0;
|
blkIds[off] = 0;
|
||||||
ext[off2] &= 0xF0;
|
} else {
|
||||||
} else {
|
++cntNonEmpty;
|
||||||
++cntNonEmpty;
|
if (Block.e(l).isTicking()) {
|
||||||
if (Block.e(l).isTicking()) {
|
++cntTicking;
|
||||||
++cntTicking;
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
off++;
|
} else {
|
||||||
l = (blkIds[off] & 0xFF) | ((extid & 0xF0) << 4); // Odd data
|
byte[] ext = this.extBlockIds.a;
|
||||||
if (l > 0) {
|
for (int off = 0, off2 = 0; off < blkIds.length;) {
|
||||||
if (Block.e(l) == null) {
|
byte extid = ext[off2];
|
||||||
blkIds[off] = 0;
|
int l = (blkIds[off] & 0xFF) | ((extid & 0xF) << 8); // Even data
|
||||||
ext[off2] &= 0x0F;
|
if (l > 0) {
|
||||||
} else {
|
if (Block.e(l) == null) {
|
||||||
++cntNonEmpty;
|
blkIds[off] = 0;
|
||||||
if (Block.e(l).isTicking()) {
|
ext[off2] &= 0xF0;
|
||||||
++cntTicking;
|
} else {
|
||||||
|
++cntNonEmpty;
|
||||||
|
if (Block.e(l).isTicking()) {
|
||||||
|
++cntTicking;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
off++;
|
||||||
|
l = (blkIds[off] & 0xFF) | ((extid & 0xF0) << 4); // Odd data
|
||||||
|
if (l > 0) {
|
||||||
|
if (Block.e(l) == null) {
|
||||||
|
blkIds[off] = 0;
|
||||||
|
ext[off2] &= 0x0F;
|
||||||
|
} else {
|
||||||
|
++cntNonEmpty;
|
||||||
|
if (Block.e(l).isTicking()) {
|
||||||
|
++cntTicking;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
off++;
|
||||||
|
off2++;
|
||||||
}
|
}
|
||||||
off++;
|
|
||||||
off2++;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
this.nonEmptyBlockCount = cntNonEmpty;
|
this.nonEmptyBlockCount = cntNonEmpty;
|
||||||
|
@ -198,56 +348,119 @@ public class ChunkSection {
|
||||||
}
|
}
|
||||||
|
|
||||||
public byte[] getIdArray() {
|
public byte[] getIdArray() {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.blockIds == null) {
|
||||||
|
byte[] ids = new byte[4096];
|
||||||
|
Arrays.fill(ids, this.compactId);
|
||||||
|
return ids;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.blockIds;
|
return this.blockIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NibbleArray getExtendedIdArray() {
|
public NibbleArray getExtendedIdArray() {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.extBlockIds == null && this.compactExtId != 0) {
|
||||||
|
return compactPregen[this.compactExtId];
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.extBlockIds;
|
return this.extBlockIds;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NibbleArray getDataArray() {
|
public NibbleArray getDataArray() {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.blockData == null) {
|
||||||
|
return compactPregen[this.compactData];
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.blockData;
|
return this.blockData;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NibbleArray getEmittedLightArray() {
|
public NibbleArray getEmittedLightArray() {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.emittedLight == null) {
|
||||||
|
return compactPregen[this.compactEmitted];
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.emittedLight;
|
return this.emittedLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public NibbleArray getSkyLightArray() {
|
public NibbleArray getSkyLightArray() {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (this.skyLight == null && this.compactSky != -1) {
|
||||||
|
return compactPregen[this.compactSky];
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
return this.skyLight;
|
return this.skyLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setIdArray(byte[] abyte) {
|
public void setIdArray(byte[] abyte) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (abyte == null) {
|
||||||
|
this.compactId = 0;
|
||||||
|
this.blockIds = null;
|
||||||
|
return;
|
||||||
|
} else if (canBeCompact(abyte)) {
|
||||||
|
this.compactId = abyte[0];
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.blockIds = this.validateByteArray(abyte); // CraftBukkit - Validate data
|
this.blockIds = this.validateByteArray(abyte); // CraftBukkit - Validate data
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setExtendedIdArray(NibbleArray nibblearray) {
|
public void setExtendedIdArray(NibbleArray nibblearray) {
|
||||||
// CraftBukkit start - Don't hang on to an empty nibble array
|
// CraftBukkit start - Compact storage
|
||||||
boolean empty = true;
|
if (nibblearray == null) {
|
||||||
for (int i = 0; i < nibblearray.a.length; i++) {
|
this.compactExtId = 0;
|
||||||
if (nibblearray.a[i] != 0) {
|
this.extBlockIds = null;
|
||||||
empty = false;
|
return;
|
||||||
break;
|
} else if (canBeCompact(nibblearray.a)) {
|
||||||
}
|
this.compactExtId = (byte) (nibblearray.a(0, 0, 0) & 0xF);
|
||||||
}
|
|
||||||
|
|
||||||
if (empty) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
// CraftBukkit end
|
// CraftBukkit end
|
||||||
|
|
||||||
this.extBlockIds = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
this.extBlockIds = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setDataArray(NibbleArray nibblearray) {
|
public void setDataArray(NibbleArray nibblearray) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (nibblearray == null) {
|
||||||
|
this.compactData = 0;
|
||||||
|
this.blockData = null;
|
||||||
|
return;
|
||||||
|
} else if (canBeCompact(nibblearray.a)) {
|
||||||
|
this.compactData = (byte) (nibblearray.a(0, 0, 0) & 0xF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.blockData = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
this.blockData = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setEmittedLightArray(NibbleArray nibblearray) {
|
public void setEmittedLightArray(NibbleArray nibblearray) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (nibblearray == null) {
|
||||||
|
this.compactEmitted = 0;
|
||||||
|
this.emittedLight = null;
|
||||||
|
return;
|
||||||
|
} else if (canBeCompact(nibblearray.a)) {
|
||||||
|
this.compactEmitted = (byte) (nibblearray.a(0, 0, 0) & 0xF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.emittedLight = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
this.emittedLight = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setSkyLightArray(NibbleArray nibblearray) {
|
public void setSkyLightArray(NibbleArray nibblearray) {
|
||||||
|
// CraftBukkit start - Compact storage
|
||||||
|
if (nibblearray == null) {
|
||||||
|
this.compactSky = -1;
|
||||||
|
this.skyLight = null;
|
||||||
|
return;
|
||||||
|
} else if (canBeCompact(nibblearray.a)) {
|
||||||
|
this.compactSky = (byte) (nibblearray.a(0, 0, 0) & 0xF);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// CraftBukkit end
|
||||||
this.skyLight = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
this.skyLight = this.validateNibbleArray(nibblearray); // CraftBukkit - Validate data
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -255,7 +468,7 @@ public class ChunkSection {
|
||||||
private NibbleArray validateNibbleArray(NibbleArray nibbleArray) {
|
private NibbleArray validateNibbleArray(NibbleArray nibbleArray) {
|
||||||
if (nibbleArray != null && nibbleArray.a.length < 2048) {
|
if (nibbleArray != null && nibbleArray.a.length < 2048) {
|
||||||
byte[] newArray = new byte[2048];
|
byte[] newArray = new byte[2048];
|
||||||
System.arraycopy(nibbleArray.a, 0, newArray, 0, ((nibbleArray.a.length > 2048) ? 2048 : nibbleArray.a.length));
|
System.arraycopy(nibbleArray.a, 0, newArray, 0, nibbleArray.a.length);
|
||||||
nibbleArray = new NibbleArray(newArray, 4);
|
nibbleArray = new NibbleArray(newArray, 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue