00001 """
00002 class to run as many simultaneous commands at the same time
00003 """
00004
00005 __copyright__ = """
00006 Copyright 2008 Sean Ross-Ross
00007 """
00008 __license__ = """
00009 This file is part of SLIMpy .
00010
00011 SLIMpy is free software: you can redistribute it and/or modify
00012 it under the terms of the GNU Lesser General Public License as published by
00013 the Free Software Foundation, either version 3 of the License, or
00014 (at your option) any later version.
00015
00016 SLIMpy is distributed in the hope that it will be useful,
00017 but WITHOUT ANY WARRANTY; without even the implied warranty of
00018 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00019 GNU Lesser General Public License for more details.
00020
00021 You should have received a copy of the GNU Lesser General Public License
00022 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00023 """
00024
00025
00026 from slimpy_base.Core.Graph.Cleaner import cleaner
00027 from slimpy_base.Core.Runners.RunnerBase import Runner
00028 import pdb
00029
00030
00031 class presStack( Runner ):
00032 """
00033 class to run as many simultaneous commands at the same time
00034 """
00035
00036 def __init__(self):
00037 Runner.__init__( self )
00038
00039 def set_graph( self, graph ):
00040 self.status = {}
00041 self.ready = {}
00042 self.sources = set()
00043 self.cleaner = cleaner( graph )
00044 self.G = graph
00045
00046 for u in self.G.getSourceNodes():
00047 self.ready[u] = True
00048
00049 return
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059 def pull( self , u=None ):
00060 """
00061 pull a command of the top of the ready stack
00062 may return none if there are no
00063 ready nodes
00064 """
00065 if u is None:
00066 if not self.ready.keys():
00067 return None
00068 u = self.ready.keys()[0]
00069
00070
00071 del self.ready[u]
00072 self.status[u] = 'working'
00073 return u
00074
00075 def pop( self, u ):
00076 """
00077 @param u: node in the graph
00078 @precondition: u was a node pulled by the
00079 pull command
00080 @postcondition:
00081 1. for each 'D' a dependent of u if all of 'D's dependencies
00082 are met, 'D' will be added to the ready stack
00083 2. u will be passes to the current cleaner
00084 3. u will be added to the graphs source nodes
00085
00086 """
00087
00088 if not self.status.has_key(u):
00089 raise Exception( "node %s has not been pulled from top of stack" %u )
00090 if not self.status[u] == 'working':
00091 return False
00092 self.status[u] = 'done'
00093
00094 self.sources.add( u )
00095
00096
00097 self.clean( u )
00098
00099 for v in self.G.adj( u ):
00100 isready = True
00101 for w in self.G.invAdj( v ):
00102 isready = isready and w in self.sources
00103 if isready:
00104 self.ready[v] = True
00105 return True
00106
00107 def has_ready(self):
00108 return len( self.ready)
00109
00110 def has_ready_data(self):
00111 return len([ key for key in self.ready.keys() if not isinstance( key, tuple) ])
00112
00113 def pull_data(self):
00114 for key in self.ready.keys():
00115 if isinstance(key, tuple):
00116 continue
00117 else:
00118 return self.pull(key)
00119
00120 return False
00121
00122
00123 def has_more_jobs(self):
00124 ready = self.has_ready()
00125 working = self.num_working()
00126 return ready or working
00127
00128 def num_working(self):
00129 return len( [ stat for stat in self.status.values() if stat == 'working' ] )
00130
00131 def clean( self, node ):
00132 """
00133 adds a node to the cleaner
00134 """
00135 self.cleaner.clean( node )
00136
00137
00138
00139
00140
00141
00142
00143
00144
00145