Skip to content

Instantly share code, notes, and snippets.

@cfillion
Last active February 26, 2016 04:20
Show Gist options
  • Select an option

  • Save cfillion/41e85ede0c6cff03ffff to your computer and use it in GitHub Desktop.

Select an option

Save cfillion/41e85ede0c6cff03ffff to your computer and use it in GitHub Desktop.
<?php
/* USAGE EXAMPLE:
* $data = [
* 'key1' => [1, 1, 1, 1],
* 'key2' => [1, 1],
* ];
*
* $win = new Window(2);
* foreach($data as $key => $points)
* {
* foreach($points as $point)
* $win->push($key, $point);
* }
*
* print_r($win->getKeys());
* print_r($win->getValues());
*
* OUTPUT:
* Array
* (
* [0] => key1
* [2] => key2
* )
* Array
* (
* [0] => 2
* [1] => 2
* [2] => 2
* )
*/
class Window
{
private $size = 0;
private $outIndex = 0;
private $winIndex = 0;
private $keys = [];
private $lastKey = null;
private $values = [];
private $buffer = [];
private $tick = 0;
private $sumFunc = null;
private $enableInterpolation = false;
function __construct($size, $interpolate = false)
{
$this->size = max(1, $size);
$this->enableInterpolation = $interpolate;
$this->sumFunc = function($a, $b) { return $a + $b; };
}
function setSumFunction(callable $f) { $this->sumFunc = $f; }
function push($key, $value)
{
if($this->winIndex < $this->size)
$this->winIndex++;
else if($this->tick > 0) {
$this->wrapUp();
$this->outIndex++;
}
$index = $this->makeIndex($this->outIndex);
if($key != $this->lastKey && !isset($this->keys[$index])) {
$this->keys[$index] = $key;
$this->lastKey = $key;
}
$this->buffer[] = $value;
$this->tick++;
}
private function wrapUp()
{
end($this->values);
$lastIndex = key($this->values);
$index = $this->makeIndex($this->outIndex);
$this->values[$index] = array_reduce($this->buffer, $this->sumFunc);
if($lastIndex !== null && $this->enableInterpolation)
$this->interpolate($lastIndex, $index);
$this->winIndex = 1;
$this->buffer = [];
}
private function interpolate($from, $to)
{
$fromValue = $this->values[$from];
$toValue = $this->values[$to];
for($i = $from + 1; $i < $to; $i++) {
$value = (($i - $from) * ($toValue - $fromValue))
/ ($to - $from) + $fromValue;
$this->values[$i] = $value;
}
ksort($this->values);
}
private function makeIndex($index)
{
return $this->enableInterpolation ? $index * $this->size : $index;
}
function getBuffer()
{
return $this->buffer;
}
function getKeys()
{
return $this->keys;
}
function getValues()
{
if(!empty($this->buffer))
$this->wrapUp();
return $this->values;
}
function getSize()
{
return $this->size;
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment