U
    ]g                     @   s|   d dl Z d dlZd dlmZ d dlZd dlmZmZ d dlm	Z	m
Z
mZmZmZmZ G dd de jZG dd deeZdS )	    N)Counter)MovingWindowSupportStorage)DictListOptionalTupleTypeUnionc                       s$   e Zd Zedd fddZ  ZS )LockableEntryN)expiryreturnc                    s$   t   | _| j| | _t   d S N)timeatimer   super__init__)selfr   	__class__ 9/tmp/pip-unpacked-wheel-kizsipjx/limits/storage/memory.pyr      s    
zLockableEntry.__init__)__name__
__module____qualname__floatr   __classcell__r   r   r   r   r   
   s   r   c                       s*  e Zd ZdZdgZd(ee eed fddZe	e
ee eee df f d	d
dZdd	ddZdd	ddZd)eeeeedddZeedddZeddddZd*eeeeedddZeedddZeeeddd Zeeeeeef d!d"d#Zed	d$d%Zee d	d&d'Z  ZS )+MemoryStoragez
    rate limit storage using :class:`collections.Counter`
    as an in memory storage for fixed and elastic window strategies,
    and a simple list to implement moving window strategy.

    ZmemoryNF)uriwrap_exceptions_c                    sJ   t  | _i | _i | _td| j| _| j  t	 j
|fd|i| d S )N{Gz?r   )r   storageexpirationsevents	threadingTimer_MemoryStorage__expire_eventstimerstartr   r   )r   r   r   r    r   r   r   r      s    
zMemoryStorage.__init__.)r   c                 C   s   t S r   )
ValueErrorr   r   r   r   base_exceptions%   s    zMemoryStorage.base_exceptionsc                 C   s   t | j D ]T}t | j| D ]@}|2 |jt krV|| j| krV| j| | W 5 Q R X q qt | j D ]2}| j| t krr| j|d  | j|d  qrd S r   )	listr$   keysr   r   remover#   r"   pop)r   keyeventr   r   r   Z__expire_events+   s    zMemoryStorage.__expire_eventsc                 C   s(   | j  s$td| j| _ | j   d S )Nr!   )r(   is_aliver%   r&   r'   r)   r+   r   r   r   Z__schedule_expiry7   s    
zMemoryStorage.__schedule_expiry   )r1   r   elastic_expiryamountr   c                 C   sV   |  | |   | j|  |7  < |s6| j| |krHt | | j|< | j |dS )aD  
        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 elastic_expiry: whether to keep extending the rate limit
         window every hit.
        :param amount: the number to increment by
        r   )get_MemoryStorage__schedule_expiryr"   r   r#   )r   r1   r   r5   r6   r   r   r   incr<   s    
zMemoryStorage.incr)r1   r   c                 C   s@   | j |dt kr2| j|d | j |d | j|dS )zB
        :param key: the key to get the counter value for
        r   N)r#   r7   r   r"   r0   r   r1   r   r   r   r7   Q   s    zMemoryStorage.getc                 C   s.   | j |d | j|d | j|d dS )z>
        :param key: the key to clear rate limits for
        N)r"   r0   r#   r$   r:   r   r   r   clear\   s    zMemoryStorage.clear)r1   limitr   r6   r   c                    s   ||krdS | j |g  |   t }z| j | ||  }W n tk
rX   d}Y nX |rp|j|  krpdS  fddt|D | j | dd< dS 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
        FNc                    s   g | ]}t  qS r   )r   ).0r    r   r   r   
<listcomp>y   s     z/MemoryStorage.acquire_entry.<locals>.<listcomp>r   T)r$   
setdefaultr8   r   
IndexErrorr   range)r   r1   r<   r   r6   	timestampentryr   r>   r   acquire_entryd   s    
$zMemoryStorage.acquire_entryc                 C   s   t | j|t S )z;
        :param key: the key to get the expiry for
        )intr#   r7   r   r:   r   r   r   
get_expiry|   s    zMemoryStorage.get_expiry)r1   r   r   c                    s6   t   | j|r2t fdd| j| D S dS )z
        returns the number of entries already acquired

        :param key: rate limit key to acquire an entry in
        :param expiry: expiry of the entry
        c                    s   g | ]}|j   kr|qS r   )r   )r=   kr   rC   r   r   r?      s      z2MemoryStorage.get_num_acquired.<locals>.<listcomp>r   )r   r$   r7   len)r   r1   r   r   rI   r   get_num_acquired   s
    
 zMemoryStorage.get_num_acquired)r1   r<   r   r   c                 C   s^   t   }| ||}| j|g ddd D ]$}|j|| kr,t|j|f  S q,t||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)
        N)r   rK   r$   r7   r   rF   )r   r1   r<   r   rC   Zacquireditemr   r   r   get_moving_window   s    	zMemoryStorage.get_moving_windowc                 C   s   dS )z-
        check if storage is healthy
        Tr   r+   r   r   r   check   s    zMemoryStorage.checkc                 C   s8   t t| jt| j}| j  | j  | j  |S r   )maxrJ   r"   r$   r;   r#   )r   Z	num_itemsr   r   r   reset   s
    


zMemoryStorage.reset)NF)Fr4   )r4   )r   r   r   __doc__ZSTORAGE_SCHEMEr   strboolr   propertyr
   r	   	Exceptionr   r,   r'   r8   rF   r9   r7   r;   rE   rG   rK   rN   rO   rQ   r   r   r   r   r   r      s>        
      r   )r%   r   collectionsr   Zlimits.typingZlimitsZlimits.storage.baser   r   r   r   r   r   r	   r
   _RLockr   r   r   r   r   r   <module>   s    