Skip to content
This repository has been archived by the owner on Jul 8, 2018. It is now read-only.

Commit

Permalink
Merge pull request #2 from pinepain/eliminate_duplication
Browse files Browse the repository at this point in the history
Add behavior logic to WeakKeyValueMap and use inheritance
  • Loading branch information
pinepain committed Jan 20, 2016
2 parents 8f8a1c6 + 5ec0e84 commit e8f0f61
Show file tree
Hide file tree
Showing 9 changed files with 217 additions and 263 deletions.
2 changes: 2 additions & 0 deletions .scrutinizer.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
tools:
external_code_coverage: true
6 changes: 5 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,4 +27,8 @@ before_script:
- composer install

script:
- vendor/bin/phpunit --coverage-text --configuration phpunit.xml
- vendor/bin/phpunit --coverage-text --configuration phpunit.xml --coverage-clover=coverage.clover

after_script:
- wget https://scrutinizer-ci.com/ocular.phar
- php ocular.phar code-coverage:upload --format=php-clover coverage.clover
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
# Weak-referenced data structures for PHP [![Build Status](https://travis-ci.org/pinepain/php-weak-lib.svg)](https://travis-ci.org/pinepain/php-weak-lib)
# Weak-referenced data structures for PHP

[![Build Status](https://travis-ci.org/pinepain/php-weak-lib.svg)](https://travis-ci.org/pinepain/php-weak-lib)
[![Scrutinizer Code Quality](https://scrutinizer-ci.com/g/pinepain/php-weak-lib/badges/quality-score.png)](https://scrutinizer-ci.com/g/pinepain/php-weak-lib)
[![Code Coverage](https://scrutinizer-ci.com/g/pinepain/php-weak-lib/badges/coverage.png)](https://scrutinizer-ci.com/g/pinepain/php-weak-lib)

This library is based on [php-weak][php-weak-ext] PHP extension and provides various weak data structures:

Expand Down
169 changes: 169 additions & 0 deletions src/AbstractWeakMap.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,169 @@
<?php

/*
* This file is part of the pinepain/php-weak-lib PHP library.
*
* Copyright (c) 2016 Bogdan Padalko <[email protected]>
*
* Licensed under the MIT license: http://opensource.org/licenses/MIT
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code or visit http://opensource.org/licenses/MIT
*/

namespace Weak;

use RuntimeException;
use SplObjectStorage;

abstract class AbstractWeakMap extends SplObjectStorage
{
const WEAK_KEY = 1;
const WEAK_VAL = 2;

protected $behavior = 0;

/** {@inheritdoc} */
public function attach($object, $data = null)
{
if ($this->behavior & self::WEAK_KEY) {
$object = $this->buildWeakKey($object);
}

if ($this->behavior & self::WEAK_VAL) {
$data = $this->buildWeakValue($object, $data);
}

parent::attach($object, $data);
}

/** {@inheritdoc} */
public function current()
{
$object = parent::current();

if ($this->behavior & self::WEAK_KEY) {
$object = $this->extractWeakObject($object);
}

/* In some rare cases (it should never happen normally) orphaned weak reference may occurs in storage, so
* so current object here MAY be null
*/

return $object;
}

/** {@inheritdoc} */
public function addAll($storage)
{
foreach ($storage as $obj) {
$this->attach($obj, $storage[$obj]);
}
}

/** {@inheritdoc} */
public function removeAllExcept($storage)
{
$pending_removal = new \SplObjectStorage();

foreach ($this as $obj) {
if (!$storage->contains($obj)) {
$pending_removal->attach($obj);
}
}

$this->removeAll($pending_removal);
}

/** {@inheritdoc} */
public function getHash($object)
{
if ($this->behavior & self::WEAK_KEY) {
if ($object instanceof HashedReference) {
return $object->getHash();
}
}

return parent::getHash($object);
}

/** {@inheritdoc} */
public function getInfo()
{
$info = parent::getInfo();

if ($this->behavior & self::WEAK_VAL) {
$info = $this->extractWeakObject($info);
}

return $info;
}

/** {@inheritdoc} */
public function setInfo($data)
{
$object = $this->current();

if (!$object) {
return; // nothing to do
}

if ($this->behavior & self::WEAK_VAL) {
$data = $this->buildWeakValue($object, $data);
}

parent::setInfo($data);
}

/** {@inheritdoc} */
public function offsetSet($object, $data = null)
{
$this->attach($object, $data);
}

/** {@inheritdoc} */
public function offsetGet($object)
{
$info = parent::offsetGet($object);

if ($this->behavior & self::WEAK_VAL) {
$info = $this->extractWeakObject($info);
}

return $info;
}

protected function validateInfo($data)
{
if (!is_object($data)) {
throw new RuntimeException(static::class . ' expects data to be object, ' . gettype($data) . ' given');
}
}

protected function extractWeakObject($object)
{
if ($object instanceof Reference) {
$object = $object->get();
}

return $object;
}

protected function buildWeakKey($object)
{
$object = new HashedReference($object, [$this, 'detach'], 'spl_object_hash');

return $object;
}

protected function buildWeakValue($object, $data)
{
$this->validateInfo($data);

$data = new Reference($data, function () use ($object) {
$this->detach($object);
});

return $data;
}
}
66 changes: 2 additions & 64 deletions src/WeakKeyMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,69 +13,7 @@

namespace Weak;

use SplObjectStorage;

class WeakKeyMap extends SplObjectStorage
class WeakKeyMap extends AbstractWeakMap
{
/** {@inheritdoc} */
public function attach($object, $data = null)
{
$object = new HashedReference($object, [$this, 'detach'], 'spl_object_hash');

parent::attach($object, $data);
}

/** {@inheritdoc} */
public function current()
{
$current = parent::current();

if ($current instanceof Reference) {
$current = $current->get();
}

/* In some rare cases (it should never happens normally) orphaned weak reference may occurs in storage, so
* so $current here MAY be null
*/

return $current;
}

/** {@inheritdoc} */
public function offsetSet($object, $data = null)
{
$this->attach($object, $data);
}

/** {@inheritdoc} */
public function addAll($storage)
{
foreach ($storage as $obj) {
$this->attach($obj, $storage[$obj]);
}
}

/** {@inheritdoc} */
public function removeAllExcept($storage)
{
$pending_removal = new \SplObjectStorage();

foreach ($this as $obj) {
if (!$storage->contains($obj)) {
$pending_removal->attach($obj);
}
}

$this->removeAll($pending_removal);
}

/** {@inheritdoc} */
public function getHash($object)
{
if ($object instanceof HashedReference) {
return $object->getHash();
}

return parent::getHash($object);
}
protected $behavior = self::WEAK_KEY;
}
121 changes: 2 additions & 119 deletions src/WeakKeyValueMap.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,124 +13,7 @@

namespace Weak;

use RuntimeException;
use SplObjectStorage;

class WeakKeyValueMap extends SplObjectStorage
class WeakKeyValueMap extends AbstractWeakMap
{
/** {@inheritdoc} */
public function attach($object, $data = null)
{
$this->validateInfo($data);

$object = new HashedReference($object, [$this, 'detach'], 'spl_object_hash');

$data = new Reference($data, function () use ($object) {
$this->detach($object);
});

parent::attach($object, $data);
}

/** {@inheritdoc} */
public function current()
{
$current = parent::current();

if ($current instanceof Reference) {
$current = $current->get();
}

/* In some rare cases (it should never happens normally) orphaned weak reference may occurs in storage, so
* so $current here MAY be null
*/

return $current;
}

/** {@inheritdoc} */
public function addAll($storage)
{
foreach ($storage as $obj) {
$this->attach($obj, $storage[$obj]);
}
}

public function removeAllExcept($storage)
{
$pending_removal = new \SplObjectStorage();

foreach ($this as $obj) {
if (!$storage->contains($obj)) {
$pending_removal->attach($obj);
}
}

$this->removeAll($pending_removal);
}

/** {@inheritdoc} */
public function getHash($object)
{
if ($object instanceof HashedReference) {
return $object->getHash();
}

return parent::getHash($object);
}

/** {@inheritdoc} */
public function getInfo()
{
$info = parent::getInfo(); // TODO: Change the autogenerated stub

if ($info instanceof Reference) {
$info = $info->get();
}

return $info;
}

/** {@inheritdoc} */
public function setInfo($data)
{
$this->validateInfo($data);

$object = $this->current();

if (!$object) {
return; // nothing to do
}

$data = new Reference($data, function () use ($object) {
$this->detach($object);
});

parent::setInfo($data);
}

/** {@inheritdoc} */
public function offsetSet($object, $data = null)
{
$this->attach($object, $data);
}

/** {@inheritdoc} */
public function offsetGet($object)
{
$info = parent::offsetGet($object); // TODO: Change the autogenerated stub

if ($info instanceof Reference) {
$info = $info->get();
}

return $info;
}

protected function validateInfo($data)
{
if (!is_object($data)) {
throw new RuntimeException(self::class . ' expects data to be object, ' . gettype($data) . ' given');
}
}
protected $behavior = self::WEAK_KEY | self::WEAK_VAL;
}
Loading

0 comments on commit e8f0f61

Please sign in to comment.