Author: romanb
Date: 2008-09-12 11:06:42 +0100 (Fri, 12 Sep 2008)
New Revision: 4926

Added:
   trunk/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php
   trunk/lib/Doctrine/ORM/Internal/CommitOrderNode.php
Removed:
   trunk/lib/Doctrine/Internal/
Modified:
   trunk/lib/Doctrine/Connection/UnitOfWork.php
Log:
moved commitordercalculator/node

Modified: trunk/lib/Doctrine/Connection/UnitOfWork.php
===================================================================
--- trunk/lib/Doctrine/Connection/UnitOfWork.php        2008-09-12 10:02:06 UTC 
(rev 4925)
+++ trunk/lib/Doctrine/Connection/UnitOfWork.php        2008-09-12 10:06:42 UTC 
(rev 4926)
@@ -124,7 +124,7 @@
     {
         $this->_em = $em;
         //TODO: any benefit with lazy init?
-        $this->_commitOrderCalculator = new 
Doctrine_Internal_CommitOrderCalculator();
+        $this->_commitOrderCalculator = new 
Doctrine_ORM_Internal_CommitOrderCalculator();
     }
 
     /**

Added: trunk/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php
===================================================================
--- trunk/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php                   
        (rev 0)
+++ trunk/lib/Doctrine/ORM/Internal/CommitOrderCalculator.php   2008-09-12 
10:06:42 UTC (rev 4926)
@@ -0,0 +1,129 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+#namespace Doctrine::ORM::Internal;
+
+/**
+ * The CommitOrderCalculator is used by the UnitOfWork to sort out the
+ * correct order in which changes to entities need to be persisted.
+ *
+ * @since 2.0
+ * @todo Rename to: CommitOrderCalculator
+ * @author Roman Borschel <[EMAIL PROTECTED]> 
+ */
+class Doctrine_ORM_Internal_CommitOrderCalculator
+{
+    private $_currentTime;
+    
+    /**
+     * The node list used for sorting.
+     *
+     * @var array
+     */
+    private $_nodes = array();
+    
+    /**
+     * The topologically sorted list of items. Note that these are not nodes
+     * but the wrapped items.
+     *
+     * @var array
+     */
+    private $_sorted;
+    
+    /**
+     * Orders the given list of CommitOrderNodes based on their dependencies.
+     * 
+     * Uses a depth-first search (DFS) to traverse the graph.
+     * The desired topological sorting is the reverse postorder of these 
searches.
+     *
+     * @param array $nodes  The list of (unordered) CommitOrderNodes.
+     * @return array  The list of ordered items. These are the items wrapped 
in the nodes.
+     */
+    public function getCommitOrder()
+    {
+        // Check whether we need to do anything. 0 or 1 node is easy.
+        $nodeCount = count($this->_nodes);
+        if ($nodeCount == 0) {
+            return array();
+        } else if ($nodeCount == 1) {
+            $node = array_pop($this->_nodes);
+            return array($node->getClass());
+        }
+        
+        $this->_sorted = array();
+        
+        // Init
+        foreach ($this->_nodes as $node) {
+            $node->markNotVisited();
+            $node->setPredecessor(null);
+        }
+        
+        $this->_currentTime = 0;
+        
+        // Go
+        foreach ($this->_nodes as $node) {
+            if ($node->isNotVisited()) {
+                $node->visit();
+            }
+        }
+        
+        return $this->_sorted;
+    }
+    
+    public function addNode($key, $node)
+    {
+        $this->_nodes[$key] = $node;
+    }
+    
+    public function addNodeWithItem($key, $item)
+    {
+        $this->_nodes[$key] = new Doctrine_ORM_Internal_CommitOrderNode($item, 
$this);
+    }
+    
+    public function getNodeForKey($key)
+    {
+        return $this->_nodes[$key];
+    }
+    
+    public function hasNodeWithKey($key)
+    {
+        return isset($this->_nodes[$key]);
+    }
+    
+    public function clear()
+    {
+        $this->_nodes = array();
+        $this->_sorted = array();
+    }
+    
+    
+    public function getNextTime()
+    {
+        return ++$this->_currentTime;
+    }
+    
+    public function prependNode($node)
+    {
+        array_unshift($this->_sorted, $node->getClass());
+    }
+}
+
+?>
\ No newline at end of file

Added: trunk/lib/Doctrine/ORM/Internal/CommitOrderNode.php
===================================================================
--- trunk/lib/Doctrine/ORM/Internal/CommitOrderNode.php                         
(rev 0)
+++ trunk/lib/Doctrine/ORM/Internal/CommitOrderNode.php 2008-09-12 10:06:42 UTC 
(rev 4926)
@@ -0,0 +1,153 @@
+<?php
+/*
+ *  $Id$
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * This software consists of voluntary contributions made by many individuals
+ * and is licensed under the LGPL. For more information, see
+ * <http://www.phpdoctrine.org>.
+ */
+
+#namespace Doctrine::ORM::Internal;
+
+/**
+ * A CommitOrderNode is a temporary wrapper around ClassMetadata objects
+ * that is used to sort the order of commits.
+ * 
+ * @since 2.0
+ * @author Roman Borschel <[EMAIL PROTECTED]>
+ */
+class Doctrine_ORM_Internal_CommitOrderNode
+{
+    const NOT_VISITED = 1;
+    const IN_PROGRESS = 2;
+    const VISITED = 3;
+    
+    private $_traversalState;
+    private $_predecessor;
+    private $_status;
+    private $_calculator;
+    private $_relatedNodes = array();
+    
+    private $_discoveryTime;
+    private $_finishingTime;
+    
+    private $_wrappedObj;
+    private $_relationEdges = array();
+    
+    
+    public function __construct($wrappedObj, 
Doctrine_ORM_Internal_CommitOrderCalculator $calc)
+    {
+        $this->_wrappedObj = $wrappedObj;
+        $this->_calculator = $calc;
+    }
+    
+    public function getClass()
+    {
+        return $this->_wrappedObj;
+    }
+    
+    public function setPredecessor($node)
+    {
+        $this->_predecessor = $node;
+    }
+    
+    public function getPredecessor()
+    {
+        return $this->_predecessor;
+    }
+    
+    public function markNotVisited()
+    {
+        $this->_traversalState = self::NOT_VISITED;
+    }
+    
+    public function markInProgress()
+    {
+        $this->_traversalState = self::IN_PROGRESS;
+    }
+    
+    public function markVisited()
+    {
+        $this->_traversalState = self::VISITED;
+    }
+    
+    public function isNotVisited()
+    {
+        return $this->_traversalState == self::NOT_VISITED;
+    }
+    
+    public function isInProgress()
+    {
+        return $this->_traversalState == self::IN_PROGRESS;
+    }
+    
+    public function visit()
+    {
+        $this->markInProgress();
+        $this->setDiscoveryTime($this->_calculator->getNextTime());
+        
+        foreach ($this->getRelatedNodes() as $node) {
+            if ($node->isNotVisited()) {
+                $node->setPredecessor($this);
+                $node->visit();
+            }
+            if ($node->isInProgress()) {
+                // back edge => cycle
+                //TODO: anything to do here?
+            }
+        }
+        
+        $this->markVisited();
+        $this->_calculator->prependNode($this);
+        $this->setFinishingTime($this->_calculator->getNextTime());
+    }
+    
+    public function setDiscoveryTime($time)
+    {
+        $this->_discoveryTime = $time;
+    }
+    
+    public function setFinishingTime($time)
+    {
+        $this->_finishingTime = $time;
+    }
+    
+    public function getDiscoveryTime()
+    {
+        return $this->_discoveryTime;
+    }
+    
+    public function getFinishingTime()
+    {
+        return $this->_finishingTime;
+    }
+    
+    public function getRelatedNodes()
+    {
+        return $this->_relatedNodes;
+    }
+    
+    /**
+     * Adds a directed dependency (an edge on the graph). "$this -before-> 
$other".
+     *
+     * @param Doctrine_Internal_CommitOrderNode $node
+     */
+    public function before(Doctrine_ORM_Internal_CommitOrderNode $node)
+    {
+        $this->_relatedNodes[] = $node;
+    }
+}
+
+?>
\ No newline at end of file


--~--~---------~--~----~------------~-------~--~----~
You received this message because you are subscribed to the Google Groups 
"doctrine-svn" group.
 To post to this group, send email to [email protected]
 To unsubscribe from this group, send email to [EMAIL PROTECTED]
 For more options, visit this group at 
http://groups.google.co.uk/group/doctrine-svn?hl=en-GB
-~----------~----~----~----~------~----~------~--~---

Reply via email to