B
    q\K                 @   s   d dl Z d dlZG dd dZG dd dZG dd dZG dd	 d	ZG d
d dZG dd dZy4d dl	m
Z
mZ G dd deZG dd deZW n ek
r   eZeZY nX dS )    Nc               @   sD   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZeZeZeZ	dS )MaxValuezL
    Represents an infinite value for purposes
    of tuple comparison.
    c             C   s   dS )NT )selfotherr   r   0lib/python3.7/site-packages/astropy/table/bst.py__gt__   s    zMaxValue.__gt__c             C   s   dS )NTr   )r   r   r   r   r   __ge__   s    zMaxValue.__ge__c             C   s   dS )NFr   )r   r   r   r   r   __lt__   s    zMaxValue.__lt__c             C   s   dS )NFr   )r   r   r   r   r   __le__   s    zMaxValue.__le__c             C   s   dS )NMAXr   )r   r   r   r   __repr__   s    zMaxValue.__repr__N)
__name__
__module____qualname____doc__r   r   r	   r
   r   __str__r   r   r   r   r      s   r   c               @   sD   e Zd ZdZdd Zdd Zdd Zdd	 Zd
d ZeZeZeZ	dS )MinValuezS
    The opposite of MaxValue, i.e. a representation of
    negative infinity.
    c             C   s   dS )NTr   )r   r   r   r   r   r	   &   s    zMinValue.__lt__c             C   s   dS )NTr   )r   r   r   r   r   r
   )   s    zMinValue.__le__c             C   s   dS )NFr   )r   r   r   r   r   r   ,   s    zMinValue.__gt__c             C   s   dS )NFr   )r   r   r   r   r   r   /   s    zMinValue.__ge__c             C   s   dS )NZMINr   )r   r   r   r   r   2   s    zMinValue.__repr__N)
r   r   r   r   r	   r
   r   r   r   r   r   r   r   r   r       s   r   c               @   s<   e Zd ZdZdZdd Zdd Zdd Zd	d
 Zdd Z	dS )Epsilona
  
    Represents the "next largest" version of a given value,
    so that for all valid comparisons we have
    x < y < Epsilon(y) < z whenever x < y < z and x, z are
    not Epsilon objects.

    Parameters
    ----------
    val : object
        Original value
    )valc             C   s
   || _ d S )N)r   )r   r   r   r   r   __init__H   s    zEpsilon.__init__c             C   s   | j |krdS | j |k S )NF)r   )r   r   r   r   r   r	   K   s    
zEpsilon.__lt__c             C   s   | j |krdS | j |kS )NT)r   )r   r   r   r   r   r   P   s    
zEpsilon.__gt__c             C   s   dS )NFr   )r   r   r   r   r   __eq__U   s    zEpsilon.__eq__c             C   s   t | jd S )Nz
 + epsilon)reprr   )r   r   r   r   r   X   s    zEpsilon.__repr__N)
r   r   r   r   	__slots__r   r	   r   r   r   r   r   r   r   r   :   s   r   c               @   st   e Zd ZdZdd Zdd Zdd Zdd Zdd Zdd Z	d	Z
d
d Zdd Zdd Zdd Zdd Zdd ZdS )Nodez
    An element in a binary search tree, containing
    a key, data, and references to children nodes and
    a parent node.

    Parameters
    ----------
    key : tuple
        Node key
    data : list or int
        Node data
    c             C   s   | j |j k S )N)key)xyr   r   r   <lambda>i   s    zNode.<lambda>c             C   s   | j |j kS )N)r   )r   r   r   r   r   r   j   s    c             C   s   | j |j kS )N)r   )r   r   r   r   r   r   k   s    c             C   s   | j |j kS )N)r   )r   r   r   r   r   r   l   s    c             C   s   | j |j kS )N)r   )r   r   r   r   r   r   m   s    c             C   s   | j |j kS )N)r   )r   r   r   r   r   r   n   s    )r   dataleftrightc             C   s,   || _ t|tr|n|g| _d | _d | _d S )N)r   
isinstancelistr   r   r    )r   r   r   r   r   r   r   r   s    zNode.__init__c             C   sD   | j dk	r| j |kr|| _ n$| jdk	r8| j|kr8|| _ntddS )z=
        Replace this node's child with a new child.
        Nz"Cannot call replace() on non-child)r   r    
