Beispiel #1
0
    def add_all_data_to_delta_list(
        self,delta_to_add_to,current_internal_val,action_event,for_map):
        '''
        Run through entire list.  Create an add action for each element.

        @param {bool} for_map --- True if performing operations for
        map.  false if performing for list.
        '''
        if for_map:
            to_iter_over = current_internal_val.keys()
        else:
            to_iter_over = range(0,len(current_internal_val))

            
        for key in to_iter_over:
            if for_map:
                action = delta_to_add_to.map_actions.add()
            else:
                action = delta_to_add_to.list_actions.add()

            action.container_action = VarStoreDeltas.ContainerAction.ADD_KEY

            add_action = action.added_key
            add_action.parent_type = VarStoreDeltas.CONTAINER_ADDED

            if isinstance(key,numbers.Number):
                add_action.added_key_num = key
            elif util.is_string(key):
                add_action.added_key_text = key
            else:
                add_action.added_key_tf = key

            
            # now actually add the value to the map
            list_val = current_internal_val[key]

            
            if isinstance(list_val,numbers.Number):
                add_action.added_what_num = list_val
            elif util.is_string(list_val):
                add_action.added_what_text = list_val
            elif isinstance(list_val,bool):
                add_action.added_what_tf = list_val
            elif isinstance(list_val,WaldoLockedObj):
                list_val.serializable_var_tuple_for_network(
                    add_action,'',action_event,True)
                
            #### DEBUG
            else:
                util.logger_assert(
                    'Unkonw type to serialize')
Beispiel #2
0
def ensure_locked_obj(new_val,host_uuid,single_threaded):
    '''
    @param {Anything} new_val --- If new_val is a non-Waldo object,
    convert it to a Waldo object.  Otherwise, return it unchanged.

    This method is used to ensure that each individual entry in a
    map/list is also protected.

    @param {bool} single_threaded --- True if the variable should be
    single threaded.
    
    '''
    # FIXME: Need to include function object check in ensure locked
    # obj
    
    if isinstance(new_val, WaldoLockedObj):
        return new_val

    if single_threaded:
        if isinstance(new_val, bool):
            return SingleThreadedLockedTrueFalseVariable(host_uuid,False,new_val)
        elif isinstance(new_val, numbers.Number):
            return SingleThreadedLockedNumberVariable(host_uuid,False,new_val)
        elif util.is_string(new_val):
            return SingleThreadedLockedTextVariable(host_uuid,False,new_val)
        elif isinstance(new_val,list):
            return SingleThreadedLockedListVariable(host_uuid,False,new_val)
        elif isinstance(new_val,dict):
            return SingleThreadedLockedMapVariable(host_uuid,False,new_val)
        elif isinstance(new_val,EndpointBase):
            return SingleThreadedLockedEndpointVariable(host_uuid,False,new_val)
        else:
            util.logger_assert('Unknown object type.')

    else:
        if isinstance(new_val, bool):
            return LockedTrueFalseVariable(host_uuid,False,new_val)
        elif isinstance(new_val, numbers.Number):
            return LockedNumberVariable(host_uuid,False,new_val)
        elif util.is_string(new_val):
            return LockedTextVariable(host_uuid,False,new_val)
        elif isinstance(new_val,list):
            return LockedListVariable(host_uuid,False,new_val)
        elif isinstance(new_val,dict):
            return LockedMapVariable(host_uuid,False,new_val)
        elif isinstance(new_val,EndpointBase):
            return LockedEndpointVariable(host_uuid,False,new_val)
        else:
            util.logger_assert('Unknown object type.')
Beispiel #3
0
    def handle_in_check(self,lhs,rhs,active_event):
        '''
        Call has form:
            lhs in rhs
        
        rhs can have three basic types: it can be a list, a map, or a
        string.  That means that it can either be a WaldoMapVariable,
        a WaldoListVariable, a WaldoStringVariable, or a Python
        string.

        Instead of using static type inference at compile time to
        determine, for sake of development, just doing dynamic check
        to determine which type it is and do the in processing here.

        FIXME: it is faster to do the static checks with type
        inference, etc. at compile time rather than at run time.
        '''
        lhs_val = self.get_val_if_waldo(lhs,active_event)

        # handles Python string case
        if util.is_string(rhs):
            return lhs_val in rhs
        
        elif is_non_ext_text_var(rhs):
            return lhs_val in rhs.get_val(active_event)

        elif is_non_ext_map_var(rhs):
            return rhs.get_val(active_event).contains_key_called(active_event,lhs_val)
        
        elif is_non_ext_list_var(rhs):
            return rhs.get_val(active_event).contains_val_called(active_event,lhs_val)


        util.logger_assert(
            'Error when calling in: unknown right hand side of expression')
