data_smart: Micro optimisation - search for "${" instead of "$"
[vuplus_bitbake] / lib / bb / data_smart.py
index 0c7f6c4..d63fdde 100644 (file)
@@ -29,15 +29,12 @@ Based on functions from the base bb module, Copyright 2003 Holger Schurig
 """
 
 import copy, os, re, sys, time, types
-from bb   import note, debug, error, fatal, utils, methodpool
+import bb
+from bb   import utils, methodpool
+from COW  import COWDictBase
 from sets import Set
 from new  import classobj
 
-try:
-    import cPickle as pickle
-except ImportError:
-    import pickle
-    print "NOTE: Importing cPickle failed. Falling back to a very slow implementation."
 
 __setvar_keyword__ = ["_append","_prepend"]
 __setvar_regexp__ = re.compile('(?P<base>.*?)(?P<keyword>_append|_prepend)(_(?P<add>.*))?')
@@ -45,30 +42,16 @@ __expand_var_regexp__ = re.compile(r"\${[^{}]+}")
 __expand_python_regexp__ = re.compile(r"\${@.+?}")
 
 
-#
-# Meta Class helper for a COW
-# implementation
-#
-class MetaCow:
-    def keys(self):
-        """
-        Return all names (variables) of this dictionary
-        """
-        return filter(lambda x: [True,False][x in ['__doc__','__module__']], dir(self) )
-
-def createMetaCow(base = MetaCow):
-    """ Create New and Copies from existing classes """
-    return classobj('MetaCowCopy', (base,), {})
-
-
 class DataSmart:
-    def __init__(self, special = createMetaCow(), seen = createMetaCow() ):
+    def __init__(self, special = COWDictBase.copy(), seen = COWDictBase.copy() ):
         self.dict = {}
 
         # cookie monster tribute
         self._special_values = special
         self._seen_overrides = seen
 
+        self.expand_cache = {}
+
     def expand(self,s, varname):
         def var_sub(match):
             key = match.group()[2:-1]
@@ -92,22 +75,30 @@ class DataSmart:
         if type(s) is not types.StringType: # sanity check
             return s
 
-        while s.find('$') != -1:
+        if varname and varname in self.expand_cache:
+            return self.expand_cache[varname]
+
+        while s.find('${') != -1:
             olds = s
             try:
                 s = __expand_var_regexp__.sub(var_sub, s)
                 s = __expand_python_regexp__.sub(python_sub, s)
                 if s == olds: break
                 if type(s) is not types.StringType: # sanity check
-                    error('expansion of %s returned non-string %s' % (olds, s))
+                    bb.msg.error(bb.msg.domain.Data, 'expansion of %s returned non-string %s' % (olds, s))
             except KeyboardInterrupt:
                 raise
             except:
-                note("%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
+                bb.msg.note(1, bb.msg.domain.Data, "%s:%s while evaluating:\n%s" % (sys.exc_info()[0], sys.exc_info()[1], s))
                 raise
+
+        if varname:
+            self.expand_cache[varname] = s
+
         return s
 
     def initVar(self, var):
+        self.expand_cache = {}
         if not var in self.dict:
             self.dict[var] = {}
 
@@ -136,6 +127,7 @@ class DataSmart:
             self.initVar(var)
 
     def setVar(self,var,value):
+        self.expand_cache = {}
         match  = __setvar_regexp__.match(var)
         if match and match.group("keyword") in __setvar_keyword__:
             base = match.group('base')
@@ -148,10 +140,10 @@ class DataSmart:
             # todo make sure keyword is not __doc__ or __module__
             # pay the cookie monster
             try:
-                self._special_values.__dict__[keyword].add( base )
+                self._special_values[keyword].add( base )
             except:
-                self._special_values.__dict__[keyword] = Set()
-                self._special_values.__dict__[keyword].add( base )
+                self._special_values[keyword] = Set()
+                self._special_values[keyword].add( base )
 
             return
 
@@ -164,9 +156,9 @@ class DataSmart:
         # more cookies for the cookie monster
         if '_' in var:
             override = var[var.rfind('_')+1:]
-            if not override in self._seen_overrides.__dict__:
-                self._seen_overrides.__dict__[override] = Set()
-            self._seen_overrides.__dict__[override].add( var )
+            if not self._seen_overrides.has_key(override):
+                self._seen_overrides[override] = Set()
+            self._seen_overrides[override].add( var )
 
         # setting var
         self.dict[var]["content"] = value
@@ -179,6 +171,7 @@ class DataSmart:
         return value
 
     def delVar(self,var):
+        self.expand_cache = {}
         self.dict[var] = {}
 
     def setVarFlag(self,var,flag,flagvalue):
@@ -248,7 +241,7 @@ class DataSmart:
         Create a copy of self by setting _data to self
         """
         # we really want this to be a DataSmart...
-        data = DataSmart(createMetaCow(self._seen_overrides), createMetaCow(self._special_values))
+        data = DataSmart(seen=self._seen_overrides.copy(), special=self._special_values.copy())
         data.dict["_data"] = self.dict
 
         return data
@@ -267,18 +260,11 @@ class DataSmart:
         return keytab.keys()
 
     def __getitem__(self,item):
-        start = self.dict
-        while start:
-            if item in start:
-                return start[item]
-            elif "_data" in start:
-                start = start["_data"]
-            else:
-                start = None
-        return None
+        #print "Warning deprecated"
+        return self.getVar(item, False)
 
     def __setitem__(self,var,data):
-        self._makeShadowCopy(var)
-        self.dict[var] = data
+        #print "Warning deprecated"
+        self.setVar(var,data)