
    [e%                        d dl mZ d dlmZmZmZ d dlmZ d dlm	Z	m
Z
 d dlmZmZmZmZmZmZmZ d dlmZ  G d deeef                   Z G d	 d
e	eef                   Z G d de
e                   ZdS )    )annotations)CallableIteratorMutableMapping)chain)	ItemsView
ValuesView)KTVTZictBaseclosediscardflushlocked)LRUc                      e Zd ZU dZded<   ded<   ded<   ded	<   ded
<   ded<   d ddfd5 fdZed6d            Zej        d7d            Zed6d            Z	e	j        d7d            Z	d8dZ
d9dZed9d            Zd8d Zed8d!            Zd:d;d#Zed<d$            Zed8d%            Zd=d'Zd>d)Zd?d+Zd@d-ZdAd0ZdBd2ZeZdCd3ZdCd4Z xZS )DBuffera  Buffer one dictionary on top of another

    This creates a MutableMapping by combining two MutableMappings, one that
    feeds into the other when it overflows, based on an LRU mechanism.  When
    the first evicts elements these get placed into the second. When an item
    is retrieved from the second it is placed back into the first.

    Parameters
    ----------
    fast: MutableMapping
    slow: MutableMapping
    n: float
        Number of elements to keep, or total weight if ``weight`` is used.
    weight: f(k, v) -> float, optional
        Weight of each key/value pair (default: 1)
    fast_to_slow_callbacks: list of callables
        These functions run every time data moves from the fast to the slow
        mapping. They take two arguments, a key and a value.
        If an exception occurs during a fast_to_slow_callbacks (e.g a callback tried
        storing to disk and raised a disk full error) the key will remain in the LRU.
    slow_to_fast_callbacks: list of callables
        These functions run every time data moves form the slow to the fast mapping.

    Notes
    -----
    If you call methods of this class from multiple threads, access will be fast as long
    as all methods of ``fast``, plus ``slow.__contains__`` and ``slow.__delitem__``, are
    fast. ``slow.__getitem__``, ``slow.__setitem__`` and callbacks are not protected
    by locks.

    Examples
    --------
    >>> fast = {}
    >>> slow = Func(dumps, loads, File('storage/'))  # doctest: +SKIP
    >>> def weight(k, v):
    ...     return sys.getsizeof(v)
    >>> buff = Buffer(fast, slow, 1e8, weight=weight)  # doctest: +SKIP

    See Also
    --------
    LRU
    zLRU[KT, VT]fastMutableMapping[KT, VT]slowCallable[[KT, VT], float]weightzlist[Callable[[KT, VT], None]]fast_to_slow_callbacksslow_to_fast_callbackszdict[KT, bool]_cancel_restorec                    dS )N    )kvs     +lib/python3.11/site-packages/zict/buffer.py<lambda>zBuffer.<lambda>F   s         Nnfloat@Callable[[KT, VT], None] | list[Callable[[KT, VT], None]] | Nonec                (   t                                                       t          |||| j        g| j        g          | _        || _        || _        t          |          r|g}t          |          r|g}|pg | _	        |pg | _
        i | _        d S )N)r   on_evicton_cancel_evict)super__init__r   fast_to_slow_cancel_evictr   r   r   callabler   r   r   )selfr   r   r$   r   r   r   	__class__s          r!   r+   zBuffer.__init__A   s     	'(!/0
 
 
	 	*++ 	>&<%="*++ 	>&<%="&<&B#&<&B#!r#   returnc                    | j         j        S )a<  Maximum weight in the fast mapping before eviction happens.
        Can be updated; this won't trigger eviction by itself; you should call
        :meth:`evict_until_below_target` afterwards.

        See also
        --------
        offset
        evict_until_below_target
        LRU.n
        LRU.offset
        r   r$   r/   s    r!   r$   zBuffer.n`   s     y{r#   valueNonec                    || j         _        d S Nr3   r/   r5   s     r!   r$   zBuffer.no   s    	r#   c                    | j         j        S )a  Offset to add to the total weight in the fast buffer to determine when
        eviction happens. Note that increasing offset is not the same as decreasing n,
        as the latter also changes what keys qualify as "heavy" and should not be stored
        in fast.

        Always starts at zero and can be updated; this won't trigger eviction by itself;
        you should call :meth:`evict_until_below_target` afterwards.

        See also
        --------
        n
        evict_until_below_target
        LRU.n
        LRU.offset
        r   offsetr4   s    r!   r<   zBuffer.offsets   s    " yr#   c                    || j         _        d S r8   r;   r9   s     r!   r<   zBuffer.offset   s     	r#   keyr
   r   c                v    || j         |<   	 | j        D ]} |||           d S # t          $ r
 | j         |=  w xY wr8   )r   r   	Exception)r/   r>   r5   cbs       r!   r,   zBuffer.fast_to_slow   sh    	#	1  3   	 	 		#	s   $ 8c                4   d| j         |<   	 |                                 5  | j        |         }d d d            n# 1 swxY w Y   | j         |         rt          |          	 | j         |= n# | j         |= w xY w|                     ||          }|| j        k    r#| j                            ||           | j        |= |                                 5  | j                                         | j	        D ]} |||           	 d d d            n# 1 swxY w Y   |S )NF)
r   unlockr   KeyErrorr   r$   r   set_noevictevict_until_below_targetr   )r/   r>   r5   wrA   s        r!   slow_to_fastzBuffer.slow_to_fast   s   $)S!	* ' '	#' ' ' ' ' ' ' ' ' ' ' ' ' ' '#C( $smm#$ $S))$S))))) KKU##;; I!!#u---	#[[]] 	 	I..0001  3	 	 	 	 	 	 	 	 	 	 	 	 	 	 	
 s:   A+ :A+ >A+ >A+ +
A50DDDc                h    	 | j         |         S # t          $ r |                     |          cY S w xY wr8   )r   rD   rH   r/   r>   s     r!   __getitem__zBuffer.__getitem__   sH    	*9S>! 	* 	* 	*$$S)))))	*s    11c                    | j         5  t          | j        |           || j        v r
d| j        |<   d d d            n# 1 swxY w Y   || j        |<   d S NT)lockr   r   r   r   r/   r>   r5   s      r!   __setitem__zBuffer.__setitem__   s    Y 	1 	1DIs###d***,0$S)	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	1 	#s   )=AAc                    t          | j        |           || j        v r
d| j        |<   | j                            ||           dS )zsVariant of ``__setitem__`` that does not move keys from fast to slow if the
        total weight exceeds n
        TN)r   r   r   r   rE   rO   s      r!   rE   zBuffer.set_noevict   sO    
 		3$&&&(,D %	c5)))))r#   float | Nonec                :    | j                             |           dS )zuWrapper around :meth:`zict.LRU.evict_until_below_target`.
        Presented here to allow easier overriding.
        N)r   rF   )r/   r$   s     r!   rF   zBuffer.evict_until_below_target   s      		**1-----r#   c                p    || j         v r
d| j         |<   	 | j        |= d S # t          $ r | j        |= Y d S w xY wrM   )r   r   rD   r   rJ   s     r!   __delitem__zBuffer.__delitem__   sY    $&&&(,D %		# 	 	 		#	s    55c                0    t          | j        |           d S r8   )r   r   rO   s      r!   r-   zBuffer._cancel_evict   s    	3r#   ValuesView[VT]c                     t          |           S r8   )BufferValuesViewr4   s    r!   valueszBuffer.values   s    %%%r#   ItemsView[KT, VT]c                     t          |           S r8   )BufferItemsViewr4   s    r!   itemszBuffer.items   s    t$$$r#   intc           
     n     j         5   j        j         5  t           j                  t           j                  z   t	           fdt           j         j        j                  D                       z
  	 cd d d            cd d d            S # 1 swxY w Y   d d d            d S # 1 swxY w Y   d S )Nc              3  <   K   | ]}|j         v o|j        v V  d S r8   r   r   ).0r   r/   s     r!   	<genexpr>z!Buffer.__len__.<locals>.<genexpr>   sH         N5qDI~     r#   )rN   r   lenr   sumr   r   r-   r4   s   `r!   __len__zBuffer.__len__   s_   Y 	 		 	 	DIdi..!    "4#79PQQ    	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	 	s5   B*A#B9B*B	B*B	B**B.1B.Iterator[KT]c              #     K   t                      }	 	 | j        | j        fD ]$}|D ]}||vr|                    |           |V   %dS # t          $ r Y nw xY wG)zmMake sure that the iteration is not disrupted if you evict/restore a key in
        the middle of it
        TN)setr   r   addRuntimeError)r/   seendr>   s       r!   __iter__zBuffer.__iter__   s       uu		)TY/ & &A  & &d?? HHSMMM"%III&    		s   3A 
AAobjectboolc                &    || j         v p|| j        v S r8   rb   rJ   s     r!   __contains__zBuffer.__contains__  s    di33$)#33r#   strc                (    d| j          d| j         dS )NzBuffer<z, >rb   r4   s    r!   __str__zBuffer.__str__  s    222di2222r#   c                :    t          | j        | j                   d S r8   )r   r   r   r4   s    r!   r   zBuffer.flush	      di#####r#   c                :    t          | j        | j                   d S r8   )r   r   r   r4   s    r!   r   zBuffer.close  ry   r#   )r   r   r   r   r$   r%   r   r   r   r&   r   r&   )r1   r%   )r5   r%   r1   r6   )r>   r
   r5   r   r1   r6   )r>   r
   r1   r   r8   )r$   rR   r1   r6   )r>   r
   r1   r6   )r1   rW   )r1   r[   )r1   r_   )r1   rh   )r>   rp   r1   rq   )r1   rt   )r1   r6   )__name__
__module____qualname____doc____annotations__r+   propertyr$   setterr<   r,   rH   r   rK   rP   rE   rF   rU   r-   rZ   r^   rg   ro   rs   rw   __repr__r   r   __classcell__)r0   s   @r!   r   r      s        ) )V     %%%%::::::::#### -;N  " " " " " " ">    X X   X       X $ ]! ! ! ]!	 	 	 	   @ * * * V*    * * * V*. . . . .    V       V & & & &% % % %	 	 	 	    4 4 4 43 3 3 3 H$ $ $ $$ $ $ $ $ $ $ $r#   r   c                  &    e Zd ZU ded<   dZddZdS )	r]   r   _mappingr   r1   Iterator[tuple[KT, VT]]c                    t          | j        j                                        | j        j                                                  S r8   )r   r   r   r^   r   r4   s    r!   ro   zBufferItemsView.__iter__  s4    T]'--//1C1I1I1K1KLLLr#   N)r1   r   )r{   r|   r}   r   	__slots__ro   r   r#   r!   r]   r]     sA         IM M M M M Mr#   r]   c                  .    e Zd ZU ded<   dZddZdd
ZdS )rY   r   r   r   r5   rp   r1   rq   c                :    t          fd| D                       S )Nc              3  $   K   | ]
}|k    V  d S r8   r   )rc   r    r5   s     r!   rd   z0BufferValuesView.__contains__.<locals>.<genexpr>  s'      ,,!5A:,,,,,,r#   )anyr9   s    `r!   rs   zBufferValuesView.__contains__  s&    ,,,,t,,,,,,r#   Iterator[VT]c                    t          | j        j                                        | j        j                                                  S r8   )r   r   r   rZ   r   r4   s    r!   ro   zBufferValuesView.__iter__!  s4    T]'..00$-2D2K2K2M2MNNNr#   N)r5   rp   r1   rq   )r1   r   )r{   r|   r}   r   r   rs   ro   r   r#   r!   rY   rY     sU         I- - - -O O O O O Or#   rY   N)
__future__r   collections.abcr   r   r   	itertoolsr   typingr   r	   zict.commonr
   r   r   r   r   r   r   zict.lrur   r   r]   rY   r   r#   r!   <module>r      ss   " " " " " " > > > > > > > > > >             
 H G G G G G G G G G G G G G G G G G      $ $ $ $ $Xb"f $ $ $DM M M M MiB' M M M
O 
O 
O 
O 
Oz"~ 
O 
O 
O 
O 
Or#   