Skip to content

Instantly share code, notes, and snippets.

@xtrasmal
Last active December 11, 2018 16:34
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save xtrasmal/1adb428a574dfce29b67a5af0fc1c53a to your computer and use it in GitHub Desktop.
Save xtrasmal/1adb428a574dfce29b67a5af0fc1c53a to your computer and use it in GitHub Desktop.
Redis HashTable Open Addressing, probing. Hashing, create an index based on the value of the item that needs to be stored.
<?php
// Add stuff to redis
foreach ($userIds as $uuid) {
$this->indexer->addAtIndex("users", $uuid);
}
// later... retrieve from redis
$userID = "fa5352f9-fa1b-48c9-862d-1cb614cc7ed8";
$user = $this->indexer->getAtIndex("users", $userID);
var_dump($user);
<?php namespace App\Libraries\Analyse;
use Ramsey\Uuid\Uuid;
use App\Libraries\Redis\RedisRepository;
final class HashIndexerUuid
{
/**
* @var RedisRepository
*/
private $repository;
public function __construct(RedisRepository $redis)
{
$this->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];
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment