repository = $redis; } /** * Get at index * @param $group * @param $uuid * @param int $increment * * @return int */ public function getAtIndex($group, $uuid, $increment = 100) { $index = $this->lookupIndex($uuid, $increment); $uuidBytes = Uuid::fromString($uuid)->getBytes(); // When group is empty, just return 0 if($this->repository->hlen("$group:$index:uuid") === 0) { return 0; } // When group contains uuid, return it if($this->repository->hget("$group:$index:uuid", $uuidBytes) !== null) { return $this->repository->hget("$group:$index:uuid", $uuidBytes); } // Else try again $increment = $increment + 100; return $this->getAtIndex($group, $uuid, $increment); // recursion } /** * Add at index * @param $group * @param $uuid * @param $maxSize * @param int $total * @param int $increment * * @return string */ public function addAtIndex($group, $uuid, $maxSize = 768, $total = 1, $increment = 100) { $index = $this->lookupIndex($uuid, $increment); if($this->repository->hlen("$group:$index:uuid") < $maxSize) { $this->repository->hset("$group:$index:uuid", Uuid::fromString($uuid)->getBytes(), $total); return "$group:$index:uuid"; } $increment = $increment + 100; return $this->addAtIndex($group, $uuid, $maxSize, $total, $increment); // recursion } /** * Index lookup table for buckets that have a fixed size. * * @param $uuid * @param int $increment * * @return int */ private function lookupIndex($uuid, $increment = 100) { $key = substr(sha1($uuid), 1, 1); $lookup = [ "a"=>10,"b"=>11,"c"=>12,"d"=>13,"e"=>15,"f"=>16,"g"=>17,"h"=>18,"i"=>19,"j"=>20,"k"=>21,"l"=>22,"m"=>23, "n"=>24,"o"=>25,"p"=>26,"q"=>27,"r"=>28,"s"=>29,"t"=>30,"u"=>31,"v"=>32,"w"=>33,"x"=>34,"y"=>35,"z"=>36, "0"=>37,"1"=>38,"2"=>39,"3"=>40,"4"=>41,"5"=>42,"6"=>43,"7"=>45,"8"=>46,"9"=>47 ]; return $increment+$lookup[$key]; } }