o
    $i                     @   sJ   d dl Z d dlmZmZ G dd dZG dd deZG dd deZdS )	    N)AnyOptionalc                   @   s   e Zd ZdZ	ddededee fddZdd	ed
ee defddZdede	ddfddZ
dedefddZdd Zdd ZdS )SegmentTreeam  A Segment Tree data structure.

    https://en.wikipedia.org/wiki/Segment_tree

    Can be used as regular array, but with two important differences:

      a) Setting an item's value is slightly slower. It is O(lg capacity),
         instead of O(1).
      b) Offers efficient `reduce` operation which reduces the tree's values
         over some specified contiguous subsequence of items in the array.
         Operation could be e.g. min/max/sum.

    The data is stored in a list, where the length is 2 * capacity.
    The second half of the list stores the actual values for each index, so if
    capacity=8, values are stored at indices 8 to 15. The first half of the
    array contains the reduced-values of the different (binary divided)
    segments, e.g. (capacity=4):
    0=not used
    1=reduced-value over all elements (array indices 4 to 7).
    2=reduced-value over array indices (4 and 5).
    3=reduced-value over array indices (6 and 7).
    4-7: values of the tree.
    NOTE that the values of the tree are accessed by indices starting at 0, so
    `tree[0]` accesses `internal_array[4]` in the above example.
    Ncapacity	operationneutral_elementc                    s   |dkr||d @ dksJ d| _ |du r*|tju rdn|tu r&tdntd}| _ fdd	td
| D  _| _dS )a>  Initializes a Segment Tree object.

        Args:
            capacity: Total size of the array - must be a power of two.
            operation: Lambda obj, obj -> obj
                The operation for combining elements (eg. sum, max).
                Must be a mathematical group together with the set of
                possible values for array elements.
            neutral_element (Optional[obj]): The neutral element for
                `operation`. Use None for automatically finding a value:
                max: float("-inf"), min: float("inf"), sum: 0.0.
        r      z+Capacity must be positive and a power of 2!Ng        z-infinfc                    s   g | ]} j qS  )r   ).0_selfr
   ]/home/ubuntu/veenaModal/venv/lib/python3.10/site-packages/ray/rllib/execution/segment_tree.py
<listcomp>=   s    z(SegmentTree.__init__.<locals>.<listcomp>   )	r   operatoraddmaxfloatr   rangevaluer   )r   r   r   r   r
   r   r   __init__    s   

zSegmentTree.__init__r   startendreturnc                 C   s   |du r| j }n	|dk r|| j 7 }| j}|| j 7 }|| j 7 }||k rP|d@ r3| || j| }|d7 }|d@ rD|d8 }| || j| }|d }|d }||k s"|S )a  Applies `self.operation` to subsequence of our values.

        Subsequence is contiguous, includes `start` and excludes `end`.

          self.operation(
              arr[start], operation(arr[start+1], operation(... arr[end])))

        Args:
            start: Start index to apply reduction to.
            end (Optional[int]): End index to apply reduction to (excluded).

        Returns:
            any: The result of reducing self.operation over the specified
                range of `self._value` elements.
        Nr   r   r   )r   r   r   r   )r   r   r   resultr
   r
   r   reduce@   s$   


zSegmentTree.reduceidxvalc                 C   s   d|  kr| j k sn J d| d| j  || j 7 }|| j|< |d? }|dkrHd| }| | j| | j|d  | j|< |d? }|dks)dS dS )z
        Inserts/overwrites a value in/into the tree.

        Args:
            idx: The index to insert to. Must be in [0, `self.capacity`)
            val: The value to insert.
        r   zidx=z
 capacity=r   r   N)r   r   r   )r   r   r   
update_idxr
   r
   r   __setitem__   s   .


zSegmentTree.__setitem__c                 C   s.   d|  kr| j k sJ  J | j|| j   S )Nr   )r   r   )r   r   r
   r
   r   __getitem__   s   zSegmentTree.__getitem__c                 C   s   | j S N)r   r   r
   r
   r   	get_state   s   zSegmentTree.get_statec                 C   s    t || jd ksJ || _d S )Nr   )lenr   r   )r   stater
   r
   r   	set_state   s   
zSegmentTree.set_stater#   r   N)__name__
__module____qualname____doc__intr   r   r   r   r   r!   r"   r$   r'   r
   r
   r
   r   r      s    
 Fr   c                       sT   e Zd ZdZdef fddZddedee d	efd
dZde	d	efddZ
  ZS )SumSegmentTreez:A SegmentTree with the reduction `operation`=operator.add.r   c                    s   t t| j|tjd d S N)r   r   )superr.   r   r   r   r   r   	__class__r
   r   r      s   zSumSegmentTree.__init__r   Nr   r   r   c                 C      |  ||S )z/Returns the sum over a sub-segment of the tree.r   r   r   r   r
   r
   r   sum      zSumSegmentTree.sum	prefixsumc                 C   s   d|  kr|   d ksJ  J d}|| j| kr"| j| d }|| jk rEd| }| j| |kr5|}n|| j| 8 }|d }|| jk s'|| j S )zFinds highest i, for which: sum(arr[0]+..+arr[i - i]) <= prefixsum.

        Args:
            prefixsum: `prefixsum` upper bound in above constraint.

        Returns:
            int: Largest possible index (i) satisfying above constraint.
        r   gh㈵>r   r   )r7   r   r   )r   r9   r   r    r
   r
   r   find_prefixsum_idx   s   $	


z!SumSegmentTree.find_prefixsum_idxr(   )r)   r*   r+   r,   r-   r   r   r   r7   r   r:   __classcell__r
   r
   r2   r   r.      s
    r.   c                       s>   e Zd Zdef fddZddedee defd	d
Z  ZS )MinSegmentTreer   c                    s   t t| j|td d S r/   )r0   r<   r   minr1   r2   r
   r   r      s   zMinSegmentTree.__init__r   Nr   r   r   c                 C   r4   )z'Returns min(arr[start], ...,  arr[end])r5   r6   r
   r
   r   r=      r8   zMinSegmentTree.minr(   )	r)   r*   r+   r-   r   r   r   r=   r;   r
   r
   r2   r   r<      s    $r<   )r   typingr   r   r   r.   r<   r
   r
   r
   r   <module>   s     ('