Skip to content

Commit

Permalink
bug fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
PabloJoan committed Nov 3, 2018
1 parent 94e3bbb commit 9255b48
Show file tree
Hide file tree
Showing 13 changed files with 168 additions and 132 deletions.
25 changes: 25 additions & 0 deletions src/Bucketing/Calculator/Id.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
<?php

declare(strict_types=1);

namespace PabloJoan\Feature\Bucketing\Calculator;

class Id
{
/**
* Map a hex value to the half-open interval between 0 and 1 while
* preserving uniformity of the input distribution.
*/
function number (string $idToHash) : float
{
$hash = hash('haval192,3', $idToHash);
$x = 0;
for ($i = 0; $i < 47; ++$i) {
$x = ($x * 2) + (hexdec($hash[$i]) < 8 ? 0 : 1);
}

$x = $x / 140737488355328; // ( 2 ** 47 ) is the max value of $x

return $x * 100;
}
}
14 changes: 14 additions & 0 deletions src/Bucketing/Calculator/Random.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
<?php

declare(strict_types=1);

namespace PabloJoan\Feature\Bucketing\Calculator;

class Random
{
function number () : float
{
$x = random_int(0, PHP_INT_MAX - 1) / PHP_INT_MAX;
return $x * 100;
}
}
21 changes: 21 additions & 0 deletions src/Bucketing/Random.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace PabloJoan\Feature\Bucketing;

use PabloJoan\Feature\Value\User;
use PabloJoan\Feature\Bucketing\Calculator\Random as Calculator;

class Random implements Type
{
function id (User $user) : string
{
return $user->uaid() ?: 'no uaid';
}

function number (string $idToHash) : float
{
return (new Calculator)->number();
}
}
18 changes: 18 additions & 0 deletions src/Bucketing/Type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
<?php

declare(strict_types=1);

namespace PabloJoan\Feature\Bucketing;

use PabloJoan\Feature\Value\User;

interface Type
{
function id (User $user) : string;

/**
* A random-ish number between 0 and 100 based on the feature name and $id
* unless we are bucketing completely at random
*/
function number (string $idToHash) : float;
}
21 changes: 21 additions & 0 deletions src/Bucketing/Uaid.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace PabloJoan\Feature\Bucketing;

use PabloJoan\Feature\Value\User;
use PabloJoan\Feature\Bucketing\Calculator\Id as Calculator;

class Uaid implements Type
{
function id (User $user) : string
{
return $user->uaid();
}

function number (string $idToHash) : float
{
return (new Calculator)->number($idToHash);
}
}
21 changes: 21 additions & 0 deletions src/Bucketing/User.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace PabloJoan\Feature\Bucketing;

use PabloJoan\Feature\Value\User as UserValue;
use PabloJoan\Feature\Bucketing\Calculator\Id as Calculator;

class User implements Type
{
function id (UserValue $user) : string
{
return $user->id();
}

function number (string $idToHash) : float
{
return (new Calculator)->number($idToHash);
}
}
35 changes: 1 addition & 34 deletions src/Config.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
User,
Url,
Feature,
Bucketing,
Variant
};

Expand Down Expand Up @@ -170,39 +169,7 @@ private function variantTime (Feature $feature) : string
private function variantByPercentage (Feature $feature, string $id) : string
{
return $feature->enabled()->variantByPercentage(
$this->randomish($feature, $id)
$feature->bucketing()->number($id)
);
}

/**
* A random-ish number between 0 and 100 based on the feature name and $id
* unless we are bucketing completely at random
*/
private function randomish (Feature $feature, string $id) : float
{
switch ($feature->bucketing()->by()) {
case Bucketing::RANDOM:
$x = random_int(0, PHP_INT_MAX - 1) / PHP_INT_MAX;

default:
$x = $this->numberFromHash($feature->name() . "-$id");
}

return $x * 100;
}

/**
* Map a hex value to the half-open interval between 0 and 1 while
* preserving uniformity of the input distribution.
*/
private function numberFromHash (string $strToHash) : float
{
$hash = hash('haval192,3', $strToHash);
$x = 0;
for ($i = 0; $i < 47; ++$i) {
$x = ($x * 2) + (hexdec($hash[$i]) < 8 ? 0 : 1);
}

return $x / 140737488355328; // ( 2 ** 47 ) is the max value of $x
}
}
24 changes: 12 additions & 12 deletions src/Feature.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
namespace PabloJoan\Feature;

