o
    ú•;hý"  ã                   @  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
Zd dlmZmZmZmZ G dd„ dƒZG dd	„ d	eeeeƒZdS )
é    )ÚannotationsN)ÚCounterÚdefaultdict)Úfloor)ÚMovingWindowSupportÚSlidingWindowCounterSupportÚStorageÚTimestampedSlidingWindowc                   @  s   e Zd Zddd„ZdS )	ÚEntryÚexpiryÚfloatÚreturnÚNonec                 C  s   t   ¡ | _| j| | _d S ©N)ÚtimeÚatimer   )Úselfr   © r   úH/var/www/html/venv/lib/python3.10/site-packages/limits/storage/memory.pyÚ__init__   s   
zEntry.__init__N)r   r   r   r   )Ú__name__Ú
__module__Ú__qualname__r   r   r   r   r   r
      s    r
   c                      sì   e Zd ZdZdgZdCdD‡ fdd„ZdEdd„ZdFdd„ZdGdd„ZdGdd„Z	e
dHdd„ƒZdIdJd"d#„ZdIdKd$d%„ZdLd&d'„ZdMd(d)„ZdIdNd+d,„ZdOd-d.„ZdPd0d1„Z	dIdNd2d3„ZdQd8d9„ZdRd:d;„ZdSd<d=„ZdTd>d?„ZdUdAdB„Z‡  ZS )VÚMemoryStoragezÀ
    rate limit storage using :class:`collections.Counter`
    as an in memory storage for fixed and sliding window strategies,
    and a simple list to implement moving window strategy.

    ZmemoryNFÚuriú
str | NoneÚwrap_exceptionsÚboolÚ_Ústrc                   sV   t ƒ | _ttjƒ| _i | _i | _t d| j	¡| _
| j
 ¡  tƒ j|fd|i|¤Ž d S )Nç{®Gáz„?r   )r   Ústorager   Ú	threadingÚRLockÚlocksÚexpirationsÚeventsÚTimerÚ_MemoryStorage__expire_eventsÚtimerÚstartÚsuperr   )r   r   r   r   ©Ú	__class__r   r   r   $   s   
zMemoryStorage.__init__r   údict[str, limits.typing.Any]c                 C  s   | j  ¡ }|d= |d= |S )Nr)   r$   )Ú__dict__Úcopy©r   Ústater   r   r   Ú__getstate__-   s   
zMemoryStorage.__getstate__r2   r   c                 C  s6   | j  |¡ ttjƒ| _t d| j¡| _| j 	¡  d S ©Nr    )
r/   Úupdater   r"   r#   r$   r'   r(   r)   r*   r1   r   r   r   Ú__setstate__3   s   zMemoryStorage.__setstate__c              	   C  sò   t | j ¡ ƒD ]G}| j| 8 | j |g ¡ }r1tj|t ¡  dd„ d}| j| d |… | j|< | j |d ¡s?| j |d ¡ W d   ƒ n1 sIw   Y  qt | j	 ¡ ƒD ] }| j	| t ¡ krv| j
 |d ¡ | j	 |d ¡ | j |d ¡ qVd S )Nc                 S  ó   | j  S r   )r   )Úeventr   r   r   Ú<lambda>>   ó    z/MemoryStorage.__expire_events.<locals>.<lambda>©Úkey)Úlistr&   Úkeysr$   ÚgetÚbisectÚbisect_leftr   Úpopr%   r!   )r   r<   r&   Úoldestr   r   r   Z__expire_events9   s&   ÿ€ù€€üzMemoryStorage.__expire_eventsc                 C  s,   | j  ¡ st d| j¡| _ | j  ¡  d S d S r4   )r)   Úis_aliver"   r'   r(   r*   ©r   r   r   r   Z__schedule_expiryI   s   
þzMemoryStorage.__schedule_expiryú-type[Exception] | tuple[type[Exception], ...]c                 C  s   t S r   )Ú
ValueErrorrE   r   r   r   Úbase_exceptionsN   s   zMemoryStorage.base_exceptionsé   r<   r   r   ÚamountÚintc                 C  s|   |   |¡ |  ¡  | j| ! | j|  |7  < | j| |kr(t ¡ | | j|< W d  ƒ n1 s2w   Y  | j  |d¡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
        Nr   )r?   Ú_MemoryStorage__schedule_expiryr$   r!   r   r%   )r   r<   r   rJ   r   r   r   ÚincrT   s   
€ýzMemoryStorage.incrc                 C  sd   |   |¡ |  ¡  | j|  t| j| | dƒ| j|< W d  ƒ n1 s&w   Y  | j  |d¡S )zŸ
        decrements the counter for a given rate limit key

        :param key: the key to decrement
        :param amount: the number to decrement by
        r   N)r?   rL   r$   Úmaxr!   )r   r<   rJ   r   r   r   Údecrd   s   
ÿzMemoryStorage.decrc                 C  sN   | 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%   r?   r   r!   rB   r$   ©r   r<   r   r   r   r?   r   s
   zMemoryStorage.getc                 C  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              	   C  sÊ   ||krdS |   ¡  | j| L | j |g ¡ t ¡ }z| j| ||  }W n ty1   d}Y nw |rD|j|| krD	 W d  ƒ dS t|ƒg| | j| dd…< 	 W d  ƒ dS 1 s^w   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)rL   r$   r&   Ú
setdefaultr   Ú
IndexErrorr   r
   )r   r<   rR   r   rJ   Ú	timestampÚentryr   r   r   Úacquire_entry‡   s"   ÿ÷$ôzMemoryStorage.acquire_entryc                 C  s   | j  |t ¡ ¡S )z;
        :param key: the key to get the expiry for
        )r%   r?   r   rP   r   r   r   Ú
get_expiry    s   zMemoryStorage.get_expiryútuple[float, int]c                 C  sN   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  r7   r   )r   )rV   r   r   r   r9   ³   r:   z1MemoryStorage.get_moving_window.<locals>.<lambda>r;   rI   r   )r   r&   r?   r@   rA   r   )r   r<   rR   r   rU   r&   rC   r   r   r   Úget_moving_window§   s   	ÿzMemoryStorage.get_moving_windowc                 C  s¦   ||krdS t   ¡ }|  |||¡\}}|  ||||¡\}}	}
}||	 | |
 }t|ƒ| |kr1dS | j|d| |d}
||	 | |
 }t|ƒ|krQ|  ||¡ dS dS )NFé   )rJ   T)r   Úsliding_window_keysÚ_get_sliding_window_infor   rM   rO   )r   r<   rR   r   rJ   ÚnowÚ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_entryr_   r`   r^   útuple[int, float, int, float]c           	      C  sb   |   |¡}|   |¡}|dkrtdƒ}nd|| | d  | }d|| d  | | }||||fS )Nr   rI   )r?   r   )	r   r_   r`   r   r^   ra   rc   rb   Zcurrent_ttlr   r   r   r]   Ù   s   


z&MemoryStorage._get_sliding_window_infoc                 C  s*   t   ¡ }|  |||¡\}}|  ||||¡S r   )r   r\   r]   ©r   r<   r   r^   r_   r`   r   r   r   Úget_sliding_windowé   s   z MemoryStorage.get_sliding_windowc                 C  s2   t   ¡ }|  |||¡\}}|  |¡ |  |¡ d S r   )r   r\   rQ   rf   r   r   r   Úclear_sliding_windowð   s   
z"MemoryStorage.clear_sliding_windowc                 C  s   dS )z-
        check if storage is healthy
        Tr   rE   r   r   r   Úcheckö   s   zMemoryStorage.checkú
int | Nonec                 C  sB   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.reset)NF)r   r   r   r   r   r   )r   r.   )r2   r.   r   r   )r   r   )r   rF   )rI   )r<   r   r   r   rJ   rK   r   rK   )r<   r   rJ   rK   r   rK   )r<   r   r   rK   )r<   r   r   r   )
r<   r   rR   rK   r   rK   rJ   rK   r   r   )r<   r   r   r   )r<   r   rR   rK   r   rK   r   rY   )
r_   r   r`   r   r   rK   r^   r   r   re   )r<   r   r   rK   r   re   )r<   r   r   rK   r   r   )r   r   )r   rj   )r   r   r   Ú__doc__ZSTORAGE_SCHEMEr   r3   r6   r(   rL   ÚpropertyrH   rM   rO   r?   rQ   rW   rX   rZ   rd   r]   rg   rh   ri   rm   Ú__classcell__r   r   r,   r   r      s0    
	




	

û
!


r   )Ú
__future__r   r@   r"   r   Úcollectionsr   r   Úmathr   Zlimits.typingZlimitsZlimits.storage.baser   r   r   r	   r
   r   r   r   r   r   Ú<module>   s    
ÿ