Beispiel #4
0
 def __init__(self,host_uuid,peered=False,init_val=None):        
     if init_val is None:
         init_val = ''
     if util.is_string(init_val):
         init_val = LockedTextVariable(host_uuid,False,init_val)
         
     # FIXME: Have no single threaded external variables.
     self.SINGLE_THREADED_CONSTRUCTOR = LockedTextVariable
     self.MULTI_THREADED_CONSTRUCTOR = LockedTextVariable
     super(WaldoExternalTextVariable,self).__init__(host_uuid,False,init_val)
Beispiel #5
0
    def get_for_iter(self,to_iter_over,active_event):
        '''
        When call for loop on Waldo variables, need to get item to
        iterate over
        '''

        if (isinstance(to_iter_over,dict) or
            isinstance(to_iter_over,list) or
            util.is_string(to_iter_over)):
            return iter(to_iter_over)

        if is_non_ext_text_var(to_iter_over):
            return iter(to_iter_over.get_val(active_event))

        if is_non_ext_map_var(to_iter_over):
            return iter(to_iter_over.get_val(active_event).get_keys(active_event))

        if is_non_ext_list_var(to_iter_over):
            # FIXME: This is an inefficient way of reading all values
            # over list.
            to_return = []
            internal_val = to_iter_over.get_val(active_event)
            for i in range(0, internal_val.get_len(active_event)):
                to_append = internal_val.get_val_on_key(active_event,i)

                # The reason that we do this here is that in a for
                # loop, the operation we perform in the compiled code
                # immediately following the actual for header is
                # assign to another Waldo variable the variable being
                # held by to_append.  (We do this through a set_val
                # call.  set_val must take in InternalMaps or
                # InternalLists.  Therefore, get_val on the
                # WaldoList/WaldoMap first.  Note this is unnecessary
                # for all other for iterations because none of the
                # others possibly return a WaldoObject to iterate over.
                if (is_non_ext_list_var(to_append) or
                    is_non_ext_map_var(to_append)):
                    to_append = to_append.get_val(active_event)
                
                to_return.append(to_append)

            return iter(to_return)

        util.logger_assert(
            'Calling get_for_iter on an object that does not support iteration')
Beispiel #6
0
    def handle_len(self,what_calling_len_on, active_event):
        '''
        Can support python lists, dicts, strings, or waldo lists, waldo maps,
        waldo texts.
        
        @returns {int}
        '''
        if (isinstance(what_calling_len_on, dict) or
            isinstance(what_calling_len_on, list) or
            util.is_string(what_calling_len_on)):
            return len(what_calling_len_on)

        if is_non_ext_text_var(what_calling_len_on):
            return len(what_calling_len_on.get_val(active_event))


        if (is_non_ext_list_var(what_calling_len_on) or
            is_non_ext_map_var(what_calling_len_on)):
            return what_calling_len_on.get_val(active_event).get_len(active_event)

        util.logger_assert(
            'Calling len on an object that does not support the function')
Beispiel #7
0
    def turn_into_waldo_var(
        self,val,force_copy,active_event, host_uuid,new_peered,
        new_multi_threaded):
        '''
        @param {Anything} val

        @param {bool} force_copy

        @param {_ActiveEvent object} active_event
        
        @param {uuid} host_uuid

        @param {bool} new_peered --- True if in the case that we have
        to copy a value, the copy should be peered.  Used for loading
        arguments into sequence local data when message send is
        called.  @see convert_for_seq_local.

        @returns {WaldoVariable}

        Used when copying arguments in to function.  Compiler's caller
        can pass in Python literals or WaldoReference objects when it
        emits a function call.  However, the emitted function
        definition requires all arguments to be WaldoVariables.
        Therefore, at the beginning of each emitted function, copy all
        arguments in to WaldoVariables if they are not already.  

        If val is not a WaldoReference, then based on its type, assign
        it as the initial value of a Waldo Variable and return.

        If val is a WaldoReference, then check force_copy.  force_copy
        represents whether or not we want to make a copy of the
        WaldoReference object.  (It would be True for instance if we
        were passed in a WaldoNumber because numbers are passed by
        value; it would be false if the arg was external or if we were
        passed in a reference type.)

        If it is false, then just return val.  Otherwise, make copy.
        
        '''

        # FIXME: Start using some of the single threaded constructors
        # as well.
        
        if isinstance(val,WaldoLockedObj):
            if force_copy:
                # means that it was a WaldoVariable: just call its copy
                # method
                return val.copy(active_event,new_peered,new_multi_threaded)
            # otherwise, just return val
            return val

        # means that val was not a reference object.... turn it into one.
        constructor = None

        if new_multi_threaded:

            if util.is_string(val):
                # not using isinstance here because python 3 and python
                # 2.7 have different ways of testing for string.
                constructor = LockedTextVariable
            elif isinstance(val,numbers.Number):
                constructor = LockedNumberVariable
            elif isinstance(val,bool):
                constructor = LockedTrueFalseVariable
            elif isinstance(val,dict):
                constructor = LockedMapVariable
            elif isinstance(val,list):
                constructor = LockedListVariable
            elif isinstance(val,EndpointBase):
                constructor = LockedEndpointVariable
            #### DEBUG
            elif hasattr(val,'__call__'):
                # checks if is function
                util.logger_assert(
                    'Should use special call func_turn_into_waldo_var for function objects')
            else:
                util.logger_assert(
                    'Unknown object type to call turn_into_waldo_var on')
            #### END DEBUG

                
        else:
            if util.is_string(val):
                # not using isinstance here because python 3 and python
                # 2.7 have different ways of testing for string.
                constructor = SingleThreadedLockedTextVariable
            elif isinstance(val,numbers.Number):
                constructor = SingleThreadedLockedNumberVariable
            elif isinstance(val,bool):
                constructor = SingleThreadedLockedTrueFalseVariable
            elif isinstance(val,dict):
                constructor = SingleThreadedLockedMapVariable
            elif isinstance(val,list):
                constructor = SingleThreadedLockedListVariable
            elif isinstance(val,EndpointBase):
                constructor = SingleThreadedLockedEndpointVariable

            #### DEBUG
            elif hasattr(val,'__call__'):
                # checks if is function
                util.logger_assert(
                    'Should use special call func_turn_into_waldo_var for function objects')
            else:
                util.logger_assert(
                    'Unknown object type to call turn_into_waldo_var on')
            #### END DEBUG
            
                
        return constructor(
            host_uuid,
            new_peered, # not peered
            val # used as initial value
            )
