Skip to content

Commit

Permalink
PHP7.4 new feature. Add method getAllValue()
Browse files Browse the repository at this point in the history
  • Loading branch information
fdreamsu committed Sep 25, 2020
1 parent e493d63 commit 7b4363e
Show file tree
Hide file tree
Showing 9 changed files with 994 additions and 899 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
/composer.lock
/cli/
22 changes: 15 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -22,13 +22,13 @@ $tree->setValue(50000, 60000, 'key2', new \SplQueue());
$tree->setValue(99999, 100000, 'key3', 'some value');

// Get value of certain position.
var_dump($tree->getValue(20006));
var_dump($tree->getValue(20006, 'key1'));

// Delete value of between certain postions.
// Delete value of between certain positions.
$tree->delValue(30000, 100000, 'key1');

// Thorws exception when value not found.
var_dump($tree->getValue(70000));
// Throws exception when value not found.
var_dump($tree->getValue(70000, 'key1'));

// Get segment arrays.
var_dump($tree->getSegmentsOfGivenKey('key1'));
Expand All @@ -46,10 +46,18 @@ $tree = Swango\SegmentTree\Tree\Version::newTree(
'1.0.0', '1.0.1', '1.0.2', '1.0.3', '1.1.0', '1.4.1', '2.0.0', '2.0.1-RC1', '3.0.0'
); // Create a tree with versions. These versions will be sorted using version_compare() and remove all duplicated

// All methos are similar with Common tree.
$tree->setValue('1.0.2', '2.0.0', 'key1', $true);
// All methods are similar with Common tree.
$tree->setValue('1.0.2', '2.0.0', 'key1', true);
var_dump($tree->getValue('1.1.0'));
```
### Date compressed segment tree
(todo)
```php
$tree = Swango\SegmentTree\Tree\Date::newTree(
'2020-09-25', '2020-12-12'
); // Create a tree with dates.

