Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,16 +26,14 @@ Once [installed](#install), let's initialize a sample graph:
```php
<?php

use \Graphp\Graph\Graph as Graph;

require_once 'vendor/autoload.php';

$graph = new Graph();
$graph = new Graphp\Graph\Graph();

// create some cities
$rome = $graph->createVertex('Rome');
$madrid = $graph->createVertex('Madrid');
$cologne = $graph->createVertex('Cologne');
$rome = $graph->createVertex()->setAttribute('name', 'Rome');
$madrid = $graph->createVertex()->setAttribute('name', 'Madrid');
$cologne = $graph->createVertex()->setAttribute('name', 'Cologne');

// build some roads
$graph->createEdgeDirected($cologne, $madrid);
Expand All @@ -48,8 +46,8 @@ Let's see which city (Vertex) has a road (i.e. an edge pointing) to Rome:

```php
foreach ($rome->getVerticesEdgeFrom() as $vertex) {
echo $vertex->getId().' leads to rome'.PHP_EOL;
// result: Madrid and Rome itself
echo $vertex->getAttribute('name') . ' leads to Rome' . PHP_EOL;
// result: Madrid and Rome itself lead to Rome
}
```

Expand Down
112 changes: 7 additions & 105 deletions src/Graph.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,9 @@
use Graphp\Graph\Attribute\AttributeBagReference;
use Graphp\Graph\Exception\InvalidArgumentException;
use Graphp\Graph\Exception\OutOfBoundsException;
use Graphp\Graph\Exception\OverflowException;
use Graphp\Graph\Set\DualAggregate;
use Graphp\Graph\Set\Edges;
use Graphp\Graph\Set\Vertices;
use Graphp\Graph\Set\VerticesMap;

class Graph implements DualAggregate, AttributeAware
{
Expand All @@ -24,7 +22,7 @@ class Graph implements DualAggregate, AttributeAware

public function __construct()
{
$this->vertices = VerticesMap::factoryArrayReference($this->verticesStorage);
$this->vertices = Vertices::factoryArrayReference($this->verticesStorage);
$this->edges = Edges::factoryArrayReference($this->edgesStorage);
}

Expand All @@ -51,24 +49,11 @@ public function getEdges()
/**
* create a new Vertex in the Graph
*
* @param int|NULL $id new vertex ID to use (defaults to NULL: use next free numeric ID)
* @param bool $returnDuplicate normal operation is to throw an exception if given id already exists. pass true to return original vertex instead
* @return Vertex (chainable)
* @throws InvalidArgumentException if given vertex $id is invalid
* @throws OverflowException if given vertex $id already exists and $returnDuplicate is not set
* @uses Vertex::getId()
* @return Vertex
*/
public function createVertex($id = NULL, $returnDuplicate = false)
public function createVertex()
{
// no ID given
if ($id === NULL) {
$id = $this->getNextId();
}
if ($returnDuplicate && $this->vertices->hasVertexId($id)) {
return $this->vertices->getVertexId($id);
}

return new Vertex($this, $id);
return new Vertex($this);
}

/**
Expand Down Expand Up @@ -105,86 +90,6 @@ public function createEdgeDirected(Vertex $source, Vertex $target)
return new EdgeDirected($source, $target);
}

/**
* create the given number of vertices or given array of Vertex IDs
*
* @param int|array $n number of vertices to create or array of Vertex IDs to create
* @return Vertices set of Vertices created
* @uses Graph::getNextId()
*/
public function createVertices($n)
{
$vertices = array();
if (\is_int($n) && $n >= 0) {
for ($id = $this->getNextId(), $n += $id; $id < $n; ++$id) {
$vertices[$id] = new Vertex($this, $id);
}
} elseif (\is_array($n)) {
// array given => check to make sure all given IDs are available (atomic operation)
foreach ($n as $id) {
if (!\is_int($id) && !\is_string($id)) {
throw new InvalidArgumentException('All Vertex IDs have to be of type integer or string');
} elseif ($this->vertices->hasVertexId($id)) {
throw new OverflowException('Given array of Vertex IDs contains an ID that already exists. Given IDs must be unique');
} elseif (isset($vertices[$id])) {
throw new InvalidArgumentException('Given array of Vertex IDs contain duplicate IDs. Given IDs must be unique');
}

// temporary marker to check for duplicate IDs in the array
$vertices[$id] = false;
}

// actually create all requested vertices
foreach ($n as $id) {
$vertices[$id] = new Vertex($this, $id);
}
} else {
throw new InvalidArgumentException('Invalid number of vertices given. Must be non-negative integer or an array of Vertex IDs');
}

return new Vertices($vertices);
}

/**
* get next free/unused/available vertex ID
*
* its guaranteed there's NO other vertex with a greater ID
*
* @return int
*/
private function getNextId()
{
if (!$this->verticesStorage) {
return 0;
}

// auto ID
return \max(\array_keys($this->verticesStorage))+1;
}

/**
* returns the Vertex with identifier $id
*
* @param int|string $id identifier of Vertex
* @return Vertex
* @throws OutOfBoundsException if given vertex ID does not exist
*/
public function getVertex($id)
{
return $this->vertices->getVertexId($id);
}

/**
* checks whether given vertex ID exists in this graph
*
* @param int|string $id identifier of Vertex
* @return bool
*/
public function hasVertex($id)
{
return $this->vertices->hasVertexId($id);
}

/**
* adds a new Vertex to the Graph (MUST NOT be called manually!)
*
Expand All @@ -195,10 +100,7 @@ public function hasVertex($id)
*/
public function addVertex(Vertex $vertex)
{
if (isset($this->verticesStorage[$vertex->getId()])) {
throw new OverflowException('ID must be unique');
}
$this->verticesStorage[$vertex->getId()] = $vertex;
$this->verticesStorage[] = $vertex;
}

/**
Expand Down Expand Up @@ -259,7 +161,7 @@ public function __clone()
{
$vertices = $this->verticesStorage;
$this->verticesStorage = array();
$this->vertices = VerticesMap::factoryArrayReference($this->verticesStorage);
$this->vertices = Vertices::factoryArrayReference($this->verticesStorage);

$edges = $this->edgesStorage;
$this->edgesStorage = array();
Expand All @@ -269,7 +171,7 @@ public function __clone()
foreach ($vertices as $originalVertex) {
\assert($originalVertex instanceof Vertex);

$vertex = new Vertex($this, $originalVertex->getId());
$vertex = new Vertex($this);
$vertex->getAttributeBag()->setAttributes($originalVertex->getAttributeBag()->getAttributes());

// create map with old vertex hash to new vertex object
Expand Down
85 changes: 19 additions & 66 deletions src/Set/Vertices.php
Original file line number Diff line number Diff line change
Expand Up @@ -67,36 +67,6 @@ public function __construct(array $vertices = array())
$this->vertices = $vertices;
}

/**
* get Vertex with the given vertex $id
*
* @param int|string $id
* @return Vertex
* @throws OutOfBoundsException if no Vertex with the given ID exists
* @uses self::getVertexMatch()
*/
public function getVertexId($id)
{
try {
return $this->getVertexMatch($this->getCallbackId($id));
}
catch (UnderflowException $e) {
throw new OutOfBoundsException('Vertex ' . $id . ' does not exist', 0, $e);
}
}

/**
* checks whether given vertex ID exists in this set of vertices
*
* @param int|string $id identifier of Vertex
* @return bool
* @uses self::hasVertexMatch()
*/
public function hasVertexId($id)
{
return $this->hasVertexMatch($this->getCallbackId($id));
}

/**
* get array index for given Vertex
*
Expand Down Expand Up @@ -353,41 +323,22 @@ public function getVertices()
/**
* get a new set of Vertices where each Vertex is distinct/unique
*
* @return VerticesMap a new VerticesMap instance
* Vertex index/keys will be preserved from original array.
*
* @return Vertices
* @uses self::getMap()
*/
public function getVerticesDistinct()
{
return new VerticesMap($this->getMap());
}

/**
* get a mapping array of Vertex ID => Vertex instance and thus remove duplicate vertices
*
* @return Vertex[] Vertex ID => Vertex instance
* @uses Vertex::getId()
*/
public function getMap()
{
$vertices = array();
foreach ($this->vertices as $vertex) {
$vertices[$vertex->getId()] = $vertex;
foreach ($this->vertices as $vid => $vertex) {
// filter duplicate vertices
if (!\in_array($vertex, $vertices, true)) {
$vertices[$vid] = $vertex;
}
}
return $vertices;
}

/**
* return array of Vertex IDs
*
* @return array
*/
public function getIds()
{
$ids = array();
foreach ($this->vertices as $vertex) {
$ids []= $vertex->getId();
}
return $ids;
return new self($vertices);
}

/**
Expand Down Expand Up @@ -432,7 +383,16 @@ public function isEmpty()
*/
public function hasDuplicates()
{
return (\count($this->vertices) !== \count($this->getMap()));
$found = array();
foreach ($this->vertices as $vertex) {
if (\in_array($vertex, $found, true)) {
return true;
}

$found[] = $vertex;
}

return false;
}

/**
Expand Down Expand Up @@ -466,13 +426,6 @@ public function getSumCallback($callback)
return $sum;
}

private function getCallbackId($id)
{
return function (Vertex $vertex) use ($id) {
return ($vertex->getId() == $id);
};
}

private function getVertexMatchOrNull($callbackCheck)
{
$callbackCheck = $this->getCallback($callbackCheck);
Expand Down
67 changes: 0 additions & 67 deletions src/Set/VerticesMap.php

This file was deleted.

Loading