U
    xÊ¹j€  ã                	   @  sÚ  U d dl mZ d dlZd dlZd dlZd dl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mZmZmZmZmZmZmZmZmZ er¼d dlZd dlmZ edƒZnedƒZed	ƒZe d
¡Z ee!e!ge"f Z#G dd„ dƒZ$G dd„ de$ƒZ%G dd„ de$ƒZ&G dd„ de$ƒZ'G dd„ de$ƒZ(G dd„ de$ƒZ)G dd„ de$ƒZ*G dd„ de$ƒZ+G dd„ deeef ƒZ,G dd„ de$ƒZ-de$iZ.de/d < d(d"d#d$d%œd&d'„Z0e$e%e)e&e(e'e*e+e-f	D ]Z1e0e1ƒ �qÆdS ))é    )ÚannotationsN)ÚFutureÚThreadPoolExecutor)Úgroupby)Ú
itemgetter)	ÚTYPE_CHECKINGÚAnyÚCallableÚClassVarÚGenericÚ
NamedTupleÚOptionalÚOrderedDictÚTypeVar)Ú	ParamSpecÚPÚTZfsspecc                   @  sn   e Zd ZU dZdZded< dddddœd	d
„Zddddœdd„Zddœdd„Zddœdd„Z	ddœdd„Z
dS )Ú	BaseCacheag  Pass-though cache: doesn't keep anything, calls every time

    Acts as base class for other cachers

    Parameters
    ----------
    blocksize: int
        How far to read ahead in numbers of bytes
    fetcher: func
        Function of the form f(start, end) which gets bytes from remote as
        specified
    size: int
        How big this file is
    ÚnoneúClassVar[str]ÚnameÚintÚFetcherÚNone©Ú	blocksizeÚfetcherÚsizeÚreturnc                 C  s.   || _ d| _|| _|| _d| _d| _d| _d S ©Nr   )r   Únblocksr   r   Ú	hit_countÚ
miss_countÚtotal_requested_bytes©Úselfr   r   r   © r&   úM/var/www/html/bwave/python/venv/lib/python3.8/site-packages/fsspec/caching.pyÚ__init__<   s    zBaseCache.__init__ú
int | NoneÚbytes©ÚstartÚstopr   c                 C  s<   |d krd}|d kr| j }|| j ks,||kr0dS |  ||¡S )Nr   ó    )r   r   ©r%   r,   r-   r&   r&   r'   Ú_fetchF   s    zBaseCache._fetch©r   c                 C  s   d| _ d| _d| _dS )zAReset hit and miss counts for a more ganular report e.g. by file.r   N)r!   r"   r#   ©r%   r&   r&   r'   Ú_reset_statsO   s    zBaseCache._reset_statsÚstrc              	   C  s>   | j dkr| jdkrdS d| j› d| j › d| j› d| j› d�	S )z2Return a formatted string of the cache statistics.r   Ú z , z: z hits, z	 misses, z total requested bytes)r!   r"   r   r#   r2   r&   r&   r'   Ú
_log_statsU   s    zBaseCache._log_statsc                 C  s@   d| j j› d| j› d| j› d| j› d| j› d| j› d| j› d�S )	Nz

        <z:
            block size  :   z
            block count :   z
            file size   :   z
            cache hits  :   z
            cache misses:   z$
            total requested bytes: z
>
        )Ú	__class__Ú__name__r   r    r   r!   r"   r#   r2   r&   r&   r'   Ú__repr__\   s    ÿþýüûúùzBaseCache.__repr__N)r8   Ú
__module__Ú__qualname__Ú__doc__r   Ú__annotations__r(   r0   r3   r6   r9   r&   r&   r&   r'   r   *   s   

	r   c                      st   e Zd ZdZdZdddddddd	œ‡ fd
d„Zddœdd„Zddddœdd„Zddœdd„Zdddœdd„Z	‡  Z
S )Ú	MMapCachezämemory-mapped sparse file cache

    Opens temporary file, which is filled blocks-wise when data is requested.
    Ensure there is enough disc space in the temporary location.

    This cache method might only work on posix
    ÚmmapNr   r   z