ValueError)r   child	new_childr   r   r   replacex   s
    zNode.replacec             C   s   |  |d dS )z)
        Remove the given child.
        N)r&   )r   r$   r   r   r   remove   s    zNode.removec             C   s   |j | _ |jdd | _dS )z&
        Copy the given node.
        N)r   r   )r   r   r   r   r   set   s    zNode.setc             C   s   t | j| jfS )N)strr   r   )r   r   r   r   r      s    zNode.__str__c             C   s   t | S )N)r)   )r   r   r   r   r      s    zNode.__repr__N)r   r   r   r   r	   r
   r   r   r   __ne__r   r   r&   r'   r(   r   r   r   r   r   r   r   \   s   r   c               @   s  e Zd ZdZeZd@ddZdAddZdd	 Zd
d Z	dd Z
dd Zdd ZdBddZdd Zdd Zdd Zdd Zdd Zdd  Zd!d" ZdCd#d$Zd%d& Zd'd( ZdDd*d+ZdEd,d-Zd.d/ Zd0d1 Zd2d3 Zd4d5 Zd6d7 Zd8d9 Ze d:d; Z!d<d= Z"d>d? Z#dS )FBSTab  
    A basic binary search tree in pure Python, used
    as an engine for indexing.

    Parameters
    ----------
    data : Table
        Sorted columns of the original table
    row_index : Column object
        Row numbers corresponding to data columns
    unique : bool (defaults to False)
        Whether the values of the index must be unique
    Fc             C   s>   d | _ d| _|| _x&t||D ]\}}| t|| qW d S )Nr   )rootsizeuniquezipaddtuple)r   r   	row_indexr.   r   rowr   r   r   r      s
    zBST.__init__Nc             C   s   |dkr|}|  j d7  _ | ||}| j}|dkr>|| _dS xv||k rb|jdkrZ||_P |j}q@||kr|jdkr|||_P |j}q@| jrtdq@|j|j t	|j|_dS q@W dS )z'
        Add a key, data pair.
        N   zCannot insert non-unique value)
r-   	NodeClassr,   r   r    r.   r#   r   extendsorted)r   r   r   node	curr_noder   r   r   r0      s0    


zBST.addc             C   s    |  |\}}|dk	r|jS g S )a	  
        Return all data values corresponding to a given key.

        Parameters
        ----------
        key : tuple
            Input key

        Returns
        -------
        data_vals : list
            List of rows corresponding to the input key
        N)	find_noder   )r   r   r8   parentr   r   r   find   s    zBST.findc             C   s   | j dkrdS | || j dS )z>
        Find the node associated with the given key.
        N)NN)r,   _find_recursive)r   r   r   r   r   r:      s    
zBST.find_nodec                s,   x&|   D ]} fdd|jD |_q
W dS )z?
        Decrement all rows larger than the given row.
        c                s    g | ]}| kr|d  n|qS )r4   r   ).0r   )r3   r   r   
<listcomp>   s    z"BST.shift_left.<locals>.<listcomp>N)traverser   )r   r3   r8   r   )r3   r   
shift_left   s    zBST.shift_leftc                s,   x&|   D ]} fdd|jD |_q
W dS )zL
        Increment all rows greater than or equal to the given row.
        c                s    g | ]}| kr|d  n|qS )r4   r   )r>   r   )r3   r   r   r?      s    z#BST.shift_right.<locals>.<listcomp>N)r@   r   )r   r3   r8   r   )r3   r   shift_right   s    zBST.shift_rightc             C   sv   y\||j kr||fS ||j kr<|jd kr,dS | ||j|S |jd krJdS | ||j|S W n tk
rp   dS X d S )N)NN)r   r    r=   r   	TypeError)r   r   r8   r;   r   r   r   r=      s    



zBST._find_recursiveinorderc             C   sT   |dkr|  | jg S |dkr,| | jg S |dkrB| | jg S td|dS )a  
        Return nodes of the BST in the given order.

        Parameters
        ----------
        order : str
            The order in which to recursively search the BST.
            Possible values are:
            "preorder": current node, left subtree, right subtree
            "inorder": left subtree, current node, right subtree
            "postorder": left subtree, right subtree, current node
        ZpreorderrD   Z	postorderzInvalid traversal method: "{0}"N)	_preorderr,   _inorder
_postorderr#   format)r   orderr   r   r   r@     s    zBST.traversec             C   s   dd |   D S )zA
        Return BST items in order as (key, data) pairs.
        c             S   s   g | ]}|j |jfqS r   )r   r   )r>   r   r   r   r   r?     s    zBST.items.<locals>.<listcomp>)r@   )r   r   r   r   items  s    z	BST.itemsc             C   sF   d}x<|   D ]0}t|j}dd t||| D |_||7 }qW dS )z6
        Make row order align with key order.
        r   c             S   s   g | ]}|qS r   r   )r>   r   r   r   r   r?   %  s    zBST.sort.<locals>.<listcomp>N)r@   lenr   range)r   ir8   num_rowsr   r   r   sort  s
    
zBST.sortc             C   s   dd |   D S )z7
        Return BST rows sorted by key values.
        c             S   s   g | ]}|j D ]}|qqS r   )r   )r>   r8   r   r   r   r   r?   ,  s    z#BST.sorted_data.<locals>.<listcomp>)r@   )r   r   r   r   sorted_data(  s    zBST.sorted_datac             C   s6   |d kr|S | | | |j| | |j| |S )N)appendrE   r   r    )r   r8   lstr   r   r   rE   .  s    
zBST._preorderc             C   s6   |d kr|S |  |j| || |  |j| |S )N)rF   r   rQ   r    )r   r8   rR   r   r   r   rF   6  s    
zBST._inorderc             C   s6   |d kr|S |  |j| |  |j| || |S )N)rG   r   r    rQ   )r   r8   rR   r   r   r   rG   >  s    
zBST._postorderc             C   s"   || j kr|| _ n||| d S )N)r,   r&   )r   r8   r;   Znew_noder   r   r   _substituteF  s    
zBST._substitutec             C   s  |  |\}}|dkrdS |dk	rT||jkr6tdnt|jdkrT|j| dS |jdkrx|jdkrx| ||d n|jdkr|jdk	r| |||j nd|jdkr|jdk	r| |||j n>|j}|}x|jdk	r|}|j}qW | |||j || |  j	d8  _	dS )a  
        Remove data corresponding to the given key.

        Parameters
        ----------
        key : tuple
            The key to remove
        data : int or None
            If None, remove the node corresponding to the given key.
            If not None, remove only the given data value from the node.

        Returns
        -------
        successful : bool
            True if removal was successful, false otherwise
        NFz$Data does not belong to correct noder4   T)
r:   r   r#   rK   r'   r   r    rS   r(   r-   )r   r   r   r8   r;   r9   r   r   r   r'   L  s0    



z
BST.removec             C   s   |  | jS )z6
        Returns whether this is a valid BST.
        )	_is_validr,   )r   r   r   r   is_validx  s    zBST.is_validc             C   sL   |d krdS |j d ks |j |koJ|jd ks4|j|koJ| |j oJ| |jS )NT)r   r    rT   )r   r8   r   r   r   rT   ~  s
    zBST._is_validTTc             C   s   |  |||}dd |D S )a  
        Return all nodes with keys in the given range.

        Parameters
        ----------
        lower : tuple
            Lower bound
        upper : tuple
            Upper bound
        bounds : tuple (x, y) of bools
            Indicates whether the search should be inclusive or
            exclusive with respect to the endpoints. The first
            argument x corresponds to an inclusive lower bound,
            and the second argument y to an inclusive upper bound.
        c             S   s   g | ]}|j D ]}|qqS r   )r   )r>   r8   r   r   r   r   r?     s    zBST.range.<locals>.<listcomp>)range_nodes)r   lowerupperboundsnodesr   r   r   rL     s    z	BST.rangec             C   sL   | j dkrg S |d rtjntj}|d r0tjntj}| ||||| j g S )z2
        Return nodes in the given range.
        Nr   r4   )r,   operatorleltgegt_range)r   rX   rY   rZ   op1op2r   r   r   rW     s
    
zBST.range_nodesc             C   s,   | j dkrg S | || j g }dd |D S )z
        Assuming the given value has smaller length than keys, return
        nodes whose keys have this value as a prefix.
        Nc             S   s   g | ]}|j D ]}|qqS r   )r   )r>   r8   r   r   r   r   r?     s    z#BST.same_prefix.<locals>.<listcomp>)r,   _same_prefix)r   r   r[   r   r   r   same_prefix  s    
