o
    `fV                     @   s6   d dl Z G dd dZG dd dZG dd dZdS )    Nc                   @   s   e Zd ZdZdd ZdS )ProfileStatszB
    ProfileStats, runtime execution statistics of operation.
    c                 C   s   || _ || _d S N)records_producedexecution_time)selfr   r    r   \/home/ubuntu/webapp/venv/lib/python3.10/site-packages/redis/commands/graph/execution_plan.py__init__	   s   
zProfileStats.__init__N)__name__
__module____qualname____doc__r	   r   r   r   r   r      s    r   c                   @   sJ   e Zd ZdZdddZdd Zdd Zd	ed
efddZ	d
e
fddZdS )	Operationz<
    Operation, single operation within execution plan.
    Nc                 C   s   || _ || _|| _g | _dS )z
        Create a new operation.

        Args:
            name: string that represents the name of the operation
            args: operation arguments
            profile_stats: profile statistics
        N)nameargsprofile_statschildren)r   r   r   r   r   r   r   r	      s   	
zOperation.__init__c                 C   s*   t |tr	| |u rtd| j| | S )Nzchild must be Operation)
isinstancer   	Exceptionr   append)r   childr   r   r   append_child!   s   zOperation.append_childc                 C   s
   t | jS r   lenr   )r   r   r   r   child_count(   s   
zOperation.child_countoreturnc                 C   s&   t |tsdS | j|jko| j|jkS )NF)r   r   r   r   )r   r   r   r   r   __eq__+   s   
zOperation.__eq__c                 C   s&   | j d u rdnd| j  }| j | S )N z | )r   r   )r   args_strr   r   r   __str__1   s   zOperation.__str__)NN)r
   r   r   r   r	   r   r   objectboolr   strr    r   r   r   r   r      s    
r   c                   @   sP   e Zd ZdZdd Zdd ZdefddZd	ede	fd
dZ
dd Zdd ZdS )ExecutionPlanz2
    ExecutionPlan, collection of operations.
    c                 C   sB   t |ts	tdt |d trdd |D }|| _|  | _dS )z
        Create a new execution plan.

        Args:
            plan: array of strings that represents the collection operations
                  the output from GRAPH.EXPLAIN
        zplan must be an arrayr   c                 S   s   g | ]}|  qS r   )decode).0br   r   r   
<listcomp>G   s    z*ExecutionPlan.__init__.<locals>.<listcomp>N)r   listr   bytesplan_operation_treestructured_plan)r   r+   r   r   r   r	   ;   s   
zExecutionPlan.__init__c                 C   sT   ||krdS |  |  krdS t|  D ]}| |j| |j| s' dS qdS )z{
        Compare execution plan operation tree

        Return: True if operation trees are equal, False otherwise
        FT)r   range_compare_operationsr   )r   root_aroot_bir   r   r   r/   L   s   z!ExecutionPlan._compare_operationsr   c                 C   s"   dd }dd }|  | jt||S )Nc                 S   s   d dd | D S )N
c                 S   s"   g | ]}|  D ]}d | qqS )    )
splitlines)r&   	str_childliner   r   r   r(   e   s    z?ExecutionPlan.__str__.<locals>.aggraget_str.<locals>.<listcomp>)join)str_childrenr   r   r   aggraget_strc   s
   z+ExecutionPlan.__str__.<locals>.aggraget_strc                 S   s   |  d| S )Nr3   r   )xyr   r   r   combine_strl   s   z*ExecutionPlan.__str__.<locals>.combine_str)_operation_traverser-   r#   )r   r:   r=   r   r   r   r    b   s
   	
zExecutionPlan.__str__r   c                 C   s&   t |tsdS | j}|j}| ||S )zfCompares two execution plans

        Return: True if the two plans are equal False otherwise
        F)r   r$   r-   r/   )r   r   r0   r1   r   r   r   r   s   s
   
zExecutionPlan.__eq__c                    sB   |}t |jdkr|S  fdd|jD }| |S )aq  
        Traverse operation tree recursively applying functions

        Args:
            op: operation to traverse
            op_f: function applied for each operation
            aggregate_f: aggregation function applied for all children of a single operation
            combine_f: combine function applied for the operation result and the children result
        r   c                    s   g | ]
} | qS r   )r>   )r&   r   aggregate_f	combine_fop_fr   r   r   r(      s    z5ExecutionPlan._operation_traverse.<locals>.<listcomp>r   )r   oprB   r@   rA   op_resr   r   r?   r   r>      s   z!ExecutionPlan._operation_traversec                 C   s
  d}d}g }d}dd }|t | jk r| j| }|d}||kr:||d}|r3| }|| |}|d7 }n@||d kr\||d}|| || |}|d7 }|d7 }n||k rv|| d }	t|	D ]}
| }qj||	8 }ntd|t | jk s|d S )	z7Build the operation tree from the string representationr   Nc                 S   s   d }| d   }| d t| dkr=d| d v r=ttd| d d}ttd| d d}t||}| d t	|t| dkrId |S | d   |S )Nr   zRecords producedzRecords produced: (\d+)   zExecution time: (\d+.\d+) ms)
strippopr   intresearchgroupfloatr   r   )r   r   r   r   r   r   r   r   _create_operation   s"   


z8ExecutionPlan._operation_tree.<locals>._create_operationr4   |rF   zcorrupted plan)	r   r+   countsplitrH   r   r   r.   r   )r   r2   levelstackcurrentrN   
current_opop_levelr   levels_back_r   r   r   r,      s<   








zExecutionPlan._operation_treeN)r
   r   r   r   r	   r/   r#   r    r!   r"   r   r>   r,   r   r   r   r   r$   6   s    r$   )rJ   r   r   r$   r   r   r   r   <module>   s    
(