str | Nonezset[int] | Noner   )r   r   r   ÚlocationÚblocksr   c                   s8   t ƒ  |||¡ |d krtƒ n|| _|| _|  ¡ | _d S ©N)Úsuperr(   ÚsetrA   r@   Ú	_makefileÚcache)r%   r   r   r   r@   rA   ©r7   r&   r'   r(   t   s    zMMapCache.__init__zmmap.mmap | bytearrayr1   c                 C  s¢   dd l }dd l}| jdkr tƒ S | jd ks8tj | j¡s„| jd krT| ¡ }t	ƒ | _
nt| jdƒ}| | jd ¡ | d¡ | ¡  nt| jdƒ}|  | ¡ | j¡S )Nr   zwb+é   ó   1zr+b)r?   Útempfiler   Ú	bytearrayr@   ÚosÚpathÚexistsÚTemporaryFilerD   rA   ÚopenÚseekÚwriteÚflushÚfileno)r%   r?   rJ   Úfdr&   r&   r'   rE   �   s    




zMMapCache._makefiler)   r*   ©r,   Úendr   c                   st  t  d|› d|› �¡ |d kr"d}|d kr0ˆ j}|ˆ jksB||krFdS |ˆ j }|ˆ j }t||d ƒ}‡ fdd„|D ƒ}ˆ  jt‡ fdd„|D ƒƒ7  _tt|ƒd	d
„ d�D ]¶\}}t	t
tdƒ|ƒƒ}|d ˆ j }	t|d ˆ j ˆ j ˆ jƒ}
ˆ  j|
|	 7  _t  d|d › d|d › d|	› d|
› d�	¡ ˆ  |	|
¡ˆ j|	|
…< ˆ j |¡ ˆ  jt|ƒ7  _q®ˆ j||… S )NzMMap cache fetching ú-r   r.   rH   c                 3  s   | ]}|ˆ j kr|V  qd S rB   ©rA   ©Ú.0Úir2   r&   r'   Ú	<genexpr>£   s     
 z#MMapCache._fetch.<locals>.<genexpr>c                 3  s   | ]}|ˆ j krd V  qdS )rH   NrY   rZ   r2   r&   r'   r]   ¥   s     
 c                 S  s   | d | d  S )Nr   rH   r&   )Úxr&   r&   r'   Ú<lambda>¯   r.   z"MMapCache._fetch.<locals>.<lambda>)ÚkeyéÿÿÿÿzMMap get blocks z (ú))ÚloggerÚdebugr   r   Úranger!   Úsumr   Ú	enumerateÚtupleÚmapr   Úminr#   r   rF   rA   Úupdater"   Úlen)r%   r,   rW   Zstart_blockZ	end_blockZblock_rangeZneedÚ_Z_blocksZsstartÚsendr&   r2   r'   r0   —   s0    

 
$ÿzMMapCache._fetchúdict[str, Any]c                 C  s   | j  ¡ }|d= |S )NrF   )Ú__dict__Úcopy©r%   Ústater&   r&   r'   Ú__getstate__Å   s    
zMMapCache.__getstate__©rs   r   c                 C  s   | j  |¡ |  ¡ | _d S rB   )rp   rk   rE   rF   rr   r&   r&   r'   Ú__setstate__Ë   s    zMMapCache.__setstate__)NN)r8   r:   r;   r<   r   r(   rE   r0   rt   rv   Ú__classcell__r&   r&   rG   r'   r>   i   s     ú.r>   c                      sB   e Zd ZdZdZdddddœ‡ fdd„Zd	d	d
dœdd„Z‡  ZS )ÚReadAheadCachea!  Cache which reads only when we get beyond a block of data

    This is a much simpler version of BytesCache, and does not attempt to
    fill holes in the cache or keep fragments alive. It is best suited to
    many small reads in a sequential order (e.g., reading lines from a file).
    Z	readaheadr   r   r   r   c                   s&   t ƒ  |||¡ d| _d| _d| _d S )Nr.   r   )rC   r(   rF   r,   rW   r$   rG   r&   r'   r(   Û   s    zReadAheadCache.__init__r)   r*   rV   c                 C  s>  |d krd}|d ks|| j kr$| j }|| j ks6||kr:dS || }|| jkr~|| jkr~|  jd7  _| j|| j || j … S | j|  kr–| jk rÐn n6|  jd7  _| j|| j d … }|t|ƒ8 }| j}n|  jd7  _d}t| j || j ƒ}|  j	|| 7  _	|  
||¡| _|| _| jt| jƒ | _|| jd |…  S ©Nr   r.   rH   )r   r,   rW   r!   rF   r"   rl   rj   r   r#   r   )r%   r,   rW   ÚlÚpartr&   r&   r'   r0   á   s.    zReadAheadCache._fetch©r8   r:   r;   r<   r   r(   r0   rw   r&   r&   rG   r'   rx   Ñ   s   rx   c                      sB   e Zd ZdZdZdddddœ‡ fdd„Zd	d	d
dœdd„Z‡  ZS )ÚFirstChunkCachez›Caches the first block of a file only

    This may be useful for file types where the metadata is stored in the header,
    but is randomly accessed.
    Úfirstr   r   r   r   c                   s&   ||kr|}t ƒ  |||¡ d | _d S rB   )rC   r(   rF   r$   rG   r&   r'   r(     s    zFirstChunkCache.__init__r)   r*   rV   c                 C  s0  |pd}|| j kr t d¡ dS t|| j ƒ}|| jk �r | jd kr°|  jd7  _|| jkr�|  j|7  _|  d|¡}|d | j… | _||d … S |  d| j¡| _|  j| j7  _| j||… }|| jkrî|  j|| j 7  _||  | j|¡7 }|  j	d7  _	|S |  jd7  _|  j|| 7  _|  ||¡S d S )Nr   z,FirstChunkCache: requested start > file sizer.   rH   )
r   rc   rd   rj   r   rF   r"   r#   r   r!   )r%   r,   rW   Údatar{   r&   r&   r'   r0     s0    




zFirstChunkCache._fetchr|   r&   r&   rG   r'   r}   ÿ   s   r}   c                      s–   e Zd ZdZdZdddddddœ‡ fdd	„Zd
d„ Zddœdd„Zdddœdd„Zddddœdd„Z	dddœ‡ fdd„Z
ddddddœdd„Z‡  ZS )Ú
BlockCacheaè  
    Cache holding memory as a set of blocks.

    Requests are only ever made ``blocksize`` at a time, and are
    stored in an LRU cache. The least recently accessed block is
    discarded when more than ``maxblocks`` are stored.

    Parameters
    ----------
    blocksize : int
        The number of bytes to store in each block.
        Requests are only ever made for ``blocksize``, so this
        should balance the overhead of making a request against
        the granularity of the blocks.
    fetcher : Callable
    size : int
        The total size of the file being cached.
    maxblocks : int
        The maximum number of blocks to cache for. The maximum memory
        use for this cache is then ``blocksize * maxblocks``.
    Z
blockcacheé    r   r   r   ©r   r   r   Ú	maxblocksr   c                   s<   t ƒ  |||¡ t || ¡| _|| _t |¡| jƒ| _	d S rB   )
rC   r(   ÚmathÚceilr    rƒ   Ú	functoolsÚ	lru_cacheÚ_fetch_blockÚ_fetch_block_cached©r%   r   r   r   rƒ   rG   r&   r'   r(   F  s    zBlockCache.__init__c                 C  s
   | j  ¡ S ©zª
        The statistics on the block cache.

        Returns
        -------
        NamedTuple
            Returned directly from the LRU Cache used internally.
        ©r‰   Ú
cache_infor2   r&   r&   r'   r�   N  s    	zBlockCache.cache_inforo   r1   c                 C  s   | j }|d= |S )Nr‰   ©rp   rr   r&   r&   r'   rt   Y  s    zBlockCache.__getstate__ru   c                 C  s&   | j  |¡ t |d ¡| jƒ| _d S )Nrƒ   )rp   rk   r†   r‡   rˆ   r‰   rr   r&   r&   r'   rv   ^  s    ÿzBlockCache.__setstate__r)   r*   rV   c                 C  st   |d krd}|d kr| j }|| j ks,||kr0dS || j }|| j }t||d ƒD ]}|  |¡ qR| j||||d�S )Nr   r.   rH   ©Ústart_block_numberÚend_block_number)r   r   re   r‰   Ú_read_cache)r%   r,   rW   r�   r‘   Úblock_numberr&   r&   r'   r0   d  s     