zBST.same_prefixc             C   sz   |||j r"|||j r"|| ||j krL|jd k	rL| |||||j| ||j k rv|jd k	rv| |||||j| |S )N)r   rQ   r    ra   r   )r   rX   rY   rb   rc   r8   rR   r   r   r   ra     s    
z
BST._rangec             C   sl   |j d t| }||kr$|| ||krF|jd k	rF| ||j| ||krh|jd k	rh| ||j| |S )N)r   rK   rQ   r    rd   r   )r   r   r8   rR   prefixr   r   r   rd     s    
zBST._same_prefixc             C   s   | j d krdS | | j dS )NZEmptyr   )r,   _print)r   r   r   r   r     s    
zBST.__str__c             C   s   t | S )N)r)   )r   r   r   r   r     s    zBST.__repr__c             C   sX   d| t | d }|jd k	r4|| |j|d 7 }|jd k	rT|| |j|d 7 }|S )N	
r4   )r)   r   rg   r    )r   r8   levelliner   r   r   rg     s    

z
BST._printc             C   s   |  | jS )z(
        Return the BST height.
        )_heightr,   )r   r   r   r   height  s    z
BST.heightc             C   s*   |d krdS t | |j| |jd S )Nr4   )maxrl   r   r    )r   r8   r   r   r   rl     s    zBST._heightc                s4   x.|   D ]"\}} fdd|D |dd< q
W dS )a)  
        Replace all rows with the values they map to in the
        given dictionary. Any rows not present as keys in
        the dictionary will have their nodes deleted.

        Parameters
        ----------
        row_map : dict
            Mapping of row numbers to new row numbers
        c                s   g | ]}| kr | qS r   r   )r>   r   )row_mapr   r   r?     s    z$BST.replace_rows.<locals>.<listcomp>N)rJ   )r   rp   r   r   r   )rp   r   replace_rows  s    zBST.replace_rows)F)N)rD   )N)rV   )rV   )$r   r   r   r   r   r5   r   r0   r<   r:   rA   rB   r=   r@   rJ   rO   rP   rE   rF   rG   rS   r'   rU   rT   rL   rW   re   ra   rd   r   r   rg   propertyrm   rl   rq   r   r   r   r   r+      s>   




,


	
r+   c               @   s   e Zd ZdZd!ddZdd Zdd Zd"d
dZdd Zdd Z	dd Z
dd Zdd Zdd Zd#ddZdd Zdd Zdd  Zd	S )$FastBaseaj  
    A fast binary search tree implementation for indexing,
    using the bintrees library.

    Parameters
    ----------
    data : Table
        Sorted columns of the original table
    row_index : Column object
        Row numbers corresponding to data columns
    unique : bool (defaults to False)
        Whether the values of the index must be unique
    Fc             C   s<   |   | _|| _x&t||D ]\}}| t|| qW d S )N)enginer   r.   r/   r0   r1   )r   r   r2   r.   r   r3   r   r   r   r     s    
zFastBase.__init__c             C   sP   | j r*|| jkrtd||| j|< n"| j|g }|t||| dS )z(
        Add a key, value pair.
        z2Cannot add duplicate value "{0}" in a unique indexN)r.   r   r#   rH   Zset_defaultinsertnpZsearchsorted)r   r   r   rowsr   r   r   r0     s    
zFastBase.addc             C   s   | j |g }| jr|g}|S )z;
        Find rows corresponding to the given key.
        )r   getr.   )r   r   rw   r   r   r   r<     s    zFastBase.findNc             C   s   | j r.y| j| W q tk
r*   dS X nh| j|d}|dksPt|dkrTdS |dkrl| j| dS ||krt|dkrdS td|| dS )z1
        Remove data from the given key.
        FNr   Tz$Data does not belong to correct node)r.   r   popKeyErrorrx   rK   r#   r'   )r   r   r   r8   r   r   r   r'     s"    
