data = $payload ?? self::ZERO; $this->collectGarbage(); } public static function fill(int $level) : self{ if($level === 0){ return new self(self::ZERO); } if($level === 15){ return new self(self::FIFTEEN); } return new self(str_repeat(chr(($level & 0x0f) | ($level << 4)), 2048)); } public function get(int $x, int $y, int $z) : int{ return (ord($this->data[($x << 7) | ($z << 3) | ($y >> 1)]) >> (($y & 1) << 2)) & 0xf; } public function set(int $x, int $y, int $z, int $level) : void{ $i = ($x << 7) | ($z << 3) | ($y >> 1); $shift = ($y & 1) << 2; $byte = ord($this->data[$i]); $this->data[$i] = chr(($byte & ~(0xf << $shift)) | (($level & 0xf) << $shift)); } public function collectGarbage() : void{ /* * This strange looking code is designed to exploit PHP's copy-on-write behaviour. Assigning will copy a * reference to the const instead of duplicating the whole string. The string will only be duplicated when * modified, which is perfect for this purpose. */ if($this->data === ZERO_NIBBLE_ARRAY){ $this->data = ZERO_NIBBLE_ARRAY; }elseif($this->data === FIFTEEN_NIBBLE_ARRAY){ $this->data = FIFTEEN_NIBBLE_ARRAY; } } public function getData() : string{ return $this->data; } public function __wakeup(){ //const refs aren't preserved when unserializing $this->collectGarbage(); } }