// All methods are similar with Common tree.
$tree->setValue('2020-09-29', '2020-11-11', 'key1', true);
var_dump($tree->getValue('2020-11-01'));
```

253 changes: 128 additions & 125 deletions src/AbstractSegmentTree.php
Original file line number Diff line number Diff line change
@@ -1,126 +1,129 @@
<?php
namespace Swango\SegmentTree;
abstract class AbstractSegmentTree extends Node {
/**
* Get all existing keys.
* Some keys maybe deleted or override by others.
*
* @return array
*/
public function getAllExistingKeys(): array {
$ret = [];
foreach ($this->data as $key=>&$tmp)
$ret[] = $key;
return $key;
}
protected $use_double_equal_sign = true;
protected function isEqual($x, $y): bool {
if ($x instanceof MixtureFlag || $y instanceof MixtureFlag)
return false;
if ($this->use_double_equal_sign)
return $x == $y;
else
return $x === $y;
}
/**
* Set to use "==" when comparing values.
* Two objects of different instances that have same content will be considered equal.
*
* This is a default setting. No need to call manualy.
* Must be called before set any value or things could be corrupted.
*
* @return self
*/
public function useDoubleEqualSign(): self {
$this->use_double_equal_sign = true;
return $this;
}
/**
* Set to use "===" when comparing values.
* Two objects of different instances will be considered not equal no matter their content.
*
* Must be called before set any value or things could be corrupted.
*
* @return self
*/
public function useTripleEqualSign(): self {
$this->use_double_equal_sign = false;
return $this;
}
/**
* fill $key of the whole tree by $value
*
* @param string $key
* @param mixed $value
* @return self
*/
public function fill(string $key, $value): self {
$this->_setValue($this->l, $this->r, $key, $value);
return $this;
}
/**
* Clear all values and child nodes.
* Make it a new tree.
*
* @return self
*/
public function clear(): self {
$this->data = new \stdClass();
$this->node_l = null;
$this->node_r = null;
return $this;
}
/**
* Remove all redundant nodes in the tree to reduce memory cost.
*
* @return self
*/
public function optimize(): self {
if (! $this->hasChildNode())
return $this;
$queue = new \SplQueue();
$queue->enqueue($this);
do {
/**
*
* @var Node $node
*/
$node = $queue->dequeue();
foreach ($node->data as $value)
if ($value instanceof MixtureFlag) {
if ($node->node_l->hasChildNode())
$queue->enqueue($node->node_l);
if ($node->node_r->hasChildNode())
$queue->enqueue($node->node_r);
continue 2;
}

$node->node_l = null;
$node->node_r = null;
} while ( ! $queue->isEmpty() );
return $this;
}
/**
* Get number of nodes in the tree
*
* @return int
*/
public function getNodesCount(): int {
$count = 0;
$queue = new \SplQueue();
$queue->enqueue($this);
do {
++ $count;
/**
*
* @var Node $node
*/
$node = $queue->dequeue();
if ($node->hasChildNode()) {
$queue->enqueue($node->node_l);
$queue->enqueue($node->node_r);
}
} while ( ! $queue->isEmpty() );
return $count;
}
<?php
namespace Swango\SegmentTree;
abstract class AbstractSegmentTree extends Node {
/**
* Get all existing keys.
* Some keys maybe deleted or override by others.
*
* @return array
*/
public function getAllExistingKeys(): array {
$ret = [];
foreach ($this->data as $key => &$tmp)
$ret[] = $key;
return $key;
}
protected bool $use_double_equal_sign = true;
protected function isEqual($x, $y): bool {
if ($x instanceof MixtureFlag || $y instanceof MixtureFlag) {
return false;
}
if ($this->use_double_equal_sign) {
return $x == $y;
} else {
return $x === $y;
}
}
/**
* Set to use "==" when comparing values.
* Two objects of different instances that have same content will be considered equal.
*
* This is a default setting. No need to call manually.
* Must be called before set any value or things could be corrupted.
*
* @return self
*/
public function useDoubleEqualSign(): self {
$this->use_double_equal_sign = true;
return $this;
}
/**
* Set to use "===" when comparing values.
* Two objects of different instances will be considered not equal no matter their content.
*
* Must be called before set any value or things could be corrupted.
*
* @return self
*/
public function useTripleEqualSign(): self {
$this->use_double_equal_sign = false;
return $this;
}
/**
* fill $key of the whole tree by $value
*
* @param string $key
* @param mixed $value
* @return self
*/
public function fill(string $key, $value): self {
$this->_setValue($this->l, $this->r, $key, $value);
return $this;
}
/**
* Clear all values and child nodes.
* Make it a new tree.
*
* @return self
*/
public function clear(): self {
$this->data = new \stdClass();
unset($this->node_l);
unset($this->node_r);
return $this;
}
/**
* Remove all redundant nodes in the tree to reduce memory cost.
*
* @return self
*/
public function optimize(): self {
if (! $this->hasChildNode()) {
return $this;
}
$queue = new \SplQueue();
$queue->enqueue($this);
do {
/**
*
* @var Node $node
*/
$node = $queue->dequeue();
foreach ($node->data as $value)
if ($value instanceof MixtureFlag) {
if ($node->node_l->hasChildNode()) {
$queue->enqueue($node->node_l);
}
if ($node->node_r->hasChildNode()) {
$queue->enqueue($node->node_r);
}
continue 2;
}
unset($this->node_l);
unset($this->node_r);
} while (! $queue->isEmpty());
return $this;
}
/**
* Get number of nodes in the tree
*
* @return int
*/
public function getNodesCount(): int {
$count = 0;
$queue = new \SplQueue();
$queue->enqueue($this);
do {
++$count;
/**
* @var Node $node
*/
$node = $queue->dequeue();
if ($node->hasChildNode()) {
$queue->enqueue($node->node_l);
$queue->enqueue($node->node_r);
}
} while (! $queue->isEmpty());
return $count;
}
}
35 changes: 17 additions & 18 deletions src/MixtureFlag.php
Original file line number Diff line number Diff line change
@@ -1,19 +1,18 @@
<?php
namespace Swango\SegmentTree;
/**
* This is only a simple object used as a flag.
*
* @author fdrea
*
*/
class MixtureFlag {
private static $instance;
public static function getInstance(): MixtureFlag {
if (isset(self::$instance))
return self::$instance;
$instance = new self();
self::$instance = $instance;
return $instance;
}
private function __construct() {}
<?php
namespace Swango\SegmentTree;
/**
* This is only a simple object used as flag.
*/
final class MixtureFlag {
private static MixtureFlag $instance;
public static function getInstance(): MixtureFlag {
if (isset(self::$instance)) {
return self::$instance;
}
$instance = new self();
self::$instance = $instance;
return $instance;
}
private function __construct() {
}
}
Loading

0 comments on commit 7b4363e

Please sign in to comment.