zFastBase.removec                sj   | j r6x^| j D ]\}}| kr|d | j|< qW n0x.| j D ] \}} fdd|D | j|< qBW dS )z;
        Decrement rows larger than the given row.
        r4   c                s    g | ]}| kr|d  n|qS )r4   r   )r>   r   )r3   r   r   r?   ;  s    z'FastBase.shift_left.<locals>.<listcomp>N)r.   r   rJ   )r   r3   r   r   r8   r   )r3   r   rA   1  s    zFastBase.shift_leftc                sj   | j r6x^| j D ]\}}| kr|d | j|< qW n0x.| j D ] \}} fdd|D | j|< qBW dS )zH
        Increment rows greater than or equal to the given row.
        r4   c                s    g | ]}| kr|d  n|qS )r4   r   )r>   r   )r3   r   r   r?   G  s    z(FastBase.shift_right.<locals>.<listcomp>N)r.   r   rJ   )r   r3   r   r   r8   r   )r3   r   rB   =  s    zFastBase.shift_rightc             C   s:   g }x0| j  D ]"\}}t||}||_ || qW |S )z/
        Return all nodes in this BST.
        )r   rJ   r   rQ   )r   lr   r   nr   r   r   r@   I  s    
zFastBase.traversec             C   s$   | j r| j S dd | j D S )z4
        Return a list of key, data tuples.
        c             S   s    g | ]}t |d  dkr|qS )r4   r   )rK   )r>   r   r   r   r   r?   Z  s    z"FastBase.items.<locals>.<listcomp>)r.   r   rJ   )r   r   r   r   rJ   T  s    
zFastBase.itemsc             C   s   | j r2xtt| j D ]\}\}}|| j|< qW nJd}xD| j D ]6\}}t|}dd t||| D | j|< ||7 }qBW dS )z6
        Make row order align with key order.
        r   c             S   s   g | ]}|qS r   r   )r>   r   r   r   r   r?   g  s    z!FastBase.sort.<locals>.<listcomp>N)r.   	enumerater   rJ   rK   rL   )r   rM   r   r3   rw   rN   r   r   r   rO   \  s    zFastBase.sortc             C   s.   | j rdd | j D S dd | j D S )z?
        Return a list of rows in order sorted by key.
        c             S   s   g | ]}|qS r   r   )r>   r   r   r   r   r?   o  s    z(FastBase.sorted_data.<locals>.<listcomp>c             S   s   g | ]}|D ]}|qqS r   r   )r>   r8   r   r   r   r   r?   p  s    )r.   r   values)r   r   r   r   rP   j  s    zFastBase.sorted_dataTTc             C   sP   |d st |}|d r t |}dd | j||D }| jrB|S dd |D S )z7
        Return row values in the given range.
        r   r4   c             S   s   g | ]}|qS r   r   )r>   vr   r   r   r?   }  s    z"FastBase.range.<locals>.<listcomp>c             S   s   g | ]}|D ]}|qqS r   r   )r>   Zsublistr   r   r   r   r?     s    )r   r   Zvalue_slicer.   )r   rX   rY   rZ   r{   r   r   r   rL   r  s    zFastBase.rangec                s   | j r`g }x8| j D ]*\}}| kr6 | | j|< q|| qW xH|D ]}| j| qJW n.x,| j D ]} fdd|D |dd< qlW dS )z:
        Replace rows with the values in row_map.
        c                s   g | ]}| kr | qS r   r   )r>   r   )rp   r   r   r?     s    z)FastBase.replace_rows.<locals>.<listcomp>N)r.   r   rJ   rQ   ry   r~   )r   rp   Zdel_keysr   r   r   )rp   r   rq     s    
zFastBase.replace_rowsc             C   s
   t | jS )N)r)   r   )r   r   r   r   r     s    zFastBase.__str__c             C   s   t | S )N)r)   )r   r   r   r   r     s    zFastBase.__repr__)F)N)r   )r   r   r   r   r   r0   r<   r'   rA   rB   r@   rJ   rO   rP   rL   rq   r   r   r   r   r   r   rs     s   



rs   )FastBinaryTree
FastRBTreec               @   s   e Zd ZeZdS )FastBSTN)r   r   r   r   rt   r   r   r   r   r     s   r   c               @   s   e Zd ZeZdS )FastRBTN)r   r   r   r   rt   r   r   r   r   r     s   r   )r\   Znumpyrv   r   r   r   r   r+   rs   Zbintreesr   r   r   r   ImportErrorr   r   r   r   <module>   s"   ";  W /