Last active
August 12, 2019 13:41
-
-
Save MisterFixx/54570994f44373e89365ba8ca938a7a0 to your computer and use it in GitHub Desktop.
Php class to fetch snowflakes from JSnowflake (https://github.com/MisterFixx/JSnowflake)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Snowflake.php | |
* | |
* Licensed under The MIT License | |
* @author Mister_Fix <me@misterfix.io> | |
* @package Snowflake | |
* @version v 2.0 | |
* @license MIT License | |
* | |
* NOTE: This will only work properly on 64 bit versions of PHP, because Snowflakes are 64 bit integers. | |
*/ | |
class Snowflake{ | |
/** | |
* Last fetched snowflake | |
*/ | |
private $lastSnowflake = 0; | |
/** | |
* If a socket has already been opened, it will be stored here so we don't have to open another one wasting time. | |
*/ | |
private $socket = null; | |
/** | |
* The data to write to the socket each time a Snowflake is needed | |
*/ | |
private $socketData = null; | |
/** | |
* The lenth of the data aforementioned data | |
*/ | |
private $dataLength = 0; | |
/** | |
* Initiate a connection to the Snowflake server | |
*/ | |
public function __construct($host = 'localhost:9098'){ | |
$this->socket = stream_socket_client("tcp://{$host}"); | |
$this->socketData = pack('N*', 1); | |
$this->dataLength = strlen($this->socketData); | |
return $this; | |
} | |
/** | |
* Fetches a single snowflake | |
* @param string (Optional Snowflake server address) | |
* @return int (The Snowflake) | |
*/ | |
public function nextId():int{ | |
if ($this->socket != false) { | |
fwrite($this->socket, $this->socketData, $this->dataLength); | |
$this->lastSnowflake = unpack("J", fread($this->socket, 8))[1]; | |
return $this->lastSnowflake; | |
} | |
else { | |
throw new RuntimeException('Unable to connect to Snowflake service'); | |
} | |
} | |
/** | |
* Returns the last generated snowflake | |
* @return int The last returned Snowflake | |
*/ | |
public function getLastId():int{ | |
return $this->lastSnowflake; | |
} | |
/** | |
* Returns the creation timestamp of a given snowflake | |
* @param int Snowflake | |
* @param int (Optional) epoch of the snowflake | |
* @return int java timestamp of Snowflake's creation time | |
* To convert to php timestamp divide by 1000 | |
*/ | |
public function getIdCreationTime($snowflake, $epoch = 1436077819000):int{ | |
return ($snowflake >> 22)+$epoch; | |
} | |
/** | |
* Returns the datacenter ID at which the given snowflake was generated. | |
* @param int Snowflake | |
* @return int Snowflake's Datacenter ID | |
*/ | |
public function getDatacenterId($snowflake):int{ | |
return $snowflake >> 17 & 31; | |
} | |
/** | |
* Returns the instance ID at which the given snowflake was generated. | |
* @param int Snowflake | |
* @return int Snowflake's Instance ID | |
*/ | |
public function getInstanceId($snowflake):int{ | |
return $snowflake >> 12 & 31; | |
} | |
/** | |
* Returns the sequential number of the given snowflake. | |
* @param int Snowflake | |
* @return int Snowflake's Sequential number | |
*/ | |
public function getSequentialNumber($snowflake):int{ | |
return $snowflake >> 0 & 4095; | |
} | |
} | |
//Example & Benchmark | |
$snowflake = new Snowflake(); | |
$time_start = microtime(true); | |
for($i = 0; $i < 10000; $i++){ | |
$snowflake->nextId(); | |
} | |
$time_stop = microtime(true); | |
$id = $snowflake->nextId(); | |
echo "Snowflake: ".$id."<br /><br />"; | |
echo "Created at: ".gmdate("Y-m-d H:i:s", $snowflake->getIdCreationTime($id)/1000)."<br />"; | |
echo "Datacenter ID: ".$snowflake->getDatacenterId($id)."<br />"; | |
echo "Instance ID: ".$snowflake->getInstanceId($id)."<br />"; | |
echo "Sequential Number: ".$snowflake->getSequentialNumber($id)."<br /><br />"; | |
echo "Time to get 10k Snowflakes: ".($time_stop-$time_start)." seconds<br />"; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment