Changeset 119


Ignore:
Timestamp:
Jun 20, 2009, 12:07:37 PM (10 years ago)
Author:
marchulsman
Message:

Restructured capability system (work in progress! not everything functional again)

Files:
11 edited

Legend:

Unmodified
Added
Removed
  • container/container.py

    r118 r119  
    1010
    1111
    12 
    13 class Invar(object):
    14     """Container classes have an variant (Container) and an
    15     invariant (Invar) part. This way we can cache similar querys,
    16     which only differ in parameters (e.g. t[0] and t[1]) """
    17 
    18     __slots__ = ['update','cache','vclass']
    19    
    20     def __init__(self):
    21         #invariant attributes are stored in update
    22         self.update = dict()
    23 
    24         #cache links from this container to other containers
    25         self.cache = dict()
    26 
    27         #saves class type of variant object
    28         self.vclass = None
    29        
    30    
    31     def register(self,obj,key=None):
    32         """Find if an invariant part for variant obj has been stored
    33         in cache. If not found, create new one.
    34         The invar object is stored as the _invar field of obj. Values
    35         stored in the 'update' dict are added to the __dict__ of obj.
    36         Returns False if old invariant was reused, otherwise True"""
    37 
    38         if(key is None):
    39             key = obj.__class__
    40         else:
    41             key = (obj.__class__,key)
    42        
    43         if(key in self.cache):
    44             obj._invar = self.cache[key]
    45             for k,v in obj._invar.update.iteritems():
    46                 setattr(obj,k,v)
    47             if(not obj._invar.vclass is None):
    48                 obj.__class__ = obj._invar.vclass
    49             return False
    50         else:
    51             r = Invar()
    52             obj._invar = r
    53             self.cache[key] = r
    54             return True
    55            
    56     def save(self,obj):
    57         self.update['_fields'] = obj._fields
    58         self.update['_actidx'] = obj._actidx
    59         self.update['_props'] = obj._props
    60         self.update['_segment_attr'] = obj._segment_attr
    61         if(obj._set_props_class()):
    62             self.vclass = obj.__class__
    63 
    64 
    65 
    66 class Container(base_container.BaseContainer,VisitorFactory(prefixes=("_rowtrans","_coltrans"),flags=NF_ROBJ)):
     12class Container(VisitorFactory(prefixes=("_rowtrans","_coltrans"),bases=(base_container.BaseContainer,),typedict={"__slots__":[]},flags=NF_ROBJ)):
    6713    __array_priority__ = 100
    6814    __array_interface__ = {'shape':tuple(),'typestr':'O','version':3}
    69 
     15    __slots__ = []
    7016    _output_segment = tuple()
     17
    7118    def __init__(self):
    7219        raise RuntimeError,"__init__ should be overloaded"
     
    8734        return t
    8835
    89     def enable(self,cap,**params):
     36    def enable(self,cls,name=None,**params):
    9037        """Registers new property or capability with this dataset. Cap should contains
    9138        the class of the property/capability, other parameters can be added using the
    9239        paramname=value form"""
    9340
    94         return opcon.NewCapCon(self,cap,params)
     41        return opcon.NewCapCon(self,cap,name,params)
    9542
    9643    ######## column / rows ################   
     
    11461            exc_class,exc,traceback = sys.exc_info()
    11562            raise RuntimeError, RuntimeError(e.message), traceback
    116 
    11763    nrow = property(fget=_getNrow)
    11864   
     
    12066    ####### fields #########################
    12167    def _getFields(self):
    122         """Returns container representation of fields numpy array.
    123         Caches result in _fieldscon parameter."""
    124         if(not '_fieldscon' in self.__dict__):
     68        """Returns container representation of fields"""
     69        if(not 'fieldscon' in self.invar.__dict__):
    12570            act_fields = self._activefields
    126 
    12771            data = []
    12872            for fieldattr in itypes_py.Field.__slots__:
    12973                getfieldattr = itypes_py.Field.__dict__[fieldattr].__get__
    13074                data.append(xnumpy.dimarray([getfieldattr(af) for af in act_fields],object,1,1))
    131             self._fieldscon = srccon.PySrcCon(itypes_py._fieldfields,tuple(data),False)
    132         return self._fieldscon
    133    
     75            self.invar.fieldscon = srccon.PySrcCon(itypes_py._fieldfields,tuple(data),False)
     76        return self.invar.fieldscon
    13477    fields=property(fget=_getFields)
    135 
    13678
    13779    def _getActiveFields(self):
     
    15799    ####### property/capabilitys ###########
    158100    def _getProps(self):
    159         """Returns container representation of props numpy array.
    160         Caches result in _propscon parameter."""
    161         if(not '_propscon' in self.__dict__):
    162             data = tuple((self._props[:,i] for i in range(self._props.shape[1])))
    163             self._propscon = srccon.PySrcCon(itypes_py._propfields,data,False)
    164         return self._propscon
    165    
    166     def _setProps(self,value):
    167         """Store prop container as numpy array and caches container
    168         version in _propscon"""
    169         self._props = value.matrix().view(xnumpy.XArray)
    170         self._props.colnames = itypes_py._propfields.name
    171         self._propcon = value
    172    
     101        """Returns container representation of properties."""
     102        if(not 'propscon' in self.invar.__dict__):
     103            act_props = self._activeprops
     104            data = []
     105            for propattr in itypes_py.Prop.__slots__:
     106                getpropattr = itypes_py.Prop.__dict__[propattr].__get__
     107                data.append(xnumpy.dimarray([getpropattr(ap) for ap in act_props],object,1,1))
     108            self.invar.propscon = srccon.PySrcCon(itypes_py._propfields,tuple(data),False)
     109        return self.invar.propscon
    173110    props=property(fget=_getProps)
     111   
    174112    def _getActiveProps(self):
    175         return self._props[self._props.active]
     113        props = self._props
     114        if(props is None):
     115            return []
     116        return [props[i] for i in self._actidx_props]
    176117    _activeprops=property(fget=_getActiveProps)
    177118
     119
     120    def _inheritProps(self,sources,\
     121            activefields_by_source=None,path_node=False,translate_fields=None):
     122       
     123        nprops = []
     124        nactidx = []
     125        if(len(sources) > 1):
     126            double_check = set()
     127        else:
     128            double_check = False
     129        pos = 0
     130        for sourceidx,source in enumerate(sources):
     131            props = source._props
     132            if(props is None):
     133                continue
     134           
     135            if(sourceidx > 1):
     136                realias_dict = dict()
     137            else:
     138                realias_dict = None
     139
     140            if(activefields_by_source is None):
     141                afields = None
     142            elif(activefields_by_source is False):
     143                afields = False
     144            else:
     145                afields = activefields_by_source[sourceidx]
     146           
     147            if(not translate_fields is None):
     148                translate_field = translate_fields[sourceidx]
     149            else:
     150                translate_field = None
     151
     152
     153            for prop in props:
     154                ih_type = prop.inherit_type
     155                #CHECK INHERITANCE
     156                if(not (ih_type == itypes_py.IH_ALWAYS \
     157                or (ih_type == itypes_py.IH_CHECK and prop.type._check_inherit(self,prop,translate_field)) \
     158                or (ih_type == itypes_py.IH_FIELDS and not afields is False) \
     159                or (ih_type == itypes_py.IH_MERGE and (double_check is False or \
     160                    (prop.id not in double_check and not double_check.add(prop.id)))))):
     161                    continue
     162               
     163                #CHECK ACTIVE STATUS
     164                ac_type = prop.activate_type
     165                if(ac_type == itypes_py.AC_ALWAYS \
     166                    or (ac_type == itypes_py.AC_CHECK and prop.type._check_active(self,prop,translate_field))\
     167                    or (ac_type == itypes_py.AC_KEEP and prop in sources[sourceidx]._activeprops)\
     168                    or (ac_type == itypes_py.AC_FIELDS and not afields is False\
     169                        and ((afields is None and prop in sources[sourceidx]._activeprops) or \
     170                            len(fields & prop.essential_fields) == len(prop.essential_fields)))):
     171                    nactidx.append(pos)
     172                    pos += 1
     173
     174                #TRANSLATE PROP and FIELD IDS
     175                if(not translate_field is None or not realias_dict is None):
     176                    prop = prop.copy(realias_dict= realias_dict,translate_field=translate_field)
     177                nprops.append(prop)
     178
     179        #path node code
     180        return (tuple(nprops),nactidx)
     181   
     182    #Set class of this object based on capabilities
     183    def _set_props_class(self):
     184        actprops = self._activeprops
     185        #find active capabilities
     186        newcaps = [p for p in actprops if issubclass(p,proptypes.Capability)]           
     187        if(newcaps):
     188            self.__class__ = capcon.getConCapType(newcaps,self.__class__)
     189            self._invar.cap_class = self.__class__
     190            return True
     191        return False
    178192
    179193    # code to be executed when using square brackets ( [] )
     
    209223        return reduce(opcon.MergeCon,select)
    210224
    211     #Set class of this object based on capabilities
    212     def _set_props_class(self):
    213         if(not self._props is None):
    214             p = self._props
    215             #find active capabilities
    216             newcaps = tuple((c for c in p[p.active == True].type if issubclass(c,capcon.Capability)))
    217             if(newcaps):
    218                 self.__class__ = capcon.getConCapType(newcaps,self.__class__)
    219                 return True
    220         return False
    221225
    222226
     
    224228    def copy(self,modifiable=False):
    225229        """Copies the containers own content into a new container."""
     230        d = srccon.PySrcCon(self._activefields,self._res().data,modifiable=modifiable)
    226231        if(modifiable):
    227             d = srccon.PySrcCon(self._activefields,self._res().data,modifiable=True)
    228             d._COPYONUPDATE = [True] * self.ncol
    229         else:
    230             d = srccon.CopySrcCon(self._activefields, self._res().copy())
     232            d._copyonupdate = [True] * self.ncol
    231233        d._props = self._props
    232234        d._set_props_class()
     
    242244            return other.__radd__(self)
    243245        elif(isinstance(other,opcon.PlusPrefixOpCon)):
    244             return opcon.SetOpCon(self,other.source,"UNION",True)
     246            return opcon.SetOpCon(self,other._source,"UNION",True)
    245247        return opcon.ArithmeticOpCon(self, other, '__add__')
    246248   
     
    252254            return other.__radd__(self)
    253255        elif(isinstance(other,opcon.PlusPrefixOpCon)):
    254             return opcon.SetOpCon(self,other.source,"EXCEPT",False)
     256            return opcon.SetOpCon(self,other._source,"EXCEPT",False)
    255257        return opcon.ArithmeticOpCon(self, other, '__sub__')
    256258   
     
    263265            return other.__rmul__(self)
    264266        elif(isinstance(other,opcon.PlusPrefixOpCon)):
    265             return opcon.JoinOpCon(self,other.source,"INNER JOIN")
     267            return opcon.JoinOpCon(self,other._source,"INNER JOIN")
    266268        return opcon.ArithmeticOpCon(self, other, '__mul__')
    267269   
     
    274276            return other.__rmul__(self)
    275277        elif(isinstance(other,opcon.PlusPrefixOpCon)):
    276             return opcon.MergeCon(self,other.source)
     278            return opcon.MergeCon(self,other._source)
    277279        return opcon.ArithmeticOpCon(self, other, '__mod__')
    278280   
     
    300302            return other.__rand__(self)
    301303        elif(isinstance(other,opcon.PlusPrefixOpCon)):
    302             return opcon.SetOpCon(self,other.source,"INTERSECT",False)
     304            return opcon.SetOpCon(self,other._source,"INTERSECT",False)
    303305        return opcon.ArithmeticOpCon(self, other, '__and__')
    304306   
     
    311313            return other.__ror__(self)
    312314        elif(isinstance(other,opcon.PlusPrefixOpCon)):
    313             return opcon.SetOpCon(self,other.source,"UNION",False)
     315            return opcon.SetOpCon(self,other._source,"UNION",False)
    314316        return opcon.ArithmeticOpCon(self, other, '__or__')
    315317
     
    321323        if(isinstance(other,context.Context)):
    322324            return other.__rxor__(self)
     325        elif(isinstance(other,opcon.PlusPrefixOpCon)):
     326            union = opcon.SetOpCon(self,other._source,"UNION",False)
     327            intersect = opcon.SetOpCon(self,other._source,"INTERSECT",False)
     328            return opcon.SetOpCon(union,intersect,"EXCEPT",False)
    323329        return opcon.ArithmeticOpCon(self, other, '__xor__')
    324330
     
    489495
    490496    def __iter__(self):
    491         if('_reuse_iter' in self.__dict__):
    492             r = self._reuse_iter
    493             del self._reuse_iter
     497        if('reuse_iter' in self.invar.__dict__):
     498            r = self.invar.reuse_iter
     499            del self.invar.reuse_iter
    494500            r._reset()
    495501            return r
     
    501507        the current record container. This way, record containers are
    502508        also valid outside the iteration loop."""
    503         if('_reuse_copyiter' in self.__dict__):
    504             r = self._reuse_iter
    505             del self._reuse_iter
     509        if('reuse_copyiter' in self.invar.__dict__):
     510            r = self.invar.reuse_copyiter
     511            del self.invar.reuse_copyiter
    506512            r._reset()
    507513            return r
     
    538544   
    539545    def _res(self):
    540         if('_result' in self.__dict__):
     546        if(not self._result is None):
    541547            if(not self._result.isvalid()):
    542                 self._query.update(self)
    543                 self._result  = self._query.execute(self._query)
    544         else:
    545             if('_query' not in self._invar.update):
    546                 self._query = engine.default.prepare_query(self)
    547                 self._invar.update['_query'] = self._query
     548                self._select_query.update(self)
     549                self._result  = self._select_query.execute(self._select_query)
     550        else:
     551            if(self._select_query is None):
     552                self._select_query = engine.default.prepare_query(self)
    548553            else:
    549                 self._query = self._invar.update['_query']
    550                 self._query.update(self)
    551             self._result = self._query.execute()
     554                self._select_query.update(self)
     555            self._result = self._select_query.execute()
    552556        return self._result
    553557   
    554 
    555558    def __getattr__(self, name):
    556         # find all fields with name 'name' (d is a list)
    557         d = [i for i in self._actidx if self._fields[i].name == name]
     559        # find all fields with name 'name'
     560        actidx = self._actidx
     561        fields = self._fields
     562        pos = None
     563        if("__" in name):
     564            idx = name.find("__")
     565            clsname = name[:idx]
     566            fieldname = name[(idx + 2):]
     567            prop = [p for p in self._activeprops if p.name == clsname]
     568            if(len(prop) >= 1):
     569                for p in prop:
     570                    if(fieldname in p.fieldnames):
     571                        field = p.fields[p.fieldnames.index(fieldname)]
     572                        pos = self._fields.index(field)
     573                        break;
     574        if(pos is None):       
     575            pos = [i for i in actidx if fields[i].name == name]
     576
     577        if(pos):
     578            return opcon.SelectCon(self, pos) 
     579        else:
     580            proppos = [self._actidx_props[pos] for pos,p in \
     581                        enumerate(self._activeprops) \
     582                            if p.name == name]
     583            if(proppos):
     584                return opcon.SelectProp(self,proppos)
    558585       
    559         if(len(d) == 0 and '_props' in self.__dict__):
    560             k = utility.find(self._props.name == name)
    561             t = numpy.zeros((self.ncol,),dtype=bool)
    562             for i in k:
    563                 if(len(self._props[i].fields) > 0):
    564                     t |= (self._props[i].fields >= 0)
    565             d = utility.find(t)
    566            
    567 
    568         if(len(d) >= 1):
    569             # cache access (memory use should be low as data is not copied
    570             # when referencing a column)
    571             self.__dict__[name] = opcon.SelectCon(self, d) 
    572             return self.__dict__[name]
    573         else:
    574             raise AttributeError("No attribute with name: " + name + " found")
     586        raise AttributeError("No attribute with name: " + name + " found")
     587       
    575588
    576589    def __len__(self):
    577590        return self._res().nrow
    578591
    579     def modify_signal(self):
     592    def _modify_signal(self):
    580593        """Signal that this container has modified to all registerd semaphores."""
    581         if('modify_sems' in self.__dict__):
    582             for sem in self.modify_sems:
     594        if(not self._modify_sems is None):
     595            for sem in self._modify_sems:
    583596                sem.signal()
    584597   
     
    586599    #tab-completion mechanism)
    587600    def _getAttributeNames(self):
    588         return [f.name for f in self._activefields]
     601        res =  [f.name for f in self._activefields] + \
     602               [p.name for p in self._activeprops]
     603           
    589604
    590605    def __repr__(self):  #called by ipython
     
    599614            return "<Con: [%d * %d]>" % (self.nrow,self.ncol)
    600615
    601     def tname(self,name,replace=True):
    602         p = self._props.copy()
    603         if(replace):
    604             p = p[p.type!='tablealias']
    605         p = numpy.append(p,[[name,"tablealias",numpy.arange(len(self._fields),dtype="int32"),None]],axis=0)
    606         return opcon.PropChangeCon(self,p)
    607 
    608616    def fname(self,*d,**kwds):
    609617        """Used to change field names"""
     
    615623        return opcon.ChangeFieldNameCon(self,fnchange)
    616624   
    617     def ftype(self,*d,**kwds):
    618         """Used to change field types"""
    619         if(len(d) > 0):
    620             fnchange = d
    621         else:
    622             fnchange = kwds
    623         return opcon.ReTypeCon(self,fnchange)
    624 
    625     def fdefval(self,oldname,newdefval):
    626         """Used to change field defvals"""
    627         if(len(d) > 0):
    628             fnchange = d
    629         else:
    630             fnchange = kwds
    631         return opcon.ReDefvalCon(self,fnchange)
    632 
    633     def bm(self,name=None):
    634         if(not name is None):
    635             return self.enable(capcon.BookmarkProp,capname=name,con=self)
    636         else:
    637             return self.enable(capcon.BookmarkProp,con=self)
    638     def pre(self,name):
    639         return opcon.PrefixCon(self,name)
    640 
    641625    def up_here(self):
    642626        return opcon.UpCon(self,opcon.BRIGHT)
     
    647631    #Returns active propertys/capabilities of a certain class cls
    648632    #if not found, returns None
    649     def _getProp(self,cls):
    650         if(not self._props is None):
    651             p = self._props
    652             r = p[(p.type == (cls,)) & (p.active==True)]
    653             if(len(r) > 0):
    654                 return r
    655         return None
     633    def _getFirstProperty(self,cls):
     634        for prop in self._activeprops:
     635            if(prop.type is cls):
     636                return prop
     637        raise RuntimeError, "Property for " + str(cls) + " not found."
    656638
    657639    def hasField(self,name):
    658         return (self._activefields.name == name).any()
     640        return len([f for f in self._active_fields if f.name == name]) > 0
    659641   
    660642    #Below are translators for row and col constraints
     
    721703import opcon
    722704import srccon
    723 import queryengine
    724705import user_if
    725706import itypes_py
    726 import capcon
     707import proptypes
    727708import engine
    728709
  • container/itypes_py.py

    r116 r119  
    5151        self.sourceids = sourceids
    5252
    53     def copy(self):
    54         return Field(self.name,self.type,self.defval,self.props,self.sourceids,self.id)
     53    def copy(self,realias_dict=None):
     54        if(not realias_dict is None):
     55            if(not self.id in realias_dict):
     56                res = Field(self.name,self.type,self.defval,self.props,self.sourceids)
     57                realias_dict[self.id] = res.id
     58            else:
     59                res = Field(self.name,self.type,self.defval,self.props,self.sourceids,realias_dict[self.id])
     60               
     61            res.sourceids = self.id
     62        else:
     63            res = Field(self.name,self.type,self.defval,self.props,self.sourceids,self.id)
     64        return res
    5565
    5666    def __cmp__(self,other):
    5767        return self.id.__cmp__(other.id)
    5868
    59     def __str__(self):
     69    def __repr__(self):
    6070        return "<" + self.name + ">"
    6171
     
    7181
    7282
    73 _fieldfields = [Field('id',createType("tuple(int32)[]"),(0,)),\
     83_fieldfields = [Field('id',createType("int64"),(0,)),\
    7484                Field('name',createType("str")),\
    7585                Field('type',createType(object),createType(object)),\
     
    8090
    8191
    82 _tmp = numpy.array([('name',   0,  createType(str),          NotNull), \
    83                             ('id',  0,  createType("int32"),      0), \
    84                             ('props',  0,  createType("uint32"),      0), \
    85                             ('type',   0,  createType(object),        createType(object)), \
    86                             ('defval', 0,  createType(object),        None)],dtype="object").view(xnumpy.XArray)
    87 _fieldfields_colnames = _tmp[:,0].copy() #copy to prevent recursion
    88 
    89 
    9092########## PROPERTIES ##################
    9193
    9294class Prop(object):
    93     __slots__ = ["id","name","type","fields","props","active","value"]
    94     field_ids = utility.seqgen(1).next
    95 
    96     def __init__(self,name,type=None,fields=None,props=0,active=True,value=None,id=None):
     95    __slots__ = ["id","name","type","fieldnames","fields",\
     96                "essential_fields","active_type","inherit_type","value"]
     97    prop_ids = utility.seqgen(1).next
     98
     99    def __init__(self,name,type=None, fieldnames=None, fields=None,\
     100                essential_fields=None, active_type=0, inherit_type=True, \
     101                value=None, id=None):
     102       
    97103        if(id is None):
    98             self.id = self.field_ids()
     104            self.id = self.prop_ids()
    99105        else:
    100106            self.id = id
     107       
    101108        self.name = name
    102109        self.type = type
     110        self.fieldnames = fieldnames
    103111        self.fields = fields
    104         self.active = active
    105         self.props = props
     112        self.essential_fields = essential_fields
     113        self.active_type = active_type
     114        self.inherit_type = inherit_type
    106115        self.value = value
    107116
    108     def copy(self):
    109         return Prop(self.name,self.type,self.fields,self.props,self.active,self.value,self.id)
     117    def copy(self,realias_dict=None,translate_field=None):
     118        if(not realias_dict is None):
     119            if(not self.id in realias_dict):
     120                res = Prop(self.name,self.type,self.fieldnames,self.fields,\
     121                        self.essential_fields, self.active_type,self.inherit_type,\
     122                        self.value)
     123                realias_dict[self.id] = res.id
     124            else:
     125                res = Prop(self.name,self.type,self.fieldnames,self.fields,\
     126                        self.essential_fields, self.active_type,self.inherit_type,\
     127                        self.value,realias_dict[self.id])
     128        else:
     129            res = Prop(self.name,self.type,self.fieldnames,self.fields,\
     130                    self.essential_fields, self.active_type,self.inherit_type,\
     131                    self.value,self.id)
     132        if(not translate_field is None):
     133             res.fields = [translate_field[field] for field in self.fields]
     134             res.essential_fields = set([translate_field[field] for field in self.essential_fields])
     135           
     136        return res
    110137
    111138    def __cmp__(self,other):
    112139        return self.id.__cmp__(other.id)
    113140
    114     def __str__(self):
     141    def __repr__(self):
    115142        return "<" + self.name + ">"
    116143
    117144
    118 def realiasFields(fields):
    119     result_ids = set()
    120     for field in fields:
    121         new_id = Field.field_ids()
    122         field.sourceids = field.id
    123         field.id = new_id
    124         result_ids.add(new_id)
    125     return result_ids
    126 
    127 
    128145#is the property inherited?
    129 IH_NONE = 1 << 0
    130 IH_FIELDALL = 1 << 2
    131 IH_FIELDANY = 1 << 3
    132 IH_CHECK = 1 << 4
    133 IH_ALWAYS = 1 << 5
    134 
     146IH_NOT = 1
     147IH_FIELDS = 2
     148IH_CHECK = 3
     149IH_ALWAYS = 4
     150IH_MERGE = 5
    135151
    136152#when is the property/capability active (default: always)?
    137 AC_FIELDANY = 1 << 6
    138 AC_FIELDALL = 1 << 7
    139 AC_CHECK = 1 << 8
    140 AC_KEEP = 1 << 9
    141 #flags
    142 FL_SETOP = 1 << 10    #enable inheritance over set operations
    143 
    144 _propfields = numpy.array([('name',     0, 0, createType(str),           ""),\
    145                            ('id',       0, 0, createType(object),        None),\
    146                            ('type',     0, 0, createType(object),        None),\
    147                            ('fields',   0, 0, createType("numpy(int32)"),numpy.empty((0,),dtype="int32")),\
    148                            ('nfields',  0, 0, createType("object"),      None),\
    149                            ('value',    0, 0, createType("object"),      None),\
    150                            ('active',   0, 0, createType("bool"),        False),\
    151                            ('props',    0, 0, createType("uint32"),      IH_NONE)],dtype=object).view(xnumpy.XArray)
    152 _propfields_names = _propfields[:,0]
    153 _propfields.colnames = _fieldfields_colnames
    154 
    155 
    156 
    157 
     153AC_FIELDS = 1
     154AC_CHECK = 2
     155AC_KEEP = 3
     156AC_ALWAYS = 4
     157
     158_propfields = [Field('id',createType("int64"),(0,)),\
     159                Field('name',createType("str")),\
     160                Field('type',createType(object),createType(object)),\
     161                Field('fieldnames',createType("tuple(str)[]"),tuple()),\
     162                Field('fields',createType("tuple(object)[]"),tuple()),\
     163                Field('essential_fields',createType("object"),set()),\
     164                Field('active_type',createType("int64"),0),\
     165                Field('inherit_type',createType("int64"),0),\
     166                Field('value',createType("object"),None)]
     167
     168######## OUTPUT SEGMENTS #####################
    158169
    159170class FLEX(int):
     
    201212        return "PASSTHROUGH(" + int.__str__(self) + ")"
    202213
    203 
    204 idgen = utility.seqgen(1000).next
    205 def createProps(pname,ptype,pfields=None,pvalue=None,pihtype=None):
    206     rows = len(ptype)
    207     if(pfields is None):
    208         pfields = [_propfields[3].defval] * rows
    209     if(pvalue is None):
    210         pvalue = [_propfields[5].defval] * rows
    211     if(pihtype is None):
    212         pihtype = [_propfields[7].defval] * rows
    213     pidgen = [idgen() for i in range(rows)]
    214 
    215     nfields = []
    216     for p in pfields:
    217         nfields.append(sum(p != 0))
    218     active = [True] * rows
    219        
    220     p = xnumpy.dimarray(transpose((pname,pidgen,ptype,pfields,nfields,pvalue,active,pihtype)),object,2,2)
    221     p.colnames = _propfields_names
    222     return p
    223214
    224215def binop_cast(left,right,operator):
  • container/opcon.py

    r116 r119  
    1111
    1212
    13 class OpCon(container.Container):
    14     #inherits props if no field is inherited from sources
    15     def _noFieldProps(self,*sources):
    16         pr = []
    17         for source in sources:
    18             if(not source._props is None):
    19                 p = source._props
    20                 ih = numpy.cast[bool](p.props & itypes_py.IH_ALWAYS)
    21                 check = numpy.cast[bool](p.props & itypes_py.IH_CHECK)
    22                 for pidx in utility.find(check):
    23                     ih[pidx] = p[pidx].type.check(self,p[pidx])
    24 
    25                 if(ih.any()):
    26                     p = p.copy()[ih]
    27                     p.fields = map(numpy.abs,p.fields)
    28                     p.fields = -1 * p.fields
    29                     pr.append(p)
    30         self._finishProps(*pr)
    31    
    32     #inherits props if active field have changed
    33     def _actFieldChgProps(self,source):
    34         if(not source._props is None):
    35             props = source._props.copy()
    36 
    37             #make all active fields positive and all inactive negative
    38             v = numpy.empty((len(self._fields),),dtype=int)
    39             v[:] = -1
    40             v[self._actidx] = 1
    41             props.fields = map(numpy.abs,props.fields)
    42             for i,f in enumerate(props.fields):
    43                 if(len(f) > 0):
    44                     props.fields[i] = f * v
    45             self._finishProps(props)
    46    
    47    
    48 
    49     #combines two sources, makes a path node property
    50     def _pathNodeProps(self,sources):
    51         pr = []
    52         nl = len(self._fields)
    53         nf = numpy.zeros((nl,),dtype=int)
    54         pos = 0
    55 
    56         assert (len(sources) == 2), "Path Node should have two sources"
    57 
    58        
    59         #filter props arrays on inheritance
    60         path_ids = [-1,-1]
    61         for j,source in enumerate(sources):
    62             if(not source._props is None):
    63                 p = source._props
    64                 #determine which properties should be inherited
    65                 ih = numpy.cast[bool](p.props & (itypes_py.IH_FIELDALL | itypes_py.IH_FIELDANY | itypes_py.IH_ALWAYS))
    66                 check = numpy.cast[bool](p.props & itypes_py.IH_CHECK)
    67                 for pidx in utility.find(check):
    68                     ih[pidx] = p[pidx].type.check(self,p[pidx])
    69 
    70                 #if any property is inherited
    71                 if(ih.any()):
    72                     p = p.copy()[ih]
    73                     #adapt fields
    74                     for prow in p:
    75                         pf = nf.copy()
    76                         pf[pos:(pos + len(prow.fields))] = prow.fields
    77                         prow.fields = pf
    78 
    79                         #get active path id's, reset active flag
    80                         if(prow.type is capcon.PathProp):
    81                             if(prow.active):
    82                                 path_ids[j] = prow.id
    83                                 prow.active = False
    84 
    85                     pr.append(p)
    86             pos = pos + source.ncol
    87        
    88         #create param array for new path node, linking to
    89         #earlier node ids
    90         params = dict()
    91         params['left'] = sources[0]
    92         params['right'] = sources[1]
    93         params['lnode'] = path_ids[0]
    94         params['rnode'] = path_ids[1]
    95 
    96         #create path node
    97         pr.append(capcon.PathProp._create_props(self,"PathProp",params))
    98 
    99         #combine props arrays, determine active props
    100         self._finishProps(*pr)
    101        
    102 
    103     def _finishProps(self,*psources):
    104        
    105         if(len(psources) > 1):
    106             props = numpy.vstack(psources)
    107             props.colnames = itypes_py._propfields_names
    108 
    109             #check for duplicate ids, while keeping ordering
    110             ids = set()
    111             remove = numpy.zeros((len(props),),dtype=bool)
    112             for i,id in enumerate(props.id):
    113                 if(id in ids):
    114                     remove[i] = True
    115                 else:
    116                     ids.add(id)
    117             if(remove.any()):
    118                 props = props[~remove]
    119         elif(len(psources) == 1 and not psources[0] is None):
    120             props = psources[0]
    121             print props
    122             if(props.ndim == 1):
    123                 props.shape = (1,props.shape[0])
    124         else:
    125             props = None
    126        
    127        
    128         if(not props is None):
    129             #check if props should be active
    130             for i,prop in enumerate(props):
    131                 if(not (prop.props & itypes_py.AC_KEEP)):
    132                     props[i].active = False
    133                     if(prop.props & itypes_py.AC_FIELDANY):
    134                         props[i].active = (sum(prop.fields > 0) > 0)
    135                     elif(prop.props & itypes_py.AC_FIELDALL):
    136                         props[i].active = (sum(prop.fields > 0) == prop.nfields)
    137                     elif(prop.props & itypes_py.AC_CHECK):
    138                         props[i].active = (prop.type.active_check(self,prop))
    139 
    140         self._props = props
    141 
    142          
    143 
    144 
    145 class MultiOpCon(OpCon):
     13
     14
     15
     16class MultiOpCon(container.Container):
     17    __slots__ = []
    14618    """Binary operator container."""
    14719    def __init__(self, *source):
    14820        self._source = source
    14921   
     22    def _mergeProps(self,leftprops,rightprops,create_path_node=True,left_fields=None,right_fields=None):
     23        #path node code
     24        return leftprops + rightprops
     25   
    15026class BroadcastOpCon(MultiOpCon):
     27    __slots__ = []
    15128    _output_segment = (REDUCE(0,1),)
    15229    def __init__(self, sleft, sright, operator):
     
    16138                self._fields = itypes_py.binop_type(sleft._activefields,rtype,operator)
    16239                self._actidx = range(len(self._fields))
    163                 self._noFieldProps(sleft)
     40                self._props,self._actidx_props = self._inheritProps((sleft,))
    16441            else:
    16542                self._fields = itypes_py.binop_type(sleft._activefields,sright._activefields,operator)
    16643                self._actidx = range(len(self._fields))
    167                 self._noFieldProps(sleft,sright)
    168             self._invar.save(self)
    169 
    170         MultiOpCon.__init__(self, sleft, sright,operator)
     44                self._props,self._actidx_props = self._inheritProps((sleft,sright))
     45            self._set_props_class()
     46
     47        self._source = (sleft, sright,operator)
    17148
    17249class ArithmeticOpCon(BroadcastOpCon):
    173     pass
     50    __slots__ = []
    17451
    17552class ComparisonOpCon(ArithmeticOpCon):
    176     pass
     53    __slots__ = []
    17754
    17855
    17956class SetOpCon(MultiOpCon):
     57    __slots__ = []
    18058    _output_segment = (REDUCE(0,1),)
    18159
     
    19270            if(not left._props is None and not right._props is None):
    19371                #search for properties occuring in both operands
    194                 common_props_ids = set(left._props.id) & set(right._props.id)
     72                common_props_ids = set([lprop.id for lprop in left._props] + [rprop.id for rprop in right._props])
    19573               
    19674                for cpid in common_props_ids:
     
    254132                   
    255133            self._finishProps(*nprops)   
    256             self._invar.save(self)
    257134        MultiOpCon.__init__(self,left,right,op,all)
    258135
    259136
    260137class MergeCon(MultiOpCon):
     138    __slots__ = []
    261139    _output_segment = (FLEX(0),FLEX(1))
    262140    def __init__(self,left,right):
     
    271149         
    272150            self._pathNodeProps((left,right))
    273             self._invar.save(self)
    274151        MultiOpCon.__init__(self,left,right)
    275152
    276153class JoinOpCon(MultiOpCon):
     154    __slots__ = []
    277155    _output_segment = (FLEX_LEASTONE(0), FLEX_LEASTONE(1))
    278156    def __init__(self,left,right,operator="CROSS JOIN"):
     
    302180           
    303181            self._pathNodeProps((left,right))
    304             self._invar.save(self)
    305182        MultiOpCon.__init__(self,left,right,operator)
    306183
    307184
    308185class EquiJoinOpCon(JoinOpCon):
    309     def __init__(self,left,right,operator,fleft,fright):
    310         JoinOpCon.__init__(self,left,right,operator)
    311         self._source = (left,right,operator,fleft,fright)
     186    __slots__ = []
    312187
    313188BRIGHT = False
    314189BLEFT = True
    315190class UpCon(MultiOpCon):
     191    __slots__ = []
    316192    _output_segment = (FLEX(0),)
    317193    def __init__(self,source,left):
     
    365241
    366242class WhereCon(MultiOpCon):
     243    __slots__ = []
    367244    _output_segment = (FLEX(0),INFIX(1))
    368245   
    369246    def __init__(self, source, row_constraint):
    370         self._source = (source,row_constraint)
    371         self._fields = source._fields
    372         self._actidx = source._actidx
    373 
    374247        #invariant key is based on row_constraint
    375248        if(isinstance(row_constraint,container.Container)):
     
    392265            if(not source._props is None):
    393266                self._props = source._props.copy() #no need to modify for now
    394             #store results
    395             self._invar.save(self)
     267       
     268        self._source = (source,row_constraint)
    396269
    397270#used internally to specify conditions specific for the
    398271#preceding join
    399272class JoinWhereCon(WhereCon):
    400     pass
    401 
     273    __slots__ = []
    402274
    403275class SelectCon(MultiOpCon):
     276    __slots__ = []
    404277    _output_segment = (FLEX(0),)
    405278
     
    420293           #apply col_constraint to currently active fields
    421294           self._actidx = list(xnumpy.dimarray(source._actidx,int).dim1(col_constraint))
    422            self._actFieldChgProps(source)
    423 
    424            #store results
    425            self._invar.save(self)
    426        
     295
     296           #inherit props
     297           self._props,self._actidx_props = self._inheritProps((source,),(set(self._activefields),))
     298           self._set_props_class()
     299
    427300        self._source = (source,col_constraint)
    428301       
     
    430303
    431304class ConIterator(WhereCon):
     305    __slots__ = []
     306       
    432307    def __init__(self, container):
    433308        self._orig_container = container
     
    441316    def next(self):
    442317        self.source[1] +=1  #row constraint
    443         self.modify_signal()
     318        self._modify_signal()
    444319        if(self.source[1] < self.maxlength):
    445320            return self
     
    458333
    459334class CopyConIterator(ConIterator):
     335    __slots__ = []
    460336    def next(self):
    461337        return ConIterator.next(self).copy()
     
    464340        self._orig_container._reuse_copyiter = self
    465341
    466 class UnaryOpCon(OpCon):
     342class UnaryOpCon(container.Container):
     343    __slots__ = []
    467344    def __init__(self, source):
    468345        self._source = source
     
    470347   
    471348class PlusPrefixOpCon(UnaryOpCon):
     349    __slots__ = []
    472350    _output_segment = (FLEX(0),)
    473351    def __init__(self, source):
    474        self._fields = source._fields
    475        self._actidx = source._actidx
    476        self._props = source._props
     352       if(source._invar.register(self)):
     353           self._fields = source._fields
     354           self._actidx = source._actidx
     355           self._props = source._props
    477356       self._source = source
    478        source._invar.register(self)
    479357
    480358class ChangeFieldNameCon(UnaryOpCon):
     359    __slots__ = []
    481360    _output_segment = (FLEX(0),)
    482361    def __init__(self, source,namedict):
     
    496375
    497376class AnyCon(UnaryOpCon):
     377    __slots__ = []
    498378    def __init__(self,source):
    499379        if(source._invar.register(self)):
     
    505385
    506386class AllCon(UnaryOpCon):
     387    __slots__ = []
    507388    def __init__(self,source):
    508389        if(source._invar.register(self)):
     
    556437
    557438class RealizeOpCon(UnaryOpCon):
     439    __slots__ = []
    558440    def __init__(self,source):
    559441        self.fields = source.fields
     
    562444            self.deriveMultipleProps((source,),(None,),(0,),source.ncol,False)
    563445
    564 
    565 
    566446class NewCapCon(UnaryOpCon):
     447    __slots__ = []
    567448    _output_segment = (FLEX(0),)
    568     def __init__(self,source,cap,params):
     449    def __init__(self,source,cap,name,params):
    569450       rsource = source
    570        self._fields = source._fields
    571        self._actidx = source._actidx
    572        self._props = rsource._props
    573        
    574451       if(issubclass(source.__class__,NewCapCon)):
    575452            source = source.source
    576        self._source = source
    577453       capkey = tuple((k,v) for k,v in params.iteritems())
    578454       if(rsource._invar.register(self,capkey)):
    579            cap._register(self,params)
    580            self._invar.vclass = self.__class__
     455           self._fields = source._fields
     456           self._actidx = source._actidx
     457           
     458           self._actidx_props = list(self._actidx_props)
     459           self._props = list(rsource._props)
     460           self._actidx_props.append(len(self._props))
     461           #FIXME: inactive props can be inactive
     462           (prop,active) = cls._create(self,name,params)
     463           if(active):
     464               self._actidx_props.insert(0,len(self._props))
     465           self._props.append(prop)
     466           self._set_props_class()
     467
     468       self._source = source
    581469       
    582470
  • container/qg_translate.py

    r117 r119  
    9191    def __init__(self,params,source_node):
    9292        super(SQLCompatibilityCheck,self).__init__(params,source_node)
    93         self.conn = source_node.props[source_node.props.name == 'conn'].value.item()
     93        self.conn = source_node.invar_dict['conn']
    9494
    9595    def __eq__(self,other):
     
    127127        context = None
    128128        for node in parwalk:
    129             if(issubclass(node.obj,srccon.SrcCon)):
     129            if(hasattr(node.obj,"_select_compat")):
    130130                compat_map[node]= node.obj._select_compat(query.params,node)
    131131                context_map[node] = None
     
    635635
    636636    def funcDBSrcCon(self,node,sources):
    637         tablename = node.props[node.props.name == 'tablename'].value.item()
    638         conn = node.props[node.props.name == 'conn'].value.item()
     637        tablename = node.invar_dict['tablename']
     638        conn = node.invar_dict['conn']
    639639
    640640        fieldnames = [f.fieldname for f in node.fields]
     
    718718        else:
    719719            tablename = "((" + str(l) + ") " + op + " (" + str(r) + "))"
    720         return SQLQuery.create(tablename,[f.name for f in node.fields], [f.type for f in node.fields],l.conn,True)
     720        return SQLQuery.create(tablename,[f.name + str(pos) for pos,f in enumerate(node.fields)], [f.type for f in node.fields],l.conn,True)
    721721       
    722722
  • container/qgraph_py.py

    r113 r119  
    1414#uses class methods to execute visit operations in the various
    1515#passes
    16 class ExtendCon(opcon.OpCon):
     16class ExtendCon(opcon.MultiOpCon):
    1717    pass
    1818
    1919#special root class, used as root for query graph
    20 class Root(opcon.OpCon):
     20class Root(opcon.UnaryOpCon):
    2121    _output_segment = [itypes_py.OUTFIX]
    2222
     
    3838   def __init__(self,root,engine):
    3939       super(Query,self).__init__(root)
    40        
     40
    4141       self.sem = self.obtain_semaphore()
    4242       #clear modifiables (we do not want to hold a reference)
     
    5959
    6060   def __del__(self):
     61       print "DELETE"
    6162       x = CycleBreakVisitor(self.params)
    6263       x.visit(self.qg)
     
    8182               sem = ModificationSemaphore(len(self.modifiables))
    8283               for con in self.modifiables:
    83                    con.modify_sems.add(sem)
     84                   con._modify_sems.add(sem)
    8485               return sem
    8586       return None   
     
    9495      return Node(target)
    9596   
    96    def visitSrcCon(self,target,root):
     97   def visitPySrcCon(self,target,root):
    9798      return Node(target,[self.visit(target._res(),root)])
    9899   
     
    122123      pass
    123124   
    124    def paramSrcCon(self,target,root):
     125   def paramPySrcCon(self,target,root):
    125126      self.param(target._res(),root)
    126127   
    127    def paramDBSrcCon(self,target,root):
    128       pass
    129 
    130128   def paramUnaryOpCon(self,target,root):
    131129      self.param(target._source,root)
  • container/srccon.py

    r108 r119  
    1 from base_container import QueryResult,ModificationSemaphore
     1from base_container import QueryResult,ModificationSemaphore,Invar
    22import container
    33import opcon
     
    1414import qg_translate
    1515
    16 class SrcCon(container.Container):
    17     """SrcCon: main class for source containers"""
    18 
     16class DBSrcCon(container.Container):
     17    """DBSrcCon: main class for database source containers"""
     18    __slots__ = []
     19    _output_segment=[itypes_py.OUTFIX]
     20    _select_compat = qg_translate.SQLCompatibilityCheck
     21   
     22
     23    def __init__(self,tablename,fields,conn):
     24        self._invar = Invar()
     25        self._fields = fields
     26        self._actidx = range(len(fields))
     27        self._invar.tablename = tablename
     28        self._invar.conn = conn
     29        self._segment_attr = ([field.id for field in self._fields],)
     30
     31class PySrcCon(container.Container):
     32    """PySrcCon: class to store python data"""
     33    __slots__ = ["_add_buffer","_modify_check","_copyonupdate"]
    1934    _output_segment=[itypes_py.OUTFIX]
    2035    _select_compat = qg_translate.PyCompatibilityCheck
    2136
    22 
    23 
    24     def fixate(self):
    25         pass
    26 
    27 class DBSrcCon(SrcCon):
    28     """DBSrcCon: main class for database source containers"""
    29     _select_compat = qg_translate.SQLCompatibilityCheck
    30    
    31 
    32     def __init__(self,tablename,fields,conn):
     37    def __init__(self, fields,data=None,modifiable=False):
     38        self._invar = Invar()
    3339        self._fields = fields
    3440        self._actidx = range(len(fields))
    35         self._props = itypes_py.createProps(pname=  ("tablename","conn"),
    36                                   ptype=  (capcon.Property  ,capcon.Property),
    37                                   pfields = None,
    38                                   pvalue = (tablename,conn)
    39                                   )
    40         self._segment_attr = ([field.id for field in self._fields],)
    41         self._invar = container.Invar()
    42 
    43 class VarSrcCon(SrcCon):
    44     """VarSrcCon: container of which the content can be varied by
    45     replacing it with different (field compatible) containers. """
    46    
    47     def __init__(self,capability):
    48         self._invar = container.Invar()
    49         self._fields = capability._varfields
    50         capability._register(self)
    51 
    52 
    53 #This class is not directly instantiated
    54 #but is used to replace the PySrcCon class on fixation
    55 
    56 class NoModPySrcCon(SrcCon):
    57     """PySrcCon is modifiable. This class is a version that is not
    58     modifiable. It cannot be instantiated directly, but is used by PySrcCon
    59     to replace its own class."""
    60     def append(self, *seq, **fields):
    61         raise AssertionError, "Modification of this container has been disabled"
    62    
    63     def extend(self,*seq,**fields):
    64         raise AssertionError, "Modification of this container has been disabled"
    65    
    66 
    67 class PySrcCon(SrcCon):
    68     """PySrcCon: class to store python data"""
    69 
    70     def __init__(self, fields,data=None,modifiable=False):
    71         self._fields = fields
    72         self._actidx = range(len(fields))
    73         self._invar = container.Invar()
    74         self._segment_attr = ([field.id for field in self._fields],)
     41        self._segment_attr = ([field.id for field in fields],)
    7542
    7643        if(not data is None):
     
    8148                data = tuple((xnumpy.dimarray(tuple(),itypes_py.to_numpy(type)) for type in fields.type))
    8249                self._result = QueryResult(data,0,0)
    83             self._res = self._result
    84             self._res.cacheable = True
     50            self._result.cacheable = True
    8551            self.__class__ = NoModPySrcCon
    86             self._set_props_class()
    8752        else:
    88             self.modify_check = ModificationSemaphore(1)
    8953            self._add_buffer = []
    90             self.modify_sems = set([self.modify_check])
     54            self._modify_check = ModificationSemaphore(1)
     55            self._modify_sems = set([self._modify_check])
    9156            if(data):
    92                 self._result.modify_check = self.modify_check
     57                self._result.modify_check = self._modify_check
    9358
    9459
     
    9661    def fixate(self):
    9762        self.flush()
    98         if('modify_sems' in self.__dict__):
    99             for sem in self.modify_sems:
     63        if(not self._modify_sems is None):
     64            for sem in self._modify_sems:
    10065               sem.nrmod -= 1
    101             del self.modify_sems
    102        
    103         self._res = self._result
    104         self._res.cacheable = True
     66            del self._modify_sems
     67       
     68        self._result.cacheable = True
    10569        self.__class__ = NoModPySrcCon
    10670        self._set_props_class()
     
    10872
    10973    def append(self, *seq, **fields):
    110         self.modify_signal()
     74        self._modify_signal()
    11175        if(not seq):
    11276            seq = []
     
    12589
    12690    def extend(self, seq):
    127         self.modify_signal()
     91        self._modify_signal()
    12892        self._add_buffer.extend(seq)
    12993
     
    152116
    153117        d.data = tuple(data)
    154         self.modify_signal()
     118        self._modify_signal()
    155119 
    156120
     
    202166        data = list(d.data)
    203167
    204         if('_COPYONUPDATE' in self.__dict__):
     168        if(not self._copyonupdate is None):
    205169            for c in ci:
    206                 if(self._COPYONUPDATE[c]):
     170                if(self._copyonupdate[c]):
    207171                    data[c] = data[c].copy()
    208                     self._COPYONUPDATE[c] = False
     172                    self._copyonupdate[c] = False
    209173       
    210174
     
    231195       
    232196        d.data = tuple(data)
    233         self.modify_signal()
     197        self._modify_signal()
    234198
    235199
    236200    def _res(self):
    237201        #a result object does not exist yet
    238         if(not '_result' in self.__dict__):
     202        if(self._result is None):
    239203            fieldtypes = utility.ensure_seq(itypes_py.to_numpy([f.type for f in self._activefields]))
    240204            nrow = len(self._add_buffer)
     
    244208            r = QueryResult(data, nrow, ncol)
    245209            self._add_buffer = []
    246             r.modify_check = self.modify_check
     210            r.modify_check = self._modify_check
    247211            self._result = r
    248212
     
    258222            self._add_buffer = []
    259223            self._result = r
    260             r.modify_check = self.modify_check
     224            r.modify_check = self._modify_check
    261225        return self._result
    262            
    263 
    264 class CopySrcCon(SrcCon):
    265     def __init__(self, fields, result):
    266         self._fields = fields
    267         self._actidx = range(len(fields))
    268         self._invar = container.Invar()
    269         self._res = result
    270         self._res.cacheable = True
    271         self._segment_attr = ([field.id for field in self._fields],)
    272 
    273 
     226#This class is not directly instantiated
     227#but is used to replace the PySrcCon class on fixation
     228class NoModPySrcCon(PySrcCon):
     229    __slots__ = []
     230
     231    """PySrcCon is modifiable. This class is a version that is not
     232    modifiable. It cannot be instantiated directly, but is used by PySrcCon
     233    to replace its own class."""
     234    def append(self, *seq, **fields):
     235        raise AssertionError, "Modification of this container has been disabled"
     236   
     237    def extend(self,*seq,**fields):
     238        raise AssertionError, "Modification of this container has been disabled"
     239   
     240    def _res(self):
     241        return self._result
     242
     243
  • src/base_container.c

    r105 r119  
    488488
    489489/*{{{*/
    490 static void BaseContainer_dealloc(BaseContainer* self)
     490static void Invar_dealloc(Invar* self)
    491491{
    492492    Py_XDECREF(self->props);
     493    Py_XDECREF(self->actidx_props);
    493494    Py_XDECREF(self->fields);
    494495    Py_XDECREF(self->actidx);
    495     Py_XDECREF(self->invar);
     496    Py_XDECREF(self->segment_attr);
    496497    Py_XDECREF(self->modify_sems);
    497     Py_XDECREF(self->segment_attr);
     498    Py_XDECREF(self->select_query);
     499    Py_XDECREF(self->cache);
     500    Py_XDECREF(self->cap_class);
     501    Py_XDECREF(self->local);
     502   
    498503    self->ob_type->tp_free((PyObject*)self);
    499504}
    500505
    501 static PyObject *
    502 BaseContainer_getProps(BaseContainer *self, void *closure)
     506static PyObject * Invar_getProps(Invar *self, void *closure)/*{{{*/
    503507{
    504508    if(self->props == NULL)
     
    509513    return self->props;
    510514}
    511 static int
    512 BaseContainer_setProps(BaseContainer *self, PyObject *value, void *closure)
    513 {
    514     PyObject *tmp;
    515     if(!(value == Py_None || (PyArray_Check(value) && ((PyArrayObject*)value)->nd == 2)))
    516     {
    517         PyErr_SetString(PyExc_TypeError, "Props objects should be a two dimensional numpy object");
     515static int Invar_setProps(Invar *self, PyObject *value, void *closure)
     516{
     517    PyObject *tmp;
     518    if(value == NULL)
     519    {
     520        Py_XDECREF(self->props);
     521        self->props = NULL;
     522        return 0;
     523    }
     524
     525    if(!(value == Py_None || (PyTuple_Check(value))))
     526    {
     527        PyErr_SetString(PyExc_TypeError, "Props objects should be a tuple");
    518528        return -1;
    519529    }
     
    523533    Py_XDECREF(tmp);
    524534    return 0;
    525 }
    526 
    527 
    528 static PyObject *
    529 BaseContainer_getFields(BaseContainer *self, void *closure)
     535}/*}}}*/
     536
     537static PyObject * Invar_getActIdxProps(Invar *self, void *closure)/*{{{*/
     538{
     539    if(self->actidx_props == NULL)
     540    {
     541        PyErr_SetString(PyExc_TypeError, "Invar object not properly initialized (no actidx_props).");
     542        return NULL;
     543    }   
     544    Py_INCREF(self->actidx_props);
     545    return self->actidx_props;
     546}
     547static int Invar_setActIdxProps(Invar *self, PyObject *value, void *closure)
     548{
     549    PyObject *tmp;
     550    if(value == NULL)
     551    {
     552        Py_XDECREF(self->actidx_props);
     553        self->actidx_props = NULL;
     554        return 0;
     555    }
     556    if(!PyList_Check(value))
     557    {
     558        PyErr_SetString(PyExc_TypeError, "Active prop index should be a list");
     559        return -1;
     560    }
     561    tmp = self->actidx_props;
     562    Py_INCREF(value);
     563    self->actidx_props = value;
     564    Py_XDECREF(tmp);
     565    return 0;
     566}/*}}}*/
     567
     568static PyObject * Invar_getFields(Invar *self, void *closure)/*{{{*/
    530569{
    531570    if(self->fields == NULL)
    532571    {
    533         PyErr_SetString(PyExc_TypeError, "BaseContainer object not properly initialized (no fields).");
     572        PyErr_SetString(PyExc_TypeError, "Invar object not properly initialized (no fields).");
    534573        return NULL;
    535574    }   
     
    537576    return self->fields;
    538577}
    539 static int
    540 BaseContainer_setFields(BaseContainer *self, PyObject *value, void *closure)
    541 {
     578static int Invar_setFields(Invar *self, PyObject *value, void *closure)
     579{
     580    if(value == NULL)
     581    {
     582        Py_XDECREF(self->fields);
     583        self->fields = NULL;
     584        return 0;
     585    }
     586   
    542587    PyObject *tmp;
    543588    if(!PyList_Check(value))
     
    551596    Py_XDECREF(tmp);
    552597    return 0;
    553 }
    554 
    555 static PyObject *
    556 BaseContainer_getActIdx(BaseContainer *self, void *closure)
     598}/*}}}*/
     599
     600static PyObject * Invar_getActIdx(Invar *self, void *closure)/*{{{*/
    557601{
    558602    if(self->actidx == NULL)
    559603    {
    560         PyErr_SetString(PyExc_TypeError, "BaseContainer object not properly initialized (no actidx).");
     604        PyErr_SetString(PyExc_TypeError, "Invar object not properly initialized (no actidx).");
    561605        return NULL;
    562606    }   
     
    564608    return self->actidx;
    565609}
    566 static int
    567 BaseContainer_setActIdx(BaseContainer *self, PyObject *value, void *closure)
    568 {
    569     PyObject *tmp;
     610static int Invar_setActIdx(Invar *self, PyObject *value, void *closure)
     611{
     612    PyObject *tmp;
     613    if(value == NULL)
     614    {
     615        Py_XDECREF(self->actidx);
     616        self->actidx = NULL;
     617        return 0;
     618    }
    570619    if(!PyList_Check(value))
    571620    {
     
    578627    Py_XDECREF(tmp);
    579628    return 0;
    580 }
    581 
    582 static PyObject *
    583 BaseContainer_getSegmentAttr(BaseContainer *self, void *closure)
     629}/*}}}*/
     630
     631static PyObject * Invar_getSegmentAttr(Invar *self, void *closure)/*{{{*/
    584632{
    585633    if(self->segment_attr == NULL)
     
    590638    return self->segment_attr;
    591639}
    592 static int
    593 BaseContainer_setSegmentAttr(BaseContainer *self, PyObject *value, void *closure)
    594 {
    595     PyObject *tmp;
     640static int Invar_setSegmentAttr(Invar *self, PyObject *value, void *closure)
     641{
     642    PyObject *tmp;
     643    if(value == NULL)
     644    {
     645        Py_XDECREF(self->segment_attr);
     646        self->segment_attr = NULL;
     647        return 0;
     648    }
    596649    if(!(value == Py_None || PyTuple_Check(value)))
    597650    {
     
    604657    Py_XDECREF(tmp);
    605658    return 0;
    606 }
    607 
    608 
    609 
    610 
    611 static PyObject *
    612 BaseContainer_getInvar(BaseContainer *self, void *closure)
    613 {
    614     if(self->invar == NULL)
    615     {
    616         PyErr_SetString(PyExc_TypeError, "BaseContainer object not properly initialized (no invar).");
    617         return NULL;
    618     }   
    619     Py_INCREF(self->invar);
    620     return self->invar;
    621 }
    622 static int
    623 BaseContainer_setInvar(BaseContainer *self, PyObject *value, void *closure)
    624 {
    625     PyObject *tmp;
    626     tmp = self->invar;
    627     Py_INCREF(value);
    628     self->invar = value;
    629     Py_XDECREF(tmp);
    630     return 0;
    631 }
    632 
    633 
    634 static PyObject *
    635 BaseContainer_getModifySems(BaseContainer *self, void *closure)
     659}/*}}}*/
     660
     661static PyObject * Invar_getModifySems(Invar *self, void *closure)/*{{{*/
    636662{
    637663    if(self->modify_sems == NULL)
     
    643669    return self->modify_sems;
    644670}
    645 static int
    646 BaseContainer_setModifySems(BaseContainer *self, PyObject *value, void *closure)
    647 {
    648     PyObject *tmp;
     671static int Invar_setModifySems(Invar *self, PyObject *value, void *closure)
     672{
     673    PyObject *tmp;
     674    if(value == NULL)
     675    {
     676        Py_XDECREF(self->modify_sems);
     677        self->modify_sems = NULL;
     678        return 0;
     679    }
     680
    649681    if(!(PyAnySet_Check(value)))
    650682    {
     
    657689    Py_XDECREF(tmp);
    658690    return 0;
    659 }
     691}/*}}}*/
     692
     693static PyObject * Invar_getSelectQuery(Invar *self, void *closure)/*{{{*/
     694{
     695    if(self->select_query == NULL)
     696    {
     697        Py_RETURN_NONE;
     698    }   
     699    Py_INCREF(self->select_query);
     700    return self->select_query;
     701}
     702static int Invar_setSelectQuery(Invar *self, PyObject *value, void *closure)
     703{
     704    PyObject *tmp;
     705    tmp = self->select_query;
     706    Py_XINCREF(value);
     707    self->select_query = value;
     708    Py_XDECREF(tmp);
     709    return 0;
     710}/*}}}*/
     711
     712static PyObject * Invar_getCache(Invar *self, void *closure)/*{{{*/
     713{
     714    if(self->cache == NULL)
     715    {
     716        self->cache = PyDict_New();
     717    }   
     718    Py_XINCREF(self->cache);
     719    return self->cache;
     720}
     721static int Invar_setCache(Invar *self, PyObject *value, void *closure)
     722{
     723    PyObject *tmp;
     724    if(value == NULL)
     725    {
     726        PyErr_SetString(PyExc_TypeError, "Cache field may not be deleted");
     727        return -1;
     728    }
     729    if(!PyDict_Check(value))
     730    {
     731        PyErr_SetString(PyExc_TypeError, "Cache field should contain dictionary");
     732        return -1;
     733    }
     734    tmp = self->cache;
     735    Py_INCREF(value);
     736    self->cache = value;
     737    Py_XDECREF(tmp);
     738    return 0;
     739}/*}}}*/
     740
     741static PyObject * Invar_getLocal(Invar *self, void *closure)/*{{{*/
     742{
     743    if(self->local == NULL)
     744    {
     745        self->local = PyDict_New();
     746    }   
     747    Py_XINCREF(self->local);
     748    return self->local;
     749}
     750static int Invar_setLocal(Invar *self, PyObject *value, void *closure)
     751{
     752    PyObject *tmp;
     753    if(value == NULL)
     754    {
     755        PyErr_SetString(PyExc_TypeError, "Local field may not be deleted");
     756        return -1;
     757    }
     758    if(!PyDict_Check(value))
     759    {
     760        PyErr_SetString(PyExc_TypeError, "Local field should contain dictionary");
     761        return -1;
     762    }
     763    tmp = self->local;
     764    Py_INCREF(value);
     765    self->local = value;
     766    Py_XDECREF(tmp);
     767    return 0;
     768}/*}}}*/
     769
     770static PyObject * Invar_getCapClass(Invar *self, void *closure)/*{{{*/
     771{
     772    if(self->cap_class == NULL)
     773    {
     774        Py_RETURN_NONE;
     775    }   
     776    Py_INCREF(self->cap_class);
     777    return self->cap_class;
     778}
     779
     780static int Invar_setCapClass(Invar *self, PyObject *value, void *closure)
     781{
     782    PyObject *tmp;
     783    if(value == NULL)
     784    {
     785        Py_XDECREF(self->cap_class);
     786        self->cap_class = NULL;
     787        return 0;
     788    }
     789    if(!PyType_Check(value))
     790    {
     791        PyErr_SetString(PyExc_TypeError, "Capability class field should be a type");
     792        return -1;
     793    }
     794    tmp = self->cap_class;
     795    Py_INCREF(value);
     796    self->cap_class = value;
     797    Py_XDECREF(tmp);
     798    return 0;
     799}/*}}}*/
     800
     801static PyGetSetDef Invar_getseters[] = {
     802    {"props",
     803     (getter)Invar_getProps, (setter)Invar_setProps,
     804     "Props object for this container object",
     805     NULL},
     806    {"actidx_props",
     807     (getter)Invar_getActIdxProps, (setter)Invar_setActIdxProps,
     808     "Active prop indexes",
     809     NULL},
     810    {"fields",
     811     (getter)Invar_getFields, (setter)Invar_setFields,
     812     "Field object for this container object",
     813     NULL},
     814    {"actidx",
     815     (getter)Invar_getActIdx, (setter)Invar_setActIdx,
     816     "Active field indexes",
     817     NULL},
     818    {"segment_attr",
     819     (getter)Invar_getSegmentAttr, (setter)Invar_setSegmentAttr,
     820     "Segment attributes",
     821     NULL},
     822    {"modify_sems",
     823     (getter)Invar_getModifySems, (setter)Invar_setModifySems,
     824     "Modification semaphore set",
     825     NULL},
     826    {"select_query",
     827     (getter)Invar_getSelectQuery, (setter)Invar_setSelectQuery,
     828     "Select query specified by this invariant",
     829     NULL},
     830    {"cache",
     831     (getter)Invar_getCache, (setter)Invar_setCache,
     832     "Cache for invariants",
     833     NULL},
     834    {"local",
     835     (getter)Invar_getLocal, (setter)Invar_setLocal,
     836     "local dictionary for invariants",
     837     NULL},
     838    {"cap_class",
     839     (getter)Invar_getCapClass, (setter)Invar_setCapClass,
     840     "Stores capability class for variable part",
     841     NULL},
     842    {NULL}  /* Sentinel */
     843};
     844
     845
     846static PyObject * Invar_register(Invar *self,PyObject * args)
     847{
     848    PyObject *basecon, *key;
     849    Invar *new_invar=NULL;
     850    PyObject *tmp;
     851    long i,args_size;
     852    args_size = PyTuple_GET_SIZE(args);
     853
     854    if(args_size == 0)
     855    {
     856        PyErr_SetString(PyExc_TypeError, "First argument of register should be source object.");
     857        Py_DECREF(new_invar);
     858        return NULL;
     859    }
     860    basecon = PyTuple_GET_ITEM(args,0);
     861    if(!PyObject_IsInstance(basecon,(PyObject *)&BaseContainer_Type))
     862    {
     863        PyErr_SetString(PyExc_TypeError, "First argument of register should be source object.");
     864        Py_DECREF(new_invar);
     865        return NULL;
     866    }
     867
     868    Py_INCREF(basecon->ob_type); //used in key, will be decrefd later
     869    if(args_size == 1)
     870        key = (PyObject *) basecon->ob_type;
     871    else
     872    {
     873       key = PyTuple_New(args_size);
     874       PyTuple_SET_ITEM(key,0,(PyObject *) basecon->ob_type);
     875       if(key == NULL)
     876            return NULL;
     877       for(i = 1; i < args_size; i++)
     878       {
     879            tmp = PyTuple_GET_ITEM(args,i);
     880            Py_INCREF(tmp);
     881            PyTuple_SET_ITEM(key,i,tmp);
     882       }
     883    }
     884
     885    if(self->cache != NULL)
     886    {
     887        new_invar = (Invar *) PyDict_GetItem(self->cache,key);
     888        Py_XINCREF(new_invar);
     889    }
     890    else
     891    {
     892        self->cache = PyDict_New();
     893        if(self->cache == NULL)
     894        {
     895            Py_DECREF(key);
     896            return NULL;
     897        }
     898    }
     899
     900    if(new_invar == NULL)
     901    {
     902        new_invar = (Invar *)  Invar_Type.tp_alloc(&Invar_Type,0);
     903        if(PyDict_SetItem(self->cache,key,(PyObject *) new_invar)==-1)
     904        {
     905            Py_DECREF(key);
     906            return NULL;
     907        }
     908        tmp = (PyObject *)((BaseContainer *)basecon)->invar;
     909        ((BaseContainer *)basecon)->invar = new_invar;
     910        Py_DECREF(key);
     911        Py_XDECREF(tmp);
     912        Py_INCREF(Py_True);
     913        return Py_True;
     914    }
     915    else
     916    {
     917
     918        if(((Invar *)new_invar)->cap_class != NULL)
     919        {
     920            //lets do it the safe way so that we check for class conflicts...
     921            if(PyObject_SetAttrString(basecon,"__class__",((Invar *)new_invar)->cap_class)==-1)
     922            {
     923                Py_DECREF(new_invar);
     924                return NULL;
     925            }
     926        }
     927        tmp = (PyObject *)((BaseContainer *)basecon)->invar;
     928        ((BaseContainer *)basecon)->invar = new_invar;
     929        Py_DECREF(key);
     930        Py_XDECREF(tmp);
     931        Py_INCREF(Py_False);
     932        return Py_False;
     933    }
     934}
     935
     936static PyMethodDef Invar_methods[] = {
     937    {"register", (PyCFunction)Invar_register, METH_VARARGS,
     938     "Register basecontainer with invariant"
     939    },
     940    {NULL}
     941};
     942
     943
     944static PyTypeObject Invar_Type = {
     945    PyObject_HEAD_INIT(NULL)
     946    0,                         /*ob_size*/
     947    "base_container.Invar",             /*tp_name*/
     948    sizeof(Invar),             /*tp_basicsize*/
     949    0,                         /*tp_itemsize*/
     950    (destructor)Invar_dealloc, /*tp_dealloc*/
     951    0,                         /*tp_print*/
     952    0,                         /*tp_getattr*/
     953    0,                         /*tp_setattr*/
     954    0,                         /*tp_compare*/
     955    0,                         /*tp_repr*/
     956    0,                         /*tp_as_number*/
     957    0,                         /*tp_as_sequence*/
     958    0,                         /*tp_as_mapping*/
     959    0,                         /*tp_hash */
     960    0,          /*tp_call*/
     961    0,                         /*tp_str*/
     962    0,                          /*tp_getattro*/
     963    0,                         /*tp_setattro*/
     964    0,                         /*tp_as_buffer*/
     965    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE | Py_TPFLAGS_HAVE_CLASS, /*tp_flags*/
     966    "Invar object",           /* tp_doc */
     967    0,                         /* tp_traverse */
     968    0,                         /* tp_clear */
     969    0,                     /* tp_richcompare */
     970    0,                         /* tp_weaklistoffset */
     971    0,                         /* tp_iter */
     972    0,                         /* tp_iternext */
     973    Invar_methods,         /* tp_methods */
     974    0,                         /* tp_members */
     975    Invar_getseters,                     /* tp_getset */
     976    0,                         /* tp_base */
     977    0,                         /* tp_dict */
     978    0,                         /* tp_descr_get */
     979    0,                         /* tp_descr_set */
     980    offsetof(Invar,local),      /* tp_dictoffset */
     981    0,                  /* tp_init */
     982    0,                         /* tp_alloc */
     983    0,                 /* tp_new */
     984};/*}}}*/
     985
     986static void BaseContainer_dealloc(BaseContainer* self)/*{{{*/
     987{
     988    Py_XDECREF(self->invar);
     989    Py_XDECREF(self->result);
     990    Py_XDECREF(self->source);
     991
     992    self->ob_type->tp_free((PyObject*)self);
     993}
     994
     995static PyObject * BaseContainer_getInvar(BaseContainer *self, void *closure)/*{{{*/
     996{
     997    if(self->invar == NULL)
     998    {
     999        PyErr_SetString(PyExc_TypeError, "BaseContainer object not properly initialized (no invar).");
     1000        return NULL;
     1001    }   
     1002    Py_INCREF(self->invar);
     1003    return (PyObject *) self->invar;
     1004}
     1005static int BaseContainer_setInvar(BaseContainer *self, PyObject *value, void *closure)
     1006{
     1007    Invar *tmp;
     1008    if(value == NULL)
     1009    {
     1010        Py_XDECREF(self->invar);
     1011        self->invar = NULL;
     1012        return 0;
     1013    }
     1014   
     1015    if(!(value->ob_type == &Invar_Type))
     1016    {
     1017        PyErr_SetString(PyExc_TypeError, "Invar parameter should be an invar object");
     1018        return -1;
     1019    }
     1020    tmp = self->invar;
     1021    Py_INCREF(value);
     1022    self->invar = (Invar *)value;
     1023    Py_XDECREF(tmp);
     1024    return 0;
     1025}/*}}}*/
     1026
     1027static PyObject * BaseContainer_getResult(BaseContainer *self, void *closure)/*{{{*/
     1028{
     1029    if(self->result == NULL)
     1030    {
     1031        Py_INCREF(Py_None);
     1032        return Py_None;
     1033    }   
     1034    Py_INCREF(self->result);
     1035    return self->result;
     1036}
     1037static int BaseContainer_setResult(BaseContainer *self, PyObject *value, void *closure)
     1038{
     1039    PyObject *tmp;
     1040    tmp = self->result;
     1041    Py_XINCREF(value);
     1042    self->result = value;
     1043    Py_XDECREF(tmp);
     1044    return 0;
     1045}/*}}}*/
     1046
     1047static PyObject * BaseContainer_getSource(BaseContainer *self, void *closure)/*{{{*/
     1048{
     1049    if(self->source == NULL)
     1050    {
     1051        Py_RETURN_NONE;
     1052    }   
     1053    Py_INCREF(self->source);
     1054    return self->source;
     1055}
     1056static int BaseContainer_setSource(BaseContainer *self, PyObject *value, void *closure)
     1057{
     1058    PyObject *tmp;
     1059    if(value == NULL)
     1060    {
     1061        Py_XDECREF(self->source);
     1062        self->source = NULL;
     1063        return 0;
     1064    }
     1065    if(!(PyTuple_Check(value)))
     1066    {
     1067        PyErr_SetString(PyExc_TypeError, "Source should be an tuple");
     1068        return -1;
     1069    }
     1070    tmp = self->source;
     1071    Py_INCREF(value);
     1072    self->source = value;
     1073    Py_XDECREF(tmp);
     1074    return 0;
     1075}/*}}}*/
     1076
     1077static PyObject * BaseContainer_getProps(BaseContainer *self, void *closure)/*{{{*/
     1078{
     1079    if(self->invar == NULL)
     1080    {
     1081        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1082        return NULL;
     1083    }   
     1084    return Invar_getProps(self->invar,closure);
     1085}
     1086static int BaseContainer_setProps(BaseContainer *self, PyObject *value, void *closure)
     1087{
     1088    if(self->invar == NULL)
     1089    {
     1090        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1091        return -1;
     1092    } 
     1093    return Invar_setProps(self->invar,value,closure);
     1094}/*}}}*/
     1095
     1096static PyObject * BaseContainer_getActIdxProps(BaseContainer *self, void *closure)/*{{{*/
     1097{
     1098    if(self->invar == NULL)
     1099    {
     1100        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1101        return NULL;
     1102    }   
     1103    return Invar_getActIdxProps(self->invar,closure);
     1104}
     1105static int BaseContainer_setActIdxProps(BaseContainer *self, PyObject *value, void *closure)
     1106{
     1107    if(self->invar == NULL)
     1108    {
     1109        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1110        return -1;
     1111    } 
     1112    return Invar_setActIdxProps(self->invar,value,closure);
     1113}/*}}}*/
     1114
     1115static PyObject * BaseContainer_getFields(BaseContainer *self, void *closure)/*{{{*/
     1116{
     1117    if(self->invar == NULL)
     1118    {
     1119        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1120        return NULL;
     1121    }   
     1122    return Invar_getFields(self->invar,closure);
     1123}
     1124static int BaseContainer_setFields(BaseContainer *self, PyObject *value, void *closure)
     1125{
     1126    if(self->invar == NULL)
     1127    {
     1128        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1129        return -1;
     1130    } 
     1131    return Invar_setFields(self->invar,value,closure);
     1132}/*}}}*/
     1133
     1134static PyObject * BaseContainer_getActIdx(BaseContainer *self, void *closure)/*{{{*/
     1135{
     1136    if(self->invar == NULL)
     1137    {
     1138        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1139        return NULL;
     1140    }   
     1141    return Invar_getActIdx(self->invar,closure);
     1142}
     1143static int BaseContainer_setActIdx(BaseContainer *self, PyObject *value, void *closure)
     1144{
     1145    if(self->invar == NULL)
     1146    {
     1147        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1148        return -1;
     1149    } 
     1150    return Invar_setActIdx(self->invar,value,closure);
     1151}/*}}}*/
     1152
     1153static PyObject * BaseContainer_getSegmentAttr(BaseContainer *self, void *closure)/*{{{*/
     1154{
     1155    if(self->invar == NULL)
     1156    {
     1157        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1158        return NULL;
     1159    }   
     1160    return Invar_getSegmentAttr(self->invar,closure);
     1161}
     1162static int BaseContainer_setSegmentAttr(BaseContainer *self, PyObject *value, void *closure)
     1163{
     1164    if(self->invar == NULL)
     1165    {
     1166        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1167        return -1;
     1168    } 
     1169    return Invar_setSegmentAttr(self->invar,value,closure);
     1170}/*}}}*/
     1171
     1172static PyObject * BaseContainer_getModifySems(BaseContainer *self, void *closure)/*{{{*/
     1173{
     1174    if(self->invar == NULL)
     1175    {
     1176        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1177        return NULL;
     1178    }   
     1179    return Invar_getModifySems(self->invar,closure);
     1180}
     1181static int BaseContainer_setModifySems(BaseContainer *self, PyObject *value, void *closure)
     1182{
     1183    if(self->invar == NULL)
     1184    {
     1185        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1186        return -1;
     1187    } 
     1188    return Invar_setModifySems(self->invar,value,closure);
     1189}/*}}}*/
     1190
     1191static PyObject * BaseContainer_getSelectQuery(BaseContainer *self, void *closure)/*{{{*/
     1192{
     1193    if(self->invar == NULL)
     1194    {
     1195        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1196        return NULL;
     1197    }   
     1198    return Invar_getSelectQuery(self->invar,closure);
     1199}
     1200static int BaseContainer_setSelectQuery(BaseContainer *self, PyObject *value, void *closure)
     1201{
     1202    if(self->invar == NULL)
     1203    {
     1204        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1205        return -1;
     1206    } 
     1207    return Invar_setSelectQuery(self->invar,value,closure);
     1208}/*}}}*/
     1209
     1210static PyObject * BaseContainer_getLocal(BaseContainer *self, void *closure)/*{{{*/
     1211{
     1212    if(self->invar == NULL)
     1213    {
     1214        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1215        return NULL;
     1216    }   
     1217    return Invar_getLocal(self->invar,closure);
     1218}
     1219static int BaseContainer_setLocal(BaseContainer *self, PyObject *value, void *closure)
     1220{
     1221    if(self->invar == NULL)
     1222    {
     1223        PyErr_SetString(PyExc_TypeError, "Invar not set!");
     1224        return -1;
     1225    } 
     1226    return Invar_setLocal(self->invar,value,closure);
     1227}/*}}}*/
     1228
    6601229static PyGetSetDef BaseContainer_getseters[] = {
    661     {"_props",
    662      (getter)BaseContainer_getProps, (setter)BaseContainer_setProps,
    663      "Props object for this container object",
    664      NULL},
    665     {"_fields",
    666      (getter)BaseContainer_getFields, (setter)BaseContainer_setFields,
    667      "Field object for this container object",
    668      NULL},
    669     {"_actidx",
    670      (getter)BaseContainer_getActIdx, (setter)BaseContainer_setActIdx,
    671      "Active field indexes",
    672      NULL},
    6731230    {"_invar",
    6741231     (getter)BaseContainer_getInvar, (setter)BaseContainer_setInvar,
    6751232     "Invariant part of this container",
    6761233     NULL},
     1234    {"_result",
     1235     (getter)BaseContainer_getResult, (setter)BaseContainer_setResult,
     1236     "Result of query",
     1237     NULL},
     1238    {"_source",
     1239     (getter)BaseContainer_getSource, (setter)BaseContainer_setSource,
     1240     "Tuple with source basecontainers",
     1241     NULL},
     1242    {"_props",
     1243     (getter)BaseContainer_getProps, (setter)BaseContainer_setProps,
     1244     "Refers to invar props",
     1245     NULL},
     1246    {"_actidx_props",
     1247     (getter)BaseContainer_getActIdxProps, (setter)BaseContainer_setActIdxProps,
     1248     "Refers to invar active prop index",
     1249     NULL},
     1250    {"_fields",
     1251     (getter)BaseContainer_getFields, (setter)BaseContainer_setFields,
     1252     "Refers to invar fields",
     1253     NULL},
     1254    {"_actidx",
     1255     (getter)BaseContainer_getActIdx, (setter)BaseContainer_setActIdx,
     1256     "Refers to invar active field index",
     1257     NULL},
    6771258    {"_segment_attr",
    6781259     (getter)BaseContainer_getSegmentAttr, (setter)BaseContainer_setSegmentAttr,
    679      "Segment attributes",
     1260     "Refers to invar segment attr",
    6801261     NULL},
    6811262    {"_modify_sems",
    6821263     (getter)BaseContainer_getModifySems, (setter)BaseContainer_setModifySems,
    683      "Modification semaphore set",
     1264     "Refers to invar modify_sems",
     1265     NULL},
     1266    {"_select_query",
     1267     (getter)BaseContainer_getSelectQuery, (setter)BaseContainer_setSelectQuery,
     1268     "Refers to invar select query",
     1269     NULL},
     1270    {"_local",
     1271     (getter)BaseContainer_getLocal, (setter)BaseContainer_setLocal,
     1272     "Local invariant dictionary ",
    6841273     NULL},
    6851274    {NULL}  /* Sentinel */
     
    7451334    QueryResult_Type.tp_new = PyType_GenericNew;
    7461335    ModificationSemaphore_Type.tp_new = PyType_GenericNew;
     1336    Invar_Type.tp_new = PyType_GenericNew;
    7471337
    7481338    if (PyType_Ready(&ModificationSemaphore_Type) < 0)
     
    7521342    if (PyType_Ready(&BaseContainer_Type) < 0)
    7531343        return;
     1344    if (PyType_Ready(&Invar_Type) < 0)
     1345        return;
    7541346
    7551347
     
    7641356    Py_INCREF(&QueryResult_Type);
    7651357    Py_INCREF(&BaseContainer_Type);
     1358    Py_INCREF(&Invar_Type);
    7661359    PyModule_AddObject(m, "ModificationSemaphore", (PyObject *)&ModificationSemaphore_Type);
    7671360    PyModule_AddObject(m, "QueryResult", (PyObject *)&QueryResult_Type);
    7681361    PyModule_AddObject(m, "BaseContainer", (PyObject *)&BaseContainer_Type);
     1362    PyModule_AddObject(m, "Invar", (PyObject *)&Invar_Type);
    7691363
    7701364    PyBContainer_API[QueryResult_copy_NUM] = (void *)QueryResult_copy;
     
    7751369        PyModule_AddObject(m, "_C_API", c_api_object);
    7761370
    777 
    778 
    779 }
     1371}
  • src/base_container.h

    r105 r119  
    2525    PyObject_HEAD
    2626    PyObject * props;
     27    PyObject * actidx_props;
     28    PyObject * fields;
    2729    PyObject * actidx;
    28     PyObject * fields;
    29     PyObject * invar;
    3030    PyObject * segment_attr;
    31    
    3231    PyObject * modify_sems;
     32    PyObject * select_query;
     33    PyObject * cache;
     34    PyObject * cap_class;
     35    PyObject * local;
     36} Invar;
     37
     38
     39typedef struct {
     40    PyObject_HEAD
     41    Invar * invar;         
     42    PyObject * result;       
     43    PyObject * source;
    3344} BaseContainer;
    3445
     
    4556    static PyTypeObject QueryResult_Type;
    4657    static PyTypeObject BaseContainer_Type;
     58    static PyTypeObject Invar_Type;
    4759   
    4860    static PyObject * QueryResult_copy(QueryResult *self);
     
    5769    static PyTypeObject * QueryResult_Type = NULL;
    5870    static PyTypeObject * BaseContainer_Type = NULL;
     71    static PyTypeObject * Invar_Type = NULL;
    5972       
    6073    /* Return -1 and set exception on error, 0 on success. */
     
    7689            QueryResult_Type = (PyTypeObject *)PyObject_GetAttrString(module, "QueryResult");
    7790            BaseContainer_Type = (PyTypeObject *)PyObject_GetAttrString(module, "BaseContainer");
     91            Invar_Type = (PyTypeObject *)PyObject_GetAttrString(module, "Invar");
    7892           
    7993        }
  • src/multi_visitor.c

    r37 r119  
    328328static PyObject * VisitorFactory(PyObject * self, PyObject *args, PyObject *kwds, PyObject *closure) /*{{{*/
    329329{
    330     PyObject *name = NULL, *prefixes = NULL, *bases = NULL, *flags = NULL, *tmp;
     330    PyObject *name = NULL, *prefixes = NULL, *bases = NULL, *flags = NULL, *typedict = NULL, *tmp;
    331331    PyObject *nargs, *res = NULL;
    332332    PyTypeObject *ntype;
     
    334334    VisitifyFunction vsfunc = (VisitifyFunction) PyCObject_AsVoidPtr(PyTuple_GET_ITEM(closure,0));
    335335
    336     static char *kwlist[] = {"name","prefixes","bases","flags",NULL};
    337     if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!O!O!O!", kwlist, &PyString_Type,&name,(PyObject *)&PyTuple_Type, &prefixes, &PyTuple_Type, &bases, (PyObject *)&PyInt_Type, &flags))
     336    static char *kwlist[] = {"name","prefixes","bases","flags","typedict",NULL};
     337    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|O!O!O!O!O!", kwlist, &PyString_Type,&name,(PyObject *)&PyTuple_Type, &prefixes, &PyTuple_Type, &bases, (PyObject *)&PyInt_Type, &flags, (PyObject *)&PyDict_Type, &typedict))
    338338        return NULL;
    339339
     
    389389        Py_INCREF(flags);
    390390 
    391 
    392     nargs = Py_BuildValue("(OON)",name,bases,PyDict_New());
     391    if(typedict == NULL)
     392        typedict = PyDict_New();
     393    else
     394        Py_INCREF(typedict);
     395
     396    nargs = Py_BuildValue("(OON)",name,bases,typedict);
    393397    if(nargs == NULL)
    394398        goto vis_error;
  • src/qgraph.c

    r110 r119  
    99 * to their source and target objects, as well as
    1010 * fields, properties, and active fields. */
     11
    1112/*{{{*/static PyTypeObject Node_Type;
    1213
     
    2829    PyObject * exec_params;
    2930    PyObject * req_fields;
     31    PyObject * invar_dict;
    3032} Node;
    3133
     
    4850    Py_XDECREF(self->exec_params);
    4951    Py_XDECREF(self->req_fields);
     52    Py_XDECREF(self->invar_dict);
    5053    self->ob_type->tp_free((PyObject*)self);
    5154}
     
    5558Node_init(Node *self, PyObject *args, PyObject *kwds)
    5659{
    57    PyObject *obj,*source = NULL,*target = NULL, *fields, *props, *actidx, *segment_attr, *output_segment;
     60   PyObject *obj,*source = NULL,*target = NULL, *output_segment;
     61   Invar * invar;
    5862   static char *kwlist[] = {"obj","source","target",NULL};
    5963   if(!PyArg_ParseTupleAndKeywords(args,kwds,"O|O!O!",kwlist,
     
    8286        Py_INCREF(obj->ob_type);
    8387        self->obj = (PyObject *)obj->ob_type;
     88        invar = ((BaseContainer *)obj)->invar;
     89
     90        if(invar == NULL)
     91        {
     92            PyErr_SetString(PyExc_TypeError, "Invar should be set");
     93            return -1;
     94        }
    8495
    8596        output_segment = PyObject_GetAttrString(self->obj,"_output_segment");
     
    89100        self->output_segment = output_segment;
    90101
    91         fields = ((BaseContainer *)obj)->fields;
    92         Py_XINCREF(fields);
    93         self->fields = fields;
    94 
    95         actidx = ((BaseContainer *)obj)->actidx;
    96         Py_XINCREF(actidx);
    97         self->actidx = actidx;
    98 
    99         props = ((BaseContainer *)obj)->props;
    100         Py_XINCREF(props);
    101         self->props = props;
     102
     103        Py_XINCREF(invar->fields);
     104        self->fields = invar->fields;
     105
     106        Py_XINCREF(invar->actidx);
     107        self->actidx = invar->actidx;
     108
     109        Py_XINCREF(invar->props);
     110        self->props = invar->props;
    102111       
    103         segment_attr = ((BaseContainer *)obj)->segment_attr;
    104         Py_XINCREF(segment_attr);
    105         self->segment_attr = segment_attr;
     112        Py_XINCREF(invar->segment_attr);
     113        self->segment_attr = invar->segment_attr;
     114       
     115        Py_XINCREF(invar->local);
     116        self->invar_dict = invar->local;
     117
    106118   }
    107119   else
     
    115127
    116128
    117 static PyObject *
    118 Node_getObj(Node *self, void *closure)
     129static PyObject * Node_getObj(Node *self, void *closure)/*{{{*/
    119130{
    120131    Py_INCREF(self->obj);
    121132    return self->obj;
    122133}
    123 static int
    124 Node_setObj(Node *self, PyObject *value, void *closure)
     134static int Node_setObj(Node *self, PyObject *value, void *closure)
    125135{
    126136    PyObject *tmp;
    127137    tmp = self->obj;
    128     Py_INCREF(value);
     138    Py_XINCREF(value);
    129139    self->obj = value;
    130140    Py_XDECREF(tmp);
    131141    return 0;
    132 }
    133 
    134 
    135 static PyObject *
    136 Node_getSource(Node *self, void *closure)
     142}/*}}}*/
     143
     144static PyObject * Node_getSource(Node *self, void *closure)/*{{{*/
    137145{
    138146    Py_INCREF(self->source);
    139147    return self->source;
    140148}
    141 static int
    142 Node_setSource(Node *self, PyObject *value, void *closure)
     149static int Node_setSource(Node *self, PyObject *value, void *closure)
    143150{
    144151    PyObject *tmp;
    145     if(!PyList_Check(value))
     152    if(value == NULL || !PyList_Check(value))
    146153    {
    147154        PyErr_SetString(PyExc_TypeError, "Source should be a list object");
     
    153160    Py_DECREF(tmp);
    154161    return 0;
    155 }
    156 
    157 static PyObject *
    158 Node_getTarget(Node *self, void *closure)
     162}/*}}}*/
     163
     164static PyObject * Node_getTarget(Node *self, void *closure)/*{{{*/
    159165{
    160166    Py_INCREF(self->target);
    161167    return self->target;
    162168}
    163 static int
    164 Node_setTarget(Node *self, PyObject *value, void *closure)
     169static int Node_setTarget(Node *self, PyObject *value, void *closure)
    165170{
    166171    PyObject *tmp;
    167     if(!PyList_Check(value))
     172    if(value == NULL || !PyList_Check(value))
    168173    {
    169174        PyErr_SetString(PyExc_TypeError, "Target should be a list object");
     
    175180    Py_DECREF(tmp);
    176181    return 0;
    177 }
    178 
    179 static PyObject *
    180 Node_getFields(Node *self, void *closure)
     182}/*}}}*/
     183
     184static PyObject * Node_getFields(Node *self, void *closure)/*{{{*/
    181185{
    182186    if(!self->fields)
     
    188192    return self->fields;
    189193}
    190 static int
    191 Node_setFields(Node *self, PyObject *value, void *closure)
     194static int Node_setFields(Node *self, PyObject *value, void *closure)
    192195{
    193196    PyObject *tmp;
    194197    tmp = self->fields;
    195     Py_INCREF(value);
     198    Py_XINCREF(value);
    196199    self->fields = value;
    197200    Py_XDECREF(tmp);
    198201    return 0;
    199 }
    200 
    201 static PyObject *
    202 Node_getActIdx(Node *self, void *closure)
     202}/*}}}*/
     203
     204static PyObject * Node_getActIdx(Node *self, void *closure)/*{{{*/
    203205{
    204206    if(!self->actidx)
     
    210212    return self->actidx;
    211213}
    212 static int
    213 Node_setActIdx(Node *self, PyObject *value, void *closure)
     214static int Node_setActIdx(Node *self, PyObject *value, void *closure)
    214215{
    215216    PyObject *tmp;
    216217    tmp = self->actidx;
    217     Py_INCREF(value);
     218    Py_XINCREF(value);
    218219    self->actidx = value;
    219220    Py_XDECREF(tmp);
    220221    return 0;
    221 }
    222 
    223 static PyObject *
    224 Node_getProps(Node *self, void *closure)
     222}/*}}}*/
     223
     224static PyObject * Node_getProps(Node *self, void *closure)/*{{{*/
    225225{
    226226    if(!self->props)
     
    232232    return self->props;
    233233}
    234 static int
    235 Node_setProps(Node *self, PyObject *value, void *closure)
     234static int Node_setProps(Node *self, PyObject *value, void *closure)
    236235{
    237236    PyObject *tmp;
    238237    tmp = self->props;
    239     Py_INCREF(value);
     238    Py_XINCREF(value);
    240239    self->props = value;
    241240    Py_XDECREF(tmp);
    242241    return 0;
    243 }
    244 
    245 static PyObject *
    246 Node_getSegmentAttr(Node *self, void *closure)
     242}/*}}}*/
     243
     244static PyObject * Node_getSegmentAttr(Node *self, void *closure)/*{{{*/
    247245{
    248246    if(!self->segment_attr)
     
    254252    return self->segment_attr;
    255253}
    256 static int
    257 Node_setSegmentAttr(Node *self, PyObject *value, void *closure)
     254static int Node_setSegmentAttr(Node *self, PyObject *value, void *closure)
    258255{
    259256    PyObject *tmp;
    260257    tmp = self->segment_attr;
    261     Py_INCREF(value);
     258    Py_XINCREF(value);
    262259    self->segment_attr = value;
    263260    Py_XDECREF(tmp);
    264261    return 0;
    265 }
    266 
    267 static PyObject *
    268 Node_getInFields(Node *self, void *closure)
     262}/*}}}*/
     263
     264static PyObject * Node_getInFields(Node *self, void *closure)/*{{{*/
    269265{
    270266    if(!self->in_fields)
     
    276272    return self->in_fields;
    277273}
    278 static int
    279 Node_setInFields(Node *self, PyObject *value, void *closure)
     274static int Node_setInFields(Node *self, PyObject *value, void *closure)
    280275{
    281276    PyObject *tmp;
    282277    tmp = self->in_fields;
    283     Py_INCREF(value);
     278    Py_XINCREF(value);
    284279    self->in_fields = value;
    285280    Py_XDECREF(tmp);
    286281    return 0;
    287 }
    288 static PyObject *
    289 Node_getOutCalc(Node *self, void *closure)
     282}/*}}}*/
     283
     284static PyObject * Node_getOutCalc(Node *self, void *closure)/*{{{*/
    290285{
    291286    if(!self->out_calc)
     
    297292    return self->out_calc;
    298293}
    299 static int
    300 Node_setOutCalc(Node *self, PyObject *value, void *closure)
     294static int Node_setOutCalc(Node *self, PyObject *value, void *closure)
    301295{
    302296    PyObject *tmp;
    303297    tmp = self->out_calc;
    304     Py_INCREF(value);
     298    Py_XINCREF(value);
    305299    self->out_calc = value;
    306300    Py_XDECREF(tmp);
    307301    return 0;
    308 }
    309 static PyObject *
    310 Node_getOutFields(Node *self, void *closure)
     302}/*}}}*/
     303
     304static PyObject * Node_getOutFields(Node *self, void *closure)/*{{{*/
    311305{
    312306    if(!self->out_fields)
     
    318312    return self->out_fields;
    319313}
    320 static int
    321 Node_setOutFields(Node *self, PyObject *value, void *closure)
     314static int Node_setOutFields(Node *self, PyObject *value, void *closure)
    322315{
    323316    PyObject *tmp;
    324317    tmp = self->out_fields;
    325     Py_INCREF(value);
     318    Py_XINCREF(value);
    326319    self->out_fields = value;
    327320    Py_XDECREF(tmp);
    328321    return 0;
    329 }
    330 
    331 static PyObject *
    332 Node_getOutputSegment(Node *self, void *closure)
     322}/*}}}*/
     323
     324static PyObject * Node_getOutputSegment(Node *self, void *closure)/*{{{*/
    333325{
    334326    if(!self->output_segment)
     
    340332    return self->output_segment;
    341333}
    342 static int
    343 Node_setOutputSegment(Node *self, PyObject *value, void *closure)
     334static int Node_setOutputSegment(Node *self, PyObject *value, void *closure)
    344335{
    345336    PyObject *tmp;
    346337    tmp = self->output_segment;
    347     Py_INCREF(value);
     338    Py_XINCREF(value);
    348339    self->output_segment = value;
    349340    Py_XDECREF(tmp);
    350341    return 0;
    351 }
    352 
    353 static PyObject *
    354 Node_getExecParams(Node *self, void *closure)
     342}/*}}}*/
     343
     344static PyObject * Node_getExecParams(Node *self, void *closure)/*{{{*/
    355345{
    356346    if(!self->exec_params)
     
    362352    return self->exec_params;
    363353}
    364 static int
    365 Node_setExecParams(Node *self, PyObject *value, void *closure)
     354static int Node_setExecParams(Node *self, PyObject *value, void *closure)
    366355{
    367356    PyObject *tmp;
    368357    tmp = self->exec_params;
    369     Py_INCREF(value);
     358    Py_XINCREF(value);
    370359    self->exec_params = value;
    371360    Py_XDECREF(tmp);
    372361    return 0;
    373 }
    374 
    375 static PyObject *
    376 Node_getReqFields(Node *self, void *closure)
     362}/*}}}*/
     363
     364static PyObject * Node_getReqFields(Node *self, void *closure)/*{{{*/
    377365{
    378366    if(!self->req_fields)
     
    384372    return self->req_fields;
    385373}
    386 static int
    387 Node_setReqFields(Node *self, PyObject *value, void *closure)
     374static int Node_setReqFields(Node *self, PyObject *value, void *closure)
    388375{
    389376    PyObject *tmp;
    390377    tmp = self->req_fields;
    391     Py_INCREF(value);
     378    Py_XINCREF(value);
    392379    self->req_fields = value;
    393380    Py_XDECREF(tmp);
    394381    return 0;
    395382}
    396 
     383/*}}}*/
     384
     385static PyObject * Node_getInvarDict(Node *self, void *closure)/*{{{*/
     386{
     387    if(!self->invar_dict)
     388    {
     389        Py_INCREF(Py_None);
     390        self->invar_dict = Py_None;
     391    }
     392    Py_INCREF(self->invar_dict);
     393    return self->invar_dict;
     394}
     395static int Node_setInvarDict(Node *self, PyObject *value, void *closure)
     396{
     397    PyObject *tmp;
     398    tmp = self->invar_dict;
     399    Py_XINCREF(value);
     400    self->invar_dict = value;
     401    Py_XDECREF(tmp);
     402    return 0;
     403}
     404/*}}}*/
    397405
    398406static PyGetSetDef Node_getseters[] = {
     
    448456     (getter)Node_getReqFields, (setter)Node_setReqFields,
    449457     "Extra required fields",
     458     NULL},
     459    {"invar_dict",
     460     (getter)Node_getInvarDict, (setter)Node_setInvarDict,
     461     "Invariant dictionary",
    450462     NULL},
    451463    {NULL}  /* Sentinel */
     
    495507/*}}}*/
    496508
    497 
    498509/*{{{*/
    499510typedef struct {
     
    529540{
    530541    PyObject *visited, *source,*target;
    531     PyObject *res, *item, *tmp;
     542    PyObject *res, *item;
    532543    Py_ssize_t ssize;
    533544    int i;
     
    538549    }
    539550    visited = PyTuple_GET_ITEM(args,0);
    540     
     551   
    541552
    542553    if(PyObject_IsInstance(visited,(PyObject *) BaseContainer_Type))
     
    584595           
    585596            /* Handle modifiable containers */
    586             if(((BaseContainer *)visited)->modify_sems != NULL)
     597            if(((BaseContainer *)visited)->invar == NULL)
     598            {
     599                PyErr_SetString(PyExc_TypeError, "Invar has not been set.");
     600                return NULL;
     601 
     602            }
     603            if(((Invar *)((BaseContainer *)visited)->invar)->modify_sems != NULL)
    587604            {
    588605                PyList_Append(self->modifiables,visited);
    589606                if(self->cur_sems == NULL)
    590                     self->cur_sems = PySet_New(tmp);
     607                {
     608                    self->cur_sems = PySet_New(((Invar*)((BaseContainer *)visited)->invar)->modify_sems);
     609                }
    591610                else
    592611                {
    593612                    printf("Refc before %d\n",self->cur_sems->ob_refcnt);
    594                     self->cur_sems = PyNumber_InPlaceAnd(self->cur_sems,((BaseContainer *)visited)->modify_sems);
     613                    self->cur_sems = PyNumber_InPlaceAnd(self->cur_sems,((Invar*)((BaseContainer *)visited)->invar)->modify_sems);
    595614                    if(self->cur_sems == NULL)
    596615                        return NULL;
     
    694713        return -1;
    695714    }
    696 
    697715    /* reset cache */
    698716    tmp = self->cache;
     
    709727    self->objs = PySet_New(NULL);
    710728    Py_XDECREF(tmp);
    711    
    712729    if(self->cache == NULL || self->params == NULL || self->objs == NULL)
    713730    {
     
    736753    if(self->qg_node == NULL)
    737754        return -1;
    738    
    739755
    740756    return 0;
  • test.py

    r105 r119  
    2929    e = container.table(data,['gene1','gene2','score'],['str(uint8)','str(uint8)','int64'],True)
    3030    #cProfile.run("e = container.table(data,['gene1','gene2','score'],['str(uint8)','str(uint8)','int64'],True)")
    31     print sys.getrefcount(e)
    32     w = "vlkasjdlajsdfsdfs"
    33     print sys.getrefcount(w)
    3431
    3532    #loop(e)
Note: See TracChangeset for help on using the changeset viewer.