o
    ưi(                     @   s   d Z ddlZddlZddlZddlZddlmZmZmZm	Z	 er&ddl
mZ ddlmZ ddlmZ ddlmZ G d	d
 d
eZdS )z|
In-Memory Cache implementation

Has 4 methods:
    - set_cache
    - get_cache
    - async_set_cache
    - async_get_cache
    N)TYPE_CHECKINGAnyListOptional)RedisPipelineIncrementOperation)	BaseModel)'MAX_SIZE_PER_ITEM_IN_MEMORY_CACHE_IN_KB   )	BaseCachec                   @   sv  e Zd Z			d>dee dee dee fddZd	efd
dZdede	fddZ
deddfddZdd Zdede	fddZdd Zdd Zd?ddZd	edee fddZdede	fd d!Zd"d# Zd$efd%d&Zd	edefd'd(Zd)d* Zd$efd+d,Zd	edefd-d.Zd/ed0 deee  fd1d2Zd3d4 Zd5d6 Zd7d8 Zdedee fd9d:Z d;edee fd<d=Z!dS )@InMemoryCache   X     max_size_in_memorydefault_ttlmax_size_per_itemc                 C   s<   |dur|nd| _ |pd| _|pt| _i | _i | _g | _dS )z
        max_size_in_memory [int]: Maximum number of items in cache. done to prevent memory leaks. Use 200 items as a default
        Nr   r   )r   r   r   r   
cache_dictttl_dictexpiration_heap)selfr   r   r    r   V/home/app/Keep/.python/lib/python3.10/site-packages/litellm/caching/in_memory_cache.py__init__   s   

zInMemoryCache.__init__valuec                 C   s   zht |ttttfrtt|| jt k rW dS t |tr(t	
|d | jkW S t|dr9| d }|| jkW S t |trHt|drH| }nt|drPW dS t |ttfs^tj|td}t	
|d | jkW S  tyr   Y dS w )z
        Check if value size exceeds max_size_per_item (1MB)
        Returns True if value size is acceptable, False otherwise
        Tr   
__sizeof__
model_dump	isoformat)defaultF)
isinstanceboolintfloatstrlenr   r   bytessys	getsizeofhasattrr   r   r   jsondumps	Exception)r   r   sizer   r   r   check_value_size4   s0   




zInMemoryCache.check_value_sizekeyreturnc                 C   s   || j v ot | j | kS )z4
        Check if a specific key is expired
        )r   timer   r-   r   r   r   _is_key_expired\   s   zInMemoryCache._is_key_expiredNc                 C   s    | j |d | j|d dS )z@
        Remove a key from both cache_dict and ttl_dict
        N)r   popr   r0   r   r   r   _remove_keyb   s   zInMemoryCache._remove_keyc                 C   s   t   }| jr1| jd \}}|| j|krt| j n||kr-t| j | | nn| jst| j| j	krXt| j\}}| j||krN| | t| j| j	ks9dS dS )a  
        Eviction policy:
        1. First, remove expired items from ttl_dict and cache_dict
        2. If cache is still at or above max_size_in_memory, evict items with earliest expiration times


        This guarantees the following:
        - 1. When item ttl not set: At minimum each item will remain in memory for the default ttl
        - 2. When ttl is set: the item will remain in memory for at least that amount of time, unless cache size requires eviction
        - 3. the size of in-memory cache is bounded

        r   N)
r/   r   r   getheapqheappopr3   r#   r   r   )r   current_timeZexpiration_timer-   r   r   r   evict_cachei   s   
zInMemoryCache.evict_cachec                 C   s0   | j |}|du rdS t|t k rdS dS )z/
        Check if ttl is set for a key
        NTF)r   r4   r!   r/   )r   r-   Zttl_timer   r   r   allow_ttl_override   s   z InMemoryCache.allow_ttl_overridec                 K   s   | j dkrd S t| j| j kr|   | |sd S || j|< | |rad|v rI|d d urIt t|d  | j|< t	
| j| j| |f d S t | j | j|< t	
| j| j| |f d S d S )Nr   ttl)r   r#   r   r8   r,   r9   r/   r!   r   r5   heappushr   r   r   r-   r   kwargsr   r   r   	set_cache   s   



zInMemoryCache.set_cachec                    s   | j d||d| d S )Nr-   r   r   r>   r<   r   r   r   async_set_cache   s   zInMemoryCache.async_set_cachec                    s<   |D ]\}}|d ur| j |||d q| j ||d qd S )N)r-   r   r:   r?   r@   )r   Z
cache_listr:   r=   	cache_keyZcache_valuer   r   r   async_set_cache_pipeline   s   z&InMemoryCache.async_set_cache_pipeliner:   c                    s<   | j |dp	t }|D ]}|| q| j|||d |S )z"
        Add value to set
        r-   )r:   )	get_cachesetaddr>   )r   r-   r   r:   
init_valuevalr   r   r   async_set_cache_sadd   s   z"InMemoryCache.async_set_cache_saddc                 C   s   |  |r| | dS dS )z
        Returns True if the element is expired and removed from the cache

        Returns False if the element is not expired
        TF)r1   r3   r0   r   r   r   evict_element_if_expired   s   

z&InMemoryCache.evict_element_if_expiredc                 K   sP   || j v r&| |rd S | j | }zt|}W |S  ty%   |}Y |S w d S N)r   rK   r(   loadsr*   )r   r-   r=   Zoriginal_cached_responsecached_responser   r   r   rE      s   


zInMemoryCache.get_cachekeysc                 K   s0   g }|D ]}| j dd|i|}|| q|S Nr-   r   rE   appendr   rO   r=   
return_valkrI   r   r   r   batch_get_cache   s
   zInMemoryCache.batch_get_cachec                 K   s0   | j |dpd}|| }| j||fi | |S NrD   r   )rE   r>   r   r-   r   r=   rH   r   r   r   increment_cache   s   zInMemoryCache.increment_cachec                    s   | j dd|i|S rP   )rE   )r   r-   r=   r   r   r   async_get_cache   s   zInMemoryCache.async_get_cachec                    s2   g }|D ]}| j dd|i|}|| q|S rP   rQ   rS   r   r   r   async_batch_get_cache   s   z#InMemoryCache.async_batch_get_cachec                    s>   | j |dI d H pd}|| }| j||fi |I d H  |S rW   )rZ   rA   rX   r   r   r   async_increment   s
   zInMemoryCache.async_incrementincrement_listr   c                    s@   g }|D ]}| j |d |d fi |I d H }|| q|S )Nr-   Zincrement_value)r\   rR   )r   r]   r=   results	incrementresultr   r   r   async_increment_pipeline   s   z&InMemoryCache.async_increment_pipelinec                 C   s"   | j   | j  | j  d S rL   )r   clearr   r   r   r   r   r   flush_cache	  s   

zInMemoryCache.flush_cachec                    s   d S rL   r   rc   r   r   r   
disconnect  s   zInMemoryCache.disconnectc                 C   s   |  | d S rL   )r3   r0   r   r   r   delete_cache  s   zInMemoryCache.delete_cachec                    s   | j |dS )zC
        Get the remaining TTL of a key in in-memory cache
        N)r   r4   r0   r   r   r   async_get_ttl  s   zInMemoryCache.async_get_ttlnc                    s.   t | j dd d}dd |d| D S )z4
        Get the oldest n keys in the cache
        c                 S   s   | d S )Nr	   r   )xr   r   r   <lambda>  s    z7InMemoryCache.async_get_oldest_n_keys.<locals>.<lambda>rD   c                 S   s   g | ]\}}|qS r   r   ).0r-   _r   r   r   
<listcomp>   s    z9InMemoryCache.async_get_oldest_n_keys.<locals>.<listcomp>N)sortedr   items)r   rh   Zsorted_ttl_dictr   r   r   async_get_oldest_n_keys  s   z%InMemoryCache.async_get_oldest_n_keys)r   r   r   rL   )"__name__
__module____qualname__r   r    r   r   r,   r"   r   r1   r3   r8   r9   r>   rA   rC   r   r!   rJ   rK   rE   listrV   rY   rZ   r[   r\   ra   rd   re   rf   rg   rp   r   r   r   r   r      sN    
(*


r   )__doc__r(   r%   r/   r5   typingr   r   r   r   Zlitellm.types.cachingr   Zpydanticr   Zlitellm.constantsr   Z
base_cacher
   r   r   r   r   r   <module>   s    
