00001 """
00002 HASHTABLE CLASS
00003 contains all active and nonactive nodes ever made
00004 """
00005
00006 __copyright__ = """
00007 Copyright 2008 Sean Ross-Ross
00008 """
00009 __license__ = """
00010 This file is part of SLIMpy .
00011
00012 SLIMpy is free software: you can redistribute it and/or modify
00013 it under the terms of the GNU Lesser General Public License as published by
00014 the Free Software Foundation, either version 3 of the License, or
00015 (at your option) any later version.
00016
00017 SLIMpy is distributed in the hope that it will be useful,
00018 but WITHOUT ANY WARRANTY; without even the implied warranty of
00019 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
00020 GNU Lesser General Public License for more details.
00021
00022 You should have received a copy of the GNU Lesser General Public License
00023 along with SLIMpy . If not, see <http://www.gnu.org/licenses/>.
00024 """
00025
00026 from slimpy_base.Environment.Singleton import Singleton
00027 from atexit import register as __register__
00028
00029 from slimpy_base.Environment.InstanceManager import InstanceManager
00030 from sys import getrefcount
00031
00032
00033 class _HashTable( Singleton ):
00034 """
00035 Basic hash table (same as __builtin__.dict)
00036
00037 """
00038 env = InstanceManager()
00039
00040 def __new_instance__( self , name ):
00041
00042 Singleton.__new_instance__(self, name)
00043 self._hash = {}
00044 self._scalars = {}
00045 self._no_clean = False
00046
00047
00048
00049 __register__( self.clear_at_exit )
00050
00051 def __len__(self):
00052 return len( self.getHash() )
00053
00054 def has_key( self, k ):
00055 return self.getHash().has_key(k)
00056
00057 def has_active_referers( self, node_id ):
00058
00059 datacontainer = self[node_id]
00060 if not hasattr(datacontainer,'referrers'):
00061 return False
00062
00063 for ref in datacontainer.referrers:
00064 if self[ref].isfull():
00065 return True
00066
00067 return False
00068
00069 def __clean__( self ):
00070 self.clear()
00071
00072 def _do_not_clean(self):
00073 self._no_clean = True
00074
00075 def get_scalars_map(self):
00076 return self._scalars
00077
00078 scalars_map = property( get_scalars_map )
00079
00080 def getHash( self ):
00081 return self._hash
00082
00083 def _get_table( self ):
00084 return self._hash
00085
00086 def _set_table(self,table):
00087 self._hash = table
00088
00089 _map = property( _get_table, _set_table)
00090
00091 def __getitem__( self, item ):
00092
00093 try:
00094
00095 return self.getHash().__getitem__( item )
00096 except KeyError, msg:
00097
00098 raise KeyError, msg
00099
00100 def __setitem__( self, item, val ):
00101 return self.getHash().__setitem__( item, val )
00102
00103 def items( self ):
00104
00105 return self._map.items()
00106
00107 def values( self ):
00108 return self._map.values()
00109
00110 def __str__( self ):
00111 s = "<Table{'%(i_name)s'}: %(elements)s elements, %(active)s active>"
00112 i_name = self._instance_name
00113 active = len(self.getActiveSet())
00114 elements = len(self.getHash())
00115
00116
00117 return s %vars()
00118
00119 def __repr__( self ):
00120
00121 return self.__str__()
00122
00123 def __contains__(self,item):
00124 return self._map.__contains__( item )
00125
00126 def append( self, item ):
00127 """
00128 appends item to the hash table
00129 @Returns the id of item
00130 """
00131 itemID = id( item )
00132 self._map[itemID] = item
00133 return itemID
00134
00135 def getActiveSet( self ):
00136 return [item[0] for item in self.items() if getrefcount( item[1] ) > 3 ]
00137
00138 def clear_at_exit( self ):
00139 """
00140 same as clear
00141 """
00142 self.clear()
00143
00144 def clear( self ):
00145 """
00146 for each item in the graph try to remove it
00147 """
00148 if self._no_clean:
00149 return
00150
00151 log = self.env['record']( 10, 'cleaner' )
00152 print >> log , "clear all called"
00153 from slimpy_base.Core.Interface.ContainerBase import DataContainer
00154
00155 for node in self.values():
00156
00157
00158 if isinstance( node , DataContainer ):
00159
00160
00161 data = node.data
00162 print >> log , "removing %(data)s" %vars()
00163 node.remove()
00164
00165 self._map.clear()
00166
00167
00168 def getRef( self, item ):
00169 """
00170 returns the refrence count of the value that item
00171 points to
00172 """
00173 return getrefcount( self[item] )-2
00174
00175 def printHash( self ):
00176 """
00177 Prints a formated output of the hash table
00178 """
00179 log = self.env['record']
00180
00181 print >>log, " ID | ref | Value"
00182 print >>log, '-----------+-----+------------'
00183 for item in self.items():
00184 print >> log, "%10d | %03d | %s" %( item[0], getrefcount( item[1] )-2, item[1] )
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210
00211
00212
00213
00214 def removeSource( self, src ):
00215 """
00216 remove a node from the set of sources
00217 """
00218
00219