Added chunk-sending.cache-chunks property (old advanced-cache), improved chunk unload saving times

This commit is contained in:
Shoghi Cervantes 2015-04-14 20:57:09 +02:00
parent 42eda170b5
commit 91388c6b86
No known key found for this signature in database
GPG Key ID: 78464DB0A7837F89
2 changed files with 36 additions and 3 deletions

View File

@ -141,6 +141,10 @@ class Level implements ChunkManager, Metadatable{
private $blockCache = []; private $blockCache = [];
private $chunkCache = [];
private $cacheChunks = false;
/** @var Server */ /** @var Server */
private $server; private $server;
@ -317,6 +321,7 @@ class Level implements ChunkManager, Metadatable{
$this->chunkPopulationQueueSize = (int) $this->server->getProperty("chunk-generation.population-queue-size", 2); $this->chunkPopulationQueueSize = (int) $this->server->getProperty("chunk-generation.population-queue-size", 2);
$this->chunkTickList = []; $this->chunkTickList = [];
$this->clearChunksOnTick = (bool) $this->server->getProperty("chunk-ticking.clear-tick-list", false); $this->clearChunksOnTick = (bool) $this->server->getProperty("chunk-ticking.clear-tick-list", false);
$this->cacheChunks = (bool) $this->server->getProperty("chunk-sending.cache-chunks", false);
$this->timings = new LevelTimings($this); $this->timings = new LevelTimings($this);
$this->temporalPosition = new Position(0, 0, 0, $this); $this->temporalPosition = new Position(0, 0, 0, $this);
@ -597,6 +602,7 @@ class Level implements ChunkManager, Metadatable{
if(count($this->changedBlocks) > 0){ if(count($this->changedBlocks) > 0){
if(count($this->players) > 0){ if(count($this->players) > 0){
foreach($this->changedBlocks as $index => $blocks){ foreach($this->changedBlocks as $index => $blocks){
unset($this->chunkCache[$index]);
Level::getXZ($index, $X, $Z); Level::getXZ($index, $X, $Z);
if(count($blocks) > 512){ if(count($blocks) > 512){
foreach($this->getUsingChunk($X, $Z) as $p){ foreach($this->getUsingChunk($X, $Z) as $p){
@ -606,6 +612,8 @@ class Level implements ChunkManager, Metadatable{
$this->sendBlocks($this->getUsingChunk($X, $Z), $blocks, UpdateBlockPacket::FLAG_ALL); $this->sendBlocks($this->getUsingChunk($X, $Z), $blocks, UpdateBlockPacket::FLAG_ALL);
} }
} }
}else{
$this->chunkCache = [];
} }
$this->changedBlocks = []; $this->changedBlocks = [];
@ -1156,17 +1164,19 @@ class Level implements ChunkManager, Metadatable{
return false; return false;
} }
unset($this->blockCache[$index = Level::blockHash($pos->x, $pos->y, $pos->z)]);
if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f, $block->getId(), $block->getDamage())){ if($this->getChunk($pos->x >> 4, $pos->z >> 4, true)->setBlock($pos->x & 0x0f, $pos->y & 0x7f, $pos->z & 0x0f, $block->getId(), $block->getDamage())){
if(!($pos instanceof Position)){ if(!($pos instanceof Position)){
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
} }
$block->position($pos); $block->position($pos);
unset($this->blockCache[Level::blockHash($pos->x, $pos->y, $pos->z)]);
$index = Level::chunkHash($pos->x >> 4, $pos->z >> 4); $index = Level::chunkHash($pos->x >> 4, $pos->z >> 4);
if($direct === true){ if($direct === true){
$this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY); $this->sendBlocks($this->getUsingChunk($pos->x >> 4, $pos->z >> 4), [$block], UpdateBlockPacket::FLAG_ALL_PRIORITY);
unset($this->chunkCache[$index]);
}else{ }else{
if(!($pos instanceof Position)){ if(!($pos instanceof Position)){
$pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z); $pos = $this->temporalPosition->setComponents($pos->x, $pos->y, $pos->z);
@ -1872,6 +1882,7 @@ class Level implements ChunkManager, Metadatable{
$this->chunks[$index] = $chunk; $this->chunks[$index] = $chunk;
} }
unset($this->chunkCache[$index]);
$chunk->setChanged(); $chunk->setChanged();
} }
@ -1959,6 +1970,10 @@ class Level implements ChunkManager, Metadatable{
continue; continue;
} }
Level::getXZ($index, $x, $z); Level::getXZ($index, $x, $z);
if(isset($this->chunkCache[$index])){
$this->chunkRequestCallback($x, $z, $this->chunkCache[$index]);
continue;
}
$this->chunkSendTasks[$index] = true; $this->chunkSendTasks[$index] = true;
$this->timings->syncChunkSendPrepareTimer->startTiming(); $this->timings->syncChunkSendPrepareTimer->startTiming();
$task = $this->provider->requestChunkTask($x, $z); $task = $this->provider->requestChunkTask($x, $z);
@ -1974,6 +1989,11 @@ class Level implements ChunkManager, Metadatable{
public function chunkRequestCallback($x, $z, $payload){ public function chunkRequestCallback($x, $z, $payload){
$index = Level::chunkHash($x, $z); $index = Level::chunkHash($x, $z);
if(!isset($this->chunkCache[$index]) and $this->cacheChunks){
$this->chunkCache[$index] = $payload;
}
if(isset($this->chunkSendTasks[$index])){ if(isset($this->chunkSendTasks[$index])){
foreach($this->chunkSendQueue[$index] as $player){ foreach($this->chunkSendQueue[$index] as $player){
/** @var Player $player */ /** @var Player $player */
@ -2139,7 +2159,16 @@ class Level implements ChunkManager, Metadatable{
} }
try{ try{
if($chunk !== null and $this->getAutoSave()){ $entities = 0;
foreach($chunk->getEntities() as $e){
if($e instanceof Player){
continue;
}
++$entities;
}
$save = ($chunk->hasChanged() or count($chunk->getTiles()) > 0 or $entities > 0);
if($chunk !== null and $this->getAutoSave() and $save){
$this->provider->setChunk($x, $z, $chunk); $this->provider->setChunk($x, $z, $chunk);
$this->provider->saveChunk($x, $z); $this->provider->saveChunk($x, $z);
} }
@ -2155,6 +2184,7 @@ class Level implements ChunkManager, Metadatable{
unset($this->chunks[$index]); unset($this->chunks[$index]);
unset($this->usedChunks[$index]); unset($this->usedChunks[$index]);
unset($this->chunkTickList[$index]); unset($this->chunkTickList[$index]);
unset($this->chunkCache[$index]);
$this->timings->doChunkUnload->stopTiming(); $this->timings->doChunkUnload->stopTiming();

View File

@ -56,6 +56,9 @@ chunk-sending:
max-chunks: 256 max-chunks: 256
#Amount of chunks that need to be sent before spawning the player #Amount of chunks that need to be sent before spawning the player
spawn-threshold: 56 spawn-threshold: 56
#Save a serialized copy of the chunk in memory for faster sending
#Useful in mostly-static worlds where lots of players join at the same time
cache-chunks: false
chunk-ticking: chunk-ticking:
#Max amount of chunks processed each tick #Max amount of chunks processed each tick