Beispiel #8
0
    def add_to_delta_list(
        self,delta_to_add_to,current_internal_val,action_event, for_map):
        '''
        @param {varStoreDeltas.SingleListDelta} delta_to_add_to ---

        @param {list} current_internal_val --- The internal val of the action event.

        @param {_InvalidationListener} action_event

        @param {bool} for_map --- True if performing operations for
        map.  false if performing for list.
        
        @returns {bool} --- Returns true if have any changes to add false otherwise.
        '''
        modified_indices = {}

        changes_made = False

        # FIXME: only need to keep track of change log for peered
        # variables.  May be expensive to otherwise.
        for partner_change in self.partner_change_log:
            changes_made = True

            # FIXME: no need to transmit overwrites.  but am doing
            # that currently.
            if for_map:
                action = delta_to_add_to.map_actions.add()                
            else:
                action = delta_to_add_to.list_actions.add()

            if is_delete_key_tuple(partner_change):
                action.container_action = VarStoreDeltas.ContainerAction.DELETE_KEY
                delete_action = action.deleted_key
                key = partner_change[1]
                modified_indices[key] = True
                if isinstance(key,numbers.Number):
                    delete_action.deleted_key_num = key
                elif util.is_string(key):
                    delete_action.deleted_key_text = key
                elif isinstance(key,bool):
                    delete_action.deleted_key_tf = key
                #### DEBUG
                else:
                    util.logger_assert('Unknown map key type when serializing')
                #### END DEBUG


            elif is_add_key_tuple(partner_change):
                key = partner_change[1]
                modified_indices[key] = True

                key_in_internal = key < len(current_internal_val)
                if for_map:
                    key_in_internal = (key in current_internal_val)

                if key_in_internal:
                    # note, key may not be in internal val, for
                    # instance if we had deleted it after adding.
                    # in this case, can ignore the add here.

                    action.container_action = VarStoreDeltas.ContainerAction.ADD_KEY
                    add_action = action.added_key
                    add_action.parent_type = VarStoreDeltas.CONTAINER_ADDED

                    if isinstance(key,numbers.Number):
                        add_action.added_key_num = key
                    elif util.is_string(key):
                        add_action.added_key_text = key
                    elif isinstance(key,bool):
                        add_action.added_key_tf = key
                    #### DEBUG
                    else:
                        util.logger_assert('Unknown map key type when serializing')
                    #### END DEBUG

                    # now actually add the value to the map
                    list_val = current_internal_val[key]

                    if isinstance(list_val,numbers.Number):
                        add_action.added_what_num = list_val
                    elif util.is_string(list_val):
                        add_action.added_what_text = list_val
                    elif isinstance(list_val,bool):
                        add_action.added_what_tf = list_val

                    elif isinstance(list_val,WaldoLockedObj):
                        list_val.serializable_var_tuple_for_network(
                            add_action,'',action_event,
                            # true here because if anything is written
                            # or added, then we must force the entire
                            # copy of it.
                            True)
                    #### DEBUG
                    else:
                        util.logger_assert(
                            'Unkonw type to serialize')
                    #### END DEBUG


            elif is_write_key_tuple(partner_change):
                key = partner_change[1]
                modified_indices[key] = True

                key_in_internal = key < len(current_internal_val)
                if for_map:
                    key_in_internal = (key in current_internal_val)

                if key_in_internal:
                    action.container_action = VarStoreDeltas.ContainerAction.WRITE_VALUE
                    write_action = action.write_key

                    write_action.parent_type = VarStoreDeltas.CONTAINER_WRITTEN

                    if isinstance(key,numbers.Number):
                        write_action.write_key_num = key
                    elif util.is_string(key):
                        write_action.write_key_text = key
                    elif isinstance(key,bool):
                        write_action.write_key_tf = key
                    #### DEBUG
                    else:
                        util.logger_assert('Unknown map key type when serializing')
                    #### END DEBUG


                    list_val = current_internal_val[key]
                    if isinstance(list_val,numbers.Number):
                        write_action.what_written_num = list_val
                    elif util.is_string(list_val):
                        write_action.what_written_text = list_val
                    elif isinstance(list_val,bool):
                        write_action.what_written_tf = list_val
                    else:
                        list_val.serializable_var_tuple_for_network(
                            write_action,'',action_event,
                            # true here because if anything is written
                            # or added, then we must force the entire
                            # copy of it.
                            True)

            #### DEBUG
            else:
                util.logger_assert('Unknown container operation')
            #### END DEBUG

        if for_map:
            to_iter_over = current_internal_val.keys()
        else:
            to_iter_over = range(0,len(current_internal_val))


        for index in to_iter_over:
            list_val = current_internal_val[index]

            if not isinstance(list_val,WaldoLockedObj):
                break

            if index not in modified_indices:
                # create action
                sub_element_action = delta_to_add_to.sub_element_update_actions.add()
                sub_element_action.parent_type = VarStoreDeltas.SUB_ELEMENT_ACTION

                if isinstance(index,numbers.Number):
                    sub_element_action.key_num = index
                elif util.is_string(index):
                    sub_element_action.key_text = index
                else:
                    sub_element_action.key_tf = index


                if list_val.serializable_var_tuple_for_network(sub_element_action,'',action_event,False):
                    changes_made = True
                else:
                    # no change made to subtree: go ahead and delete added subaction
                    del delta_to_add_to.sub_element_update_actions[-1]


        # clean out change log: do not need to re-send updates for
        # these changes to partner, so can just reset after sending
        # once.
        self.partner_change_log = []
        return changes_made
