o
    ;hZ&                     @  s   d dl mZ d dlZd dlZd dlZd dlmZmZ d dlm	Z	 d dl
mZ d dlZd dlmZmZmZ d dlmZ G dd	 d	Zed
dG dd deeeeZdS )    )annotationsN)Counterdefaultdict)floor)versionadded)MovingWindowSupportSlidingWindowCounterSupportStorage)TimestampedSlidingWindowc                   @  s   e Zd ZdddZdS )	EntryexpiryintreturnNonec                 C  s   t   | _| j| | _d S N)timeatimer   )selfr    r   L/var/www/html/venv/lib/python3.10/site-packages/limits/aio/storage/memory.py__init__   s   
zEntry.__init__N)r   r   r   r   )__name__
__module____qualname__r   r   r   r   r   r      s    r   z2.1)versionc                      s   e Zd ZdZdgZ	 	dEdF fddZdGddZdHddZdIddZdIddZ	e
dJddZdKdLd"d#ZdKdMd$d%ZdNd&d'ZdOd(d)Z	dKdPd+d,ZdQd-d.ZdRd0d1Z	dKdPd2d3ZdSd5d6ZdTd7d8ZdUd<d=ZdVd>d?ZdWdAdBZdIdCdDZ  ZS )XMemoryStoragez
    rate limit storage using :class:`collections.Counter`
    as an in memory storage for fixed & sliding window strategies,
    and a simple list to implement moving window strategy.
    zasync+memoryNFuri
str | Nonewrap_exceptionsbool_strr   r   c                   sB   t  | _ttj| _i | _i | _d | _t	 j
|fd|i| d S )Nr   )r   storager   asyncioLocklocksexpirationseventstimersuperr   )r   r   r   r    	__class__r   r   r   *   s   zMemoryStorage.__init__dict[str, limits.typing.Any]c                 C  s   | j  }|d= |d= |S )Nr(   r%   )__dict__copyr   stater   r   r   __getstate__4   s   
zMemoryStorage.__getstate__r0   c                 C  s0   | j | d | _ttj| _t|   d S r   )	r-   updater(   r   r#   r$   r%   Zensure_future_MemoryStorage__schedule_expiryr/   r   r   r   __setstate__:   s   zMemoryStorage.__setstate__c              
     s:  zt    t| j D ]Y}t fdd| j| I d H }| j| 4 I d H 3 | j|g r<| j| d | | j|< | j|d sQ| j|d  | j|d  W d   I d H  n1 I d H saw   Y  qt| j	 D ] }| j	| t   kr| j
|d  | j	|d  | j|d  qnW d S  tjy   Y d S w )Nc                   s   t j|   dd dS )Nc                 S     | j  S r   )r   )eventr   r   r   <lambda>F       zAMemoryStorage.__expire_events.<locals>.<lambda>.<locals>.<lambda>key)bisectbisect_left)Zevtsnowr   r   r7   E   s    z/MemoryStorage.__expire_events.<locals>.<lambda>)r   listr'   keysr#   Z	to_threadr%   getpopr&   r"   ZCancelledError)r   r:   cutoffr   r=   r   Z__expire_events@   s6   

(zMemoryStorage.__expire_eventsc                   s*   | j r	| j  rt|  | _ d S d S r   )r(   doner#   Zcreate_task_MemoryStorage__expire_eventsr   r   r   r   Z__schedule_expiryY   s   zMemoryStorage.__schedule_expiry-type[Exception] | tuple[type[Exception], ...]c                 C  s   t S r   )
ValueErrorrF   r   r   r   base_exceptions]   s   zMemoryStorage.base_exceptions   r:   r   floatamountr   c              	     s   |  |I dH  |  I dH  | j| 4 I dH $ | j|  |7  < | j| |kr3t | | j|< W d  I dH  n1 I dH sCw   Y  | j ||S )z
        increments the counter for a given rate limit key

        :param key: the key to increment
        :param expiry: amount in seconds for the key to expire in
        :param amount: the number to increment by
        N)rA   r3   r%   r"   r   r&   )r   r:   r   rL   r   r   r   incrc   s   (zMemoryStorage.incrc              	     s   |  |I dH  |  I dH  | j| 4 I dH  t| j| | d| j|< W d  I dH  n1 I dH s7w   Y  | j ||S )z
        decrements the counter for a given rate limit key. 0 is the minimum allowed value.

        :param amount: the number to increment by
        Nr   )rA   r3   r%   maxr"   )r   r:   rL   r   r   r   decrs   s   (zMemoryStorage.decrc                   sP   | j |dt kr!| j|d | j |d | j|d | j|dS )zB
        :param key: the key to get the counter value for
        r   N)r&   rA   r   r"   rB   r%   r   r:   r   r   r   rA      s   zMemoryStorage.getc                   s>   | j |d | j|d | j|d | j|d dS )z>
        :param key: the key to clear rate limits for
        N)r"   rB   r&   r'   r%   rP   r   r   r   clear   s
   zMemoryStorage.clearlimitc              	     s   ||krdS |   I dH  | j| 4 I dH R | j|g  t }z| j| ||  }W n ty9   d}Y nw |rO|j|| krO	 W d  I dH  dS t|g| | j| dd< 	 W d  I dH  dS 1 I dH sow   Y  dS )z
        :param key: rate limit key to acquire an entry in
        :param limit: amount of entries allowed
        :param expiry: expiry of the entry
        :param amount: the number of entries to acquire
        FNr   T)r3   r%   r'   
setdefaultr   
IndexErrorr   r   )r   r:   rR   r   rL   	timestampentryr   r   r   acquire_entry   s$   	0zMemoryStorage.acquire_entryc                   s   | j |t S )z;
        :param key: the key to get the expiry for
        )r&   rA   r   rP   r   r   r   
get_expiry   s   zMemoryStorage.get_expirytuple[float, int]c                   sP   t   }| j|g  }r$tj|||  dd d}||d  j|fS |dfS )z
        returns the starting point and the number of entries in the moving
        window

        :param key: rate limit key
        :param expiry: expiry of entry
        :return: (start of window, number of acquired entries)
        c                 S  r5   r   )r   )rV   r   r   r   r7      r8   z1MemoryStorage.get_moving_window.<locals>.<lambda>r9   rJ   r   )r   r'   rA   r;   r<   r   )r   r:   rR   r   rU   r'   Zoldestr   r   r   get_moving_window   s   zMemoryStorage.get_moving_windowc                   s   ||krdS t   }| |||\}}| ||||I d H \}}	}
}||	 | |
 }t|| |kr5dS | j|d| |dI d H }
||	 | |
 }t||kr[| ||I d H  dS dS )NF   )rL   T)r   sliding_window_keys_get_sliding_window_infor   rM   rO   )r   r:   rR   r   rL   r>   previous_keycurrent_keyprevious_countprevious_ttlcurrent_countr    Zweighted_countr   r   r   acquire_sliding_window_entry   s(   z*MemoryStorage.acquire_sliding_window_entrytuple[int, float, int, float]c                   s2   t   }| |||\}}| ||||I d H S r   )r   r\   r]   r   r:   r   r>   r^   r_   r   r   r   get_sliding_window   s   
z MemoryStorage.get_sliding_windowc                   s@   t   }| |||\}}| |I d H  | |I d H  d S r   )r   r\   rQ   re   r   r   r   clear_sliding_window   s
   z"MemoryStorage.clear_sliding_windowr^   r_   r>   c           	        sp   |  |I d H }|  |I d H }|dkrtd}nd|| | d  | }d|| d  | | }||||fS )Nr   rJ   )rA   rK   )	r   r^   r_   r   r>   r`   rb   ra   Zcurrent_ttlr   r   r   r]      s   
z&MemoryStorage._get_sliding_window_infoc                   s   dS )z-
        check if storage is healthy
        Tr   rF   r   r   r   check
  s   zMemoryStorage.check
int | Nonec                   sD   t t| jt| j}| j  | j  | j  | j  |S r   )rN   lenr"   r'   rQ   r&   r%   )r   	num_itemsr   r   r   reset  s   



zMemoryStorage.resetc                 C  sB   z| j r| j  s| j   W d S W d S W d S  ty    Y d S w r   )r(   rD   cancelRuntimeErrorrF   r   r   r   __del__  s   zMemoryStorage.__del__)NF)r   r   r   r   r    r!   r   r   )r   r,   )r0   r,   r   r   )r   r   )r   rG   )rJ   )r:   r!   r   rK   rL   r   r   r   )r:   r!   rL   r   r   r   )r:   r!   r   r   )r:   r!   r   r   )
r:   r!   rR   r   r   r   rL   r   r   r   )r:   r!   r   rK   )r:   r!   rR   r   r   r   r   rY   )r:   r!   r   r   r   rd   )r:   r!   r   r   r   r   )
r^   r!   r_   r!   r   r   r>   rK   r   rd   )r   r   )r   ri   )r   r   r   __doc__ZSTORAGE_SCHEMEr   r1   r4   rE   r3   propertyrI   rM   rO   rA   rQ   rW   rX   rZ   rc   rf   rg   r]   rh   rl   ro   __classcell__r   r   r*   r   r      s8    










!
	


	r   )
__future__r   r#   r;   r   collectionsr   r   mathr   Zdeprecated.sphinxr   Zlimits.typingZlimitsZlimits.aio.storage.baser   r   r	   Zlimits.storage.baser
   r   r   r   r   r   r   <module>   s    