üzBlockCache._fetch)r“   r   c                   st   || j kr"td|› d| j › d�ƒ‚|| j }|| j }|  j|| 7  _|  jd7  _t d|¡ tƒ  ||¡}|S )ú=
        Fetch the block of data for `block_number`.
        ú'block_number=ú(' is greater than the number of blocks (rb   rH   zBlockCache fetching block %d)	r    Ú
ValueErrorr   r#   r"   rc   ÚinforC   r0   )r%   r“   r,   rW   Úblock_contentsrG   r&   r'   rˆ   {  s    
ÿ

zBlockCache._fetch_block©r,   rW   r�   r‘   r   c           	      C  s–   || j  }|| j  }|  jd7  _||kr@|  |¡}|||… S |  |¡|d… g}| t| jt|d |ƒƒ¡ | |  |¡d|… ¡ d |¡S dS ©zú
        Read from our block cache.

        Parameters
        ----------
        start, end : int
            The start and end byte positions.
        start_block_number, end_block_number : int
            The start and end block numbers.
        rH   Nr.   ©r   r!   r‰   Úextendri   re   ÚappendÚjoin©	r%   r,   rW   r�   r‘   Ú	start_posÚend_posÚblockÚoutr&   r&   r'   r’   �  s    


þÿzBlockCache._read_cache)r�   )r8   r:   r;   r<   r   r(   r�   rt   rv   r0   rˆ   r’   rw   r&   r&   rG   r'   r€   -  s    ÿr€   c                      s^   e Zd ZU dZdZded< dddddd	d
œ‡ fdd„Zddddœdd„Zddœdd„Z‡  Z	S )Ú
BytesCacheaK  Cache which holds data in a in-memory bytes object

    Implements read-ahead by the block size, for semi-random reads progressing
    through the file.

    Parameters
    ----------
    trim: bool
        As we read more data, whether to discard the start of the buffer when
        we are more than a blocksize ahead of it.
    r*   r   r   Tr   r   Úboolr   )r   r   r   Útrimr   c                   s,   t ƒ  |||¡ d| _d | _d | _|| _d S )Nr.   )rC   r(   rF   r,   rW   r§   )r%   r   r   r   r§   rG   r&   r'   r(   Å  s
    zBytesCache.__init__r)   rV   c                 C  sì  |d krd}|d kr| j }|| j ks,||kr0dS | jd k	r†|| jkr†| jd k	r†|| jk r†|| j }|  jd7  _| j||| | … S | jr t| j || j ƒ}n|}||ks¶|| j krºdS | jd ksÐ|| jk �r| jd ksæ|| jk�r|  j|| 7  _|  jd7  _|  	||¡| _|| _�nF| jd k	�s.t
‚| jd k	�s>t
‚|  jd7  _|| jk �rÔ| jd k�sv| j| | jk�rž|  j|| 7  _|  	||¡| _|| _n4|  j| j| 7  _|  	|| j¡}|| _|| j | _n�| jd k	�rd|| jk�rd| j| j k�rünh|| j | jk�r6|  j|| 7  _|  	||¡| _|| _n.|  j|| j 7  _|  	| j|¡}| j| | _| jt| jƒ | _|| j }| j||| | … }| j�rè| j| j | jd  }|dk�rè|  j| j| 7  _| j| j| d … | _|S ry   )r   r,   rW   r!   rF   r   rj   r#   r"   r   ÚAssertionErrorrl   r§   )r%   r,   rW   ÚoffsetZbendÚnewr¤   Únumr&   r&   r'   r0   Î  s|    ÿþýü
ÿÿ


zBytesCache._fetchr1   c                 C  s
   t | jƒS rB   )rl   rF   r2   r&   r&   r'   Ú__len__  s    zBytesCache.__len__)T)
r8   r:   r;   r<   r   r=   r(   r0   r¬   rw   r&   r&   rG   r'   r¥   ¶  s   
 ÿ	Ir¥   c                      sP   e Zd ZU dZdZded< dddddd	d
œ‡ fdd„Zddddœdd„Z‡  ZS )ÚAllBytesz!Cache entire contents of the fileÚallr   r   Nr)   zFetcher | Nonezbytes | Noner   )r   r   r   r   r   c                   sN   t ƒ  |||¡ |d krD|  jd7  _|  j| j7  _|  d| j¡}|| _d S )NrH   r   )rC   r(   r"   r#   r   r   r   )r%   r   r   r   r   rG   r&   r'   r(      s    zAllBytes.__init__r*   r+   c                 C  s   |  j d7  _ | j||… S )NrH   )r!   r   r/   r&   r&   r'   r0   .  s    zAllBytes._fetch)NNNN©	r8   r:   r;   r<   r   r=   r(   r0   rw   r&   r&   rG   r'   r­     s   
    ûr­   c                      sV   e Zd ZU dZdZded< ddddd	d
ddœ‡ fdd„Zddddœ‡ fdd„Z‡  ZS )ÚKnownPartsOfAFilea½  
    Cache holding known file parts.

    Parameters
    ----------
    blocksize: int
        How far to read ahead in numbers of bytes
    fetcher: func
        Function of the form f(start, end) which gets bytes from remote as
        specified
    size: int
        How big this file is
    data: dict
        A dictionary mapping explicit `(start, stop)` file-offset tuples
        with known bytes.
    strict: bool, default True
        Whether to fetch reads that go beyond a known byte-range boundary.
        If `False`, any read that ends outside a known part will be zero
        padded. Note that zero padding will not be used for reads that
        begin outside a known byte-range.
    Úpartsr   r   NTr   r   z&Optional[dict[tuple[int, int], bytes]]r¦   r   )r   r   r   r   Ústrictrm   c                   sÐ   t ƒ  |||¡ || _|rÆt| ¡ ƒ}|d g}| |d ¡g}	|dd … D ]f\}
}|d \}}|
|kr�||f|d< |	d  | |
|f¡7  < qL| |
|f¡ |	 | |
|f¡¡ qLtt||	ƒƒ| _	ni | _	d S )Nr   rH   ra   )
rC   r(   r²   ÚsortedÚkeysÚpoprž   ÚdictÚzipr   )r%   r   r   r   r   r²   rm   Zold_offsetsÚoffsetsrA   r,   r-   Zstart0Zstop0rG   r&   r'   r(   L  s    	
zKnownPartsOfAFile.__init__r)   r*   r+   c                   s:  |d krd}|d kr| j }d}| j ¡ D ]”\\}}}||  krH|k r(n q(|| }|||| | … }| jr†||  kr‚|kr´n n.|d|| t|ƒ  7 }|  jd7  _|  S |} q¾q(| jd krÜtd||f› d�ƒ‚t 	d||f› d�¡ t
 d|› d	|› �¡ |  j|| 7  _|  jd7  _|tƒ  ||¡ S )
Nr   r.   ó    rH   z&Read is outside the known file parts: z. z%. IO/caching performance may be poor!z!KnownPartsOfAFile cache fetching rX   )r   r   Úitemsr²   rl   r!   r   r—   ÚwarningsÚwarnrc   rd   r#   r"   rC   r0   )r%   r,   r-   r¤   Zloc0Zloc1r   ÚoffrG   r&   r'   r0   j  s0    
ÿzKnownPartsOfAFile._fetch)NTr¯   r&   r&   rG   r'   r°   3  s   
  úr°   c                   @  sv   e Zd ZdZG dd„ deƒZdddddœd	d
„Zddddœdd„Zdddœdd„Zddddœdd„Z	ddœdd„Z
dS )ÚUpdatableLRUzg
    Custom implementation of LRU cache that allows updating keys

    Used by BackgroudBlockCache
    c                   @  s.   e Zd ZU ded< ded< ded< ded< dS )úUpdatableLRU.CacheInfor   ÚhitsÚmissesÚmaxsizeÚcurrsizeN)r8   r:   r;   r=   r&   r&   r&   r'   Ú	CacheInfoŸ  s   
rÄ   é€   zCallable[P, T]r   r   )ÚfuncÚmax_sizer   c                 C  s0   t  ¡ | _|| _|| _d| _d| _t ¡ | _	d S r   )
Úcollectionsr   Ú_cacheÚ_funcÚ	_max_sizeÚ_hitsÚ_missesÚ	threadingÚLockÚ_lock)r%   rÆ   rÇ   r&   r&   r'   r(   ¥  s    
zUpdatableLRU.__init__zP.argszP.kwargsr   )ÚargsÚkwargsr   c              
   O  sº   |rt d| ¡ › �ƒ‚| j�@ || jkrX| j |¡ |  jd7  _| j| W  5 Q R £ S W 5 Q R X | j||Ž}| j�< || j|< |  jd7  _t| jƒ| j	kr¬| jj
dd� W 5 Q R X |S )Nz Got unexpected keyword argument rH   F©Úlast)Ú	TypeErrorr´   rÐ   rÉ   Úmove_to_endrÌ   rÊ   rÍ   rl   rË   Úpopitem)r%   rÑ   rÒ   Úresultr&   r&   r'   Ú__call__­  s    
 
zUpdatableLRU.__call__r   r¦   )rÑ   r   c              
   G  s(   | j � || jkW  5 Q R £ S Q R X d S rB   )rÐ   rÉ   )r%   rÑ   r&   r&   r'   Úis_key_cachedÀ  s    zUpdatableLRU.is_key_cached)rØ   rÑ   r   c              	   G  s>   | j �. || j|< t| jƒ| jkr0| jjdd� W 5 Q R X d S )NFrÓ   )rÐ   rÉ   rl   rË   r×   )r%   rØ   rÑ   r&   r&   r'   Úadd_keyÄ  s    
zUpdatableLRU.add_keyr¿   r1   c              
   C  s<   | j �, | j| jt| jƒ| j| jd�W  5 Q R £ S Q R X d S )N)rÂ   rÃ   rÀ   rÁ   )rÐ   rÄ   rË   rl   rÉ   rÌ   rÍ   r2   r&   r&   r'   r�   Ê  s    üzUpdatableLRU.cache_infoN)rÅ   )r8   r:   r;   r<   r   rÄ   r(   rÙ   rÚ   rÛ   r�   r&   r&   r&   r'   r¾   ˜  s   r¾   c                      s¨   e Zd ZU dZdZded< d"dddddd	œ‡ fd
d„Zddœdd„Zddœdd„Zddœdd„Z	ddddœdd„Z
d#ddddœ‡ fdd„Zddddddœd d!„Z‡  ZS )$ÚBackgroundBlockCacheaƒ  
    Cache holding memory as a set of blocks with pre-loading of
    the next block in the background.

    Requests are only ever made ``blocksize`` at a time, and are
    stored in an LRU cache. The least recently accessed block is
    discarded when more than ``maxblocks`` are stored. If the
    next block is not in cache, it is loaded in a separate thread
    in non-blocking way.

    Parameters
    ----------
    blocksize : int
        The number of bytes to store in each block.
        Requests are only ever made for ``blocksize``, so this
        should balance the overhead of making a request against
        the granularity of the blocks.
    fetcher : Callable
    size : int
        The total size of the file being cached.
    maxblocks : int
        The maximum number of blocks to cache for. The maximum memory
        use for this cache is then ``blocksize * maxblocks``.
    Ú
backgroundr   r   r�   r   r   r   r‚   c                   sZ   t ƒ  |||¡ t || ¡| _|| _t| j|ƒ| _t	dd�| _
d | _d | _t ¡ | _d S )NrH   ©Úmax_workers)rC   r(   r„   r…   r    rƒ   r¾   rˆ   r‰   r   Ú_thread_executorÚ_fetch_future_block_numberÚ_fetch_futurerÎ   rÏ   Ú_fetch_future_lockrŠ   rG   r&   r'   r(   ð  s    zBackgroundBlockCache.__init__r¿   r1   c                 C  s
   | j  ¡ S r‹   rŒ   r2   r&   r&   r'   r�   ý  s    	zBackgroundBlockCache.cache_inforo   c                 C  s(   | j }|d= |d= |d= |d= |d= |S )Nr‰   rà   rá   râ   rã   rŽ   rr   r&   r&   r'   rt     s    z!BackgroundBlockCache.__getstate__c                 C  sD   | j  |¡ t| j|d ƒ| _tdd�| _d | _d | _t	 
¡ | _d S )Nrƒ   rH   rÞ   )rp   rk   r¾   rˆ   r‰   r   rà   rá   râ   rÎ   rÏ   rã   rr   r&   r&   r'   rv     s    z!BackgroundBlockCache.__setstate__r)   r*   rV   c           
   	   C  sš  |d krd}|d kr| j }|| j ks,||kr0dS || j }|| j }d }d }| j�� | jd k	rÞ| jd k	slt‚| j ¡ r¤t d¡ | j	 
| j ¡ | j¡ d | _d | _n:t|| j  koº|kn  ƒ}|rÞ| j}| j}d | _d | _W 5 Q R X |d k	�rt d¡ | j	 
| ¡ |¡ t||d ƒD ]}|  	|¡ �q|d }	| j�F | jd k�r~|	| jk�r~| j	 |	¡�s~|	| _| j | j|	d¡| _W 5 Q R X | j||||d�S )Nr   r.   z3BlockCache joined background fetch without waiting.z(BlockCache waiting for background fetch.rH   Úasyncr�   )r   r   rã   râ   rá   r¨   Údonerc   r˜   r‰   rÛ   rØ   r¦   re   r    rÚ   rà   Zsubmitrˆ   r’   )
r%   r,   rW   r�   r‘   Zfetch_future_block_numberZfetch_futureZ	must_joinr“   Zend_block_plus_1r&   r&   r'   r0     sz    




 ÿÿþÿ

 ÿÿþ
ý  ÿüzBackgroundBlockCache._fetchÚsyncr4   )r“   Úlog_infor   c                   sv   || j kr"td|› d| j › d�ƒ‚|| j }|| j }t d||¡ |  j|| 7  _|  jd7  _tƒ  ||¡}|S )r”   r•   r–   rb   z!BlockCache fetching block (%s) %drH   )	r    r—   r   rc   r˜   r#   r"   rC   r0   )r%   r“   rç   r,   rW   r™   rG   r&   r'   rˆ   e  s    
ÿ

z!BackgroundBlockCache._fetch_blockrš   c           	      C  s–   || j  }|| j  }|  jd7  _||kr@|  |¡}|||… S |  |¡|d… g}| t| jt|d |ƒƒ¡ | |  |¡d|… ¡ d |¡S dS r›   rœ   r    r&   r&   r'   r’   w  s    


þÿz BackgroundBlockCache._read_cache)r�   )ræ   )r8   r:   r;   r<   r   r=   r(   r�   rt   rv   r0   rˆ   r’   rw   r&   r&   rG   r'   rÜ   Ô  s   
 ÿ	LrÜ   z!dict[str | None, type[BaseCache]]ÚcachesFztype[BaseCache]r¦   r   )ÚclsÚclobberr   c                 C  s6   | j }|s*|tkr*td|›dt| › �ƒ‚| t|< dS )zÝ'Register' cache implementation.

    Parameters
    ----------
    clobber: bool, optional
        If set to True (default is False) - allow to overwrite existing
        entry.

    Raises
    ------
    ValueError
    zCache with name z is already known: N)r   rè   r—   )ré   rê   r   r&   r&   r'   Úregister_cache¨  s    rë   )F)2Ú
__future__r   rÈ   r†   Úloggingr„   rL   rÎ   r»   Úconcurrent.futuresr   r   Ú	itertoolsr   Úoperatorr   Útypingr   r   r	   r
   r   r   r   r   r   r?   Útyping_extensionsr   r   r   Ú	getLoggerrc   r   r*   r   r   r>   rx   r}   r€   r¥   r­   r°   r¾   rÜ   rè   r=   rë   Úcr&   r&   r&   r'   Ú<module>   s^    ,

?h.. 
ee< Q þ÷