use PabloJoan\Feature\Value\{
FeatureCollection,
Features,
User,
Url
};
Expand Down Expand Up @@ -41,7 +41,7 @@ class Feature

function __construct (array $input = null)
{
$this->features = new FeatureCollection($input['features'] ?? []);
$this->features = new Features($input['features'] ?? []);
$this->user = new User($input['user'] ?? []);
$this->url = new Url($input['url'] ?? '');
$this->source = $input['source'] ?? '';
Expand All @@ -52,7 +52,7 @@ function __construct (array $input = null)
*/
function changeFeatures (array $features) : Feature
{
$this->features = new FeatureCollection($features);
$this->features = new Features($features);
return $this;
}

Expand All @@ -63,7 +63,7 @@ function changeFeatures (array $features) : Feature
*/
function setFeature (string $name, array $feature) : Feature
{
$this->features->set($name, $feature);
$this->features[$name] = $feature;
return $this;
}

Expand All @@ -72,7 +72,7 @@ function setFeature (string $name, array $feature) : Feature
*/
function removeFeature (string $name) : Feature
{
$this->features->remove($name);
unset($this->features[$name]);
return $this;
}

Expand Down Expand Up @@ -109,7 +109,7 @@ function changeSource (string $source) : Feature
function isEnabled (string $name) : bool
{
$config = new Config($this->user, $this->url, $this->source);
return $config->isEnabled($this->features->get($name));
return $config->isEnabled($this->features[$name]);
}

/**
Expand All @@ -121,7 +121,7 @@ function isEnabled (string $name) : bool
function isEnabledFor (string $name, array $user) : bool
{
$config = new Config(new User($user), $this->url, $this->source);
return $config->isEnabled($this->features->get($name));
return $config->isEnabled($this->features[$name]);
}

/**
Expand All @@ -133,7 +133,7 @@ function isEnabledBucketingBy (string $name, string $id) : bool
{
$config = new Config(new User([]), $this->url, $this->source);
return $config->isEnabledBucketingBy(
$this->features->get($name),
$this->features[$name],
$id
);
}
Expand All @@ -145,7 +145,7 @@ function isEnabledBucketingBy (string $name, string $id) : bool
function variant (string $name) : string
{
$config = new Config($this->user, $this->url, $this->source);
return $config->variant($this->features->get($name));
return $config->variant($this->features[$name]);
}

/**
Expand All @@ -157,7 +157,7 @@ function variant (string $name) : string
function variantFor (string $name, array $user) : string
{
$config = new Config(new User($user), $this->url, $this->source);
return $config->variant($this->features->get($name));
return $config->variant($this->features[$name]);
}

/**
Expand All @@ -170,13 +170,13 @@ function variantBucketingBy (string $name, string $id) : string
{
$config = new Config(new User([]), $this->url, $this->source);
return $config->variantBucketingBy(
$this->features->get($name),
$this->features[$name],
$id
);
}

function description (string $name) : string
{
return $this->features->get($name)->description();
return $this->features[$name]->description();
}
}
62 changes: 0 additions & 62 deletions src/Value/Bucketing.php

This file was deleted.

17 changes: 8 additions & 9 deletions src/Value/Enabled.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,19 +20,18 @@ function __construct ($enabled)
$variant = is_int($variant) ? Variant::ON : $variant;
$this->percentages[$variant] = $total;
}
asort($this->percentages, SORT_NUMERIC);
}

function variantByPercentage (float $number) : string
{
foreach ($this->percentages as $variant => $percent) {
$withinThreshold = $number < $percent;
switch ($withinThreshold) {
case true:
return $variant;
break;
}
}
return '';
$threshHold = function ($percent) use ($number) {
return $number < $percent;
};

$variant = key(array_filter($this->percentages, $threshHold));

return (string) ($variant ?: '');
}

private function percentage (int $percent) : int
Expand Down
Loading

0 comments on commit 9255b48

Please sign in to comment.