def value_variable_py_val_serialize(value_variable,parent,var_data,var_name):
    '''
    @param {} parent --- Either a ContainerAction a VarStoreDeltas.

    FIXME: unclear if actually need var_name for all elements
    py_serialize-ing, or just py variables that are in the
    top-level.

    @returns {bool} --- True if var_data was a python value type
    and we put it into parent.  False otherwise.

    If is python value type, then adds a delta message to
    parent.  Otherwise, does nothing.
    '''
    is_value_type = False
    delta = None
    if isinstance(var_data, numbers.Number):
        # can only add a pure number to var store a holder or to
        # an added key
        if parent.parent_type == VarStoreDeltas.VAR_STORE_DELTA:
            delta = parent.num_deltas.add()
        elif parent.parent_type == VarStoreDeltas.CONTAINER_ADDED:
            parent.added_what_num = var_data
        elif parent.parent_type == VarStoreDeltas.CONTAINER_WRITTEN:
            parent.what_written_num = var_data
        #### DEBUG
        else:
            util.logger_assert('Unexpected parent type in py_serialize')
        #### END DEBUG

        is_value_type = True

    elif util.is_string(var_data):
        if parent.parent_type == VarStoreDeltas.VAR_STORE_DELTA:
            delta = parent.text_deltas.add()
        elif parent.parent_type == VarStoreDeltas.CONTAINER_ADDED:
            parent.added_what_text = var_data
        elif parent.parent_type == VarStoreDeltas.CONTAINER_WRITTEN:
            parent.what_written_text = var_data

        #### DEBUG
        else:
            util.logger_assert('Unexpected parent type in py_serialize')
        #### END DEBUG                

        is_value_type = True

    elif isinstance(var_data,bool):
        if parent.parent_type == VarStoreDeltas.VAR_STORE_DELTA:
            delta = parent.true_false_deltas.add()
        elif parent.parent_type == VarStoreDeltas.CONTAINER_ADDED:
            parent.added_what_tf = var_data
        elif parent.parent_type == VarStoreDeltas.CONTAINER_WRITTEN:
            parent.what_written_tf = var_data                
        #### DEBUG
        else:
            util.logger_assert('Unexpected parent type in py_serialize')
        #### END DEBUG                

        is_value_type = True

    if delta != None:
        # all value types have same format
        delta.var_name = var_name
        delta.var_data = var_data

    return is_value_type