o
    h                  	   @  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#ee$e!e!f 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Z0de1d < d*d+d(d)Z2e&e'e+e(e*e)e,e-e/f	D ]Z3e2e3 qdS ),    )annotationsN)FutureThreadPoolExecutor)groupby)
itemgetter)	TYPE_CHECKINGAnyCallableClassVarGeneric
NamedTupleOptionalOrderedDictTypeVar)	ParamSpecPTfsspecc                   @  sP   e Zd ZU dZdZded< dddZdddZdddZdddZ	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	blocksizeintfetcherFetchersizereturnNonec                 C  s.   || _ d| _|| _|| _d| _d| _d| _d S Nr   )r   nblocksr   r   	hit_count
miss_counttotal_requested_bytesselfr   r   r    r&   b/var/www/html/construction_image-detection-poc/venv/lib/python3.10/site-packages/fsspec/caching.py__init__=   s   
zBaseCache.__init__start
int | Nonestopbytesc                 C  s<   |d u rd}|d u r| j }|| j ks||krdS | ||S )Nr       )r   r   r%   r)   r+   r&   r&   r'   _fetchG   s   zBaseCache._fetchc                 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_statsP   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#   r0   r&   r&   r'   
_log_statsV   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#   r0   r&   r&   r'   __repr__]   s   zBaseCache.__repr__Nr   r   r   r   r   r   r   r   r)   r*   r+   r*   r   r,   r   r   )r   r2   )r6   
__module____qualname____doc__r   __annotations__r(   r/   r1   r4   r7   r&   r&   r&   r'   r   +   s   
 



	
r   c                      sV   e Zd ZdZdZ			d"d# fddZd$ddZd%ddZd&ddZd'd d!Z	  Z
S )(	MMapCachea  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

    Parameters
    ----------
    blocksize: int
        How far to read ahead in numbers of bytes
    fetcher: Fetcher
        Function of the form f(start, end) which gets bytes from remote as
        specified
    size: int
        How big this file is
    location: str
        Where to create the temporary file. If None, a temporary file is
        created using tempfile.TemporaryFile().
    blocks: set[int]
        Set of block numbers that have already been fetched. If None, an empty
        set is created.
    multi_fetcher: MultiFetcher
        Function of the form f([(start, end)]) which gets bytes from remote
        as specified. This function is used to fetch multiple blocks at once.
        If not specified, the fetcher function is used instead.
    mmapNr   r   r   r   r   location
str | Noneblocksset[int] | Nonemulti_fetcherMultiFetcher | Noner   r   c                   s>   t  ||| |d u rt n|| _|| _|| _|  | _d S N)superr(   setrC   rA   rE   	_makefilecache)r%   r   r   r   rA   rC   rE   r5   r&   r'   r(      s
   	zMMapCache.__init__mmap.mmap | bytearrayc                 C  s   dd l }dd l}| jdkrt S | jd u stj| jsB| jd u r*| }t	 | _
nt| jd}|| jd  |d |  nt| jd}| | | jS )Nr   zwb+      1zr+b)r@   tempfiler   	bytearrayrA   ospathexistsTemporaryFilerI   rC   openseekwriteflushfileno)r%   r@   rP   fdr&   r&   r'   rJ      s   




zMMapCache._makefiler)   r*   endr,   c                   s  t d| d|  |d u rd}|d u r j}| jks!||kr#dS | j }| j }t||d } fdd|D }  jt fdd|D 7  _g }tt|d	d
 dD ]W\}}	t	t
td|	}	|	d  j }
t|	d  j  j  j}  j||
 7  _t d|	d  d|	d  d|
 d| d	 ||
|f  j|	   jt|	7  _qY|s j|| S  jrt d|  t |D ]\}}|| \}
}t d|
 d|  | j|
|< qn|D ]\}
}t d|
 d|   |
| j|
|< q j|| S )NzMMap cache fetching -r   r-   rN   c                 3  s    | ]
}| j vr|V  qd S rG   rC   .0ir0   r&   r'   	<genexpr>       z#MMapCache._fetch.<locals>.<genexpr>c                 3  s    | ]
}| j v rd V  qdS )rN   Nr^   r_   r0   r&   r'   rb      rc   c                 S  s   | d | d  S )Nr   rN   r&   )xr&   r&   r'   <lambda>   s    z"MMapCache._fetch.<locals>.<lambda>)keyzMMap get blocks z ()zMMap copy block (zMMap get block ()loggerdebugr   r   ranger!   sumr   	enumeratetuplemapr   minr#   appendrC   updater"   lenrK   rE   r   )r%   r)   r\   start_block	end_blockblock_rangeneedranges__blockssstartsendidxrr&   r0   r'   r/      sJ   

 
$zMMapCache._fetchdict[str, Any]c                 C  s   | j  }|d= |S )NrK   )__dict__copyr%   stater&   r&   r'   __getstate__   s   
zMMapCache.__getstate__r   c                 C  s   | j | |  | _d S rG   )r   rr   rJ   rK   r   r&   r&   r'   __setstate__   s   zMMapCache.__setstate__)NNN)r   r   r   r   r   r   rA   rB   rC   rD   rE   rF   r   r   )r   rM   r)   r*   r\   r*   r   r,   r   r   r   r   r   r   )r6   r;   r<   r=   r   r(   rJ   r/   r   r   __classcell__r&   r&   rL   r'   r?   j   s    


>r?   c                      0   e Zd ZdZdZd fd
dZ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).
    	readaheadr   r   r   r   r   r   r   c                   s&   t  ||| d| _d| _d| _d S )Nr-   r   )rH   r(   rK   r)   r\   r$   rL   r&   r'   r(     s   
zReadAheadCache.__init__r)   r*   r\   r,   c                 C  s>  |d u rd}|d u s|| j kr| j }|| j ks||krdS || }|| jkr?|| jkr?|  jd7  _| j|| j || j  S | j|  krK| jk rhn n|  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-   rN   )r   r)   r\   r!   rK   r"   rs   rp   r   r#   r   )r%   r)   r\   lpartr&   r&   r'   r/     s.   zReadAheadCache._fetchr8   r   r6   r;   r<   r=   r   r(   r/   r   r&   r&   rL   r'   r      s
    r   c                      r   )FirstChunkCachezCaches 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   r   r   r   c                   s&   ||kr|}t  ||| d | _d S rG   )rH   r(   rK   r$   rL   r&   r'   r(   /  s   
zFirstChunkCache.__init__r)   r*   r\   r,   c                 C  s*  |pd}|| j krtd dS t|| j }|| jk r| jd u rW|  jd7  _|| jkrG|  j|7  _| d|}|d | j | _||d  S | d| j| _|  j| j7  _| j|| }|| jkrv|  j|| j 7  _|| | j|7 }|  j	d7  _	|S |  jd7  _|  j|| 7  _| ||S )Nr   z,FirstChunkCache: requested start > file sizer-   rN   )
r   ri   rj   rp   r   rK   r"   r#   r   r!   )r%   r)   r\   datar   r&   r&   r'   r/   6  s0   





zFirstChunkCache._fetchr8   r   r   r&   r&   rL   r'   r   &  s
    r   c                      sh   e Zd ZdZdZ	d#d$ fddZdd Zd%ddZd&ddZd'ddZ	d( fddZ
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``.
    
blockcache    r   r   r   r   r   	maxblocksr   r   c                   s<   t  ||| t|| | _|| _t|| j| _	d S rG   )
rH   r(   mathceilr    r   	functools	lru_cache_fetch_block_fetch_block_cachedr%   r   r   r   r   rL   r&   r'   r(   m  s   zBlockCache.__init__c                 C  
   | j  S z
        The statistics on the block cache.

        Returns
        -------
        NamedTuple
            Returned directly from the LRU Cache used internally.
        r   
cache_infor0   r&   r&   r'   r   u     
	zBlockCache.cache_infor   c                 C  s   | j }|d= |S )Nr   r   r   r&   r&   r'   r     s   zBlockCache.__getstate__r   c                 C  s&   | j | t|d | j| _d S )Nr   )r   rr   r   r   r   r   r   r&   r&   r'   r     s   
zBlockCache.__setstate__r)   r*   r\   r,   c                 C  st   |d u rd}|d u r| j }|| j ks||krdS || j }|| j }t||d D ]}| | q)| j||||dS )Nr   r-   rN   start_block_numberend_block_number)r   r   rk   r   _read_cache)r%   r)   r\   r   r   block_numberr&   r&   r'   r/     s    

zBlockCache._fetchr   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 (rh   rN   zBlockCache fetching block %d)	r    
ValueErrorr   r#   r"   ri   inforH   r/   )r%   r   r)   r\   block_contentsrL   r&   r'   r     s   


zBlockCache._fetch_blockr   r   c           	      C     || j  }|| j  }|  jd7  _||kr | |}||| S | ||d g}|t| jt|d | || |d|  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.
        rN   Nr-   r   r!   r   extendro   rk   rq   join	r%   r)   r\   r   r   	start_posend_posblockoutr&   r&   r'   r     s   



zBlockCache._read_cacher   
r   r   r   r   r   r   r   r   r   r   r   r   r   )r   r   r   r,   
r)   r   r\   r   r   r   r   r   r   r,   )r6   r;   r<   r=   r   r(   r   r   r   r/   r   r   r   r&   r&   rL   r'   r   T  s    


r   c                      sH   e Zd ZU dZdZded< 	dd fddZdddZ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   r   r   r   trimboolr   r   c                   s,   t  ||| d| _d | _d | _|| _d S )Nr-   )rH   r(   rK   r)   r\   r   )r%   r   r   r   r   rL   r&   r'   r(     s
   
zBytesCache.__init__r)   r*   r\   c                 C  s  |d u rd}|d u r| j }|| j ks||krdS | jd urC|| jkrC| jd urC|| jk rC|| j }|  jd7  _| j||| |  S | jrPt| j || j }n|}||ks[|| j kr]dS | jd u sg|| jk r| jd u sq|| jkr|  j|| 7  _|  jd7  _| 	||| _|| _n| jd usJ | jd usJ |  jd7  _|| jk r| jd u s| j| | jkr|  j|| 7  _| 	||| _|| _nb|  j| j| 7  _| 	|| j}|| _|| j | _nG| jd ur)|| jkr)| j| j krn4|| j | jkr|  j|| 7  _| 	||| _|| _n|  j|| j 7  _| 	| j|}| j| | _| jt
| j | _|| j }| j||| |  }| jrk| j| j | jd  }|dkrk|  j| j| 7  _| j| j| d  | _|S r   )r   r)   r\   r!   rK   r   rp   r#   r"   r   rs   r   )r%   r)   r\   offsetbendnewr   numr&   r&   r'   r/     sn   







zBytesCache._fetchc                 C  s
   t | jS rG   )rs   rK   r0   r&   r&   r'   __len__>  s   
zBytesCache.__len__)T)
r   r   r   r   r   r   r   r   r   r   r   )r   r   )
r6   r;   r<   r=   r   r>   r(   r/   r   r   r&   r&   rL   r'   r     s   
 
	Ir   c                      sD   e Zd ZU dZdZded< 				dd fddZdddZ  ZS )AllBytesz!Cache entire contents of the fileallr   r   Nr   r*   r   Fetcher | Noner   r   bytes | Noner   r   c                   sN   t  ||| |d u r"|  jd7  _|  j| j7  _| d| j}|| _d S )NrN   r   )rH   r(   r"   r#   r   r   r   )r%   r   r   r   r   rL   r&   r'   r(   G  s   
zAllBytes.__init__r)   r+   r,   c                 C  s   |  j d7  _ | j|| S )NrN   )r!   r   r.   r&   r&   r'   r/   U  s   zAllBytes._fetch)NNNN)
r   r*   r   r   r   r*   r   r   r   r   r9   	r6   r;   r<   r=   r   r>   r(   r/   r   r&   r&   rL   r'   r   B  s   
 r   c                      sD   e Zd ZU dZdZded< 		dd fddZ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   r   r   r   r   &Optional[dict[tuple[int, int], bytes]]strictr   ry   r   c                   s   t  ||| || _|rdt| }|d g}||d g}	|dd  D ]3\}
}|d \}}|
|krH||f|d< |	d  ||
|f7  < q&||
|f |	||
|f q&tt||	| _	d S i | _	d S )Nr   rN   rg   )
rH   r(   r   sortedkeyspoprq   dictzipr   )r%   r   r   r   r   r   ry   old_offsetsoffsetsrC   r)   r+   start0stop0rL   r&   r'   r(   s  s   	

zKnownPartsOfAFile.__init__r)   r*   r+   r   r,   c                   s:  |d u rd}|d u r| j }d}| j D ]J\\}}}||  kr$|k r^n q|| }|||| |  }| jrC||  krA|krZn n|d|| t|  7 }|  jd7  _|  S |} nq| jd u rntd||f dt	d||f d t
d| d	|  |  j|| 7  _|  jd7  _|t || S )
Nr   r-       rN   z&Read is outside the known file parts: z. z%. IO/caching performance may be poor!z!KnownPartsOfAFile cache fetching r]   )r   r   itemsr   rs   r!   r   r   warningswarnri   rj   r#   r"   rH   r/   )r%   r)   r+   r   loc0loc1r   offrL   r&   r'   r/     s2   
zKnownPartsOfAFile._fetch)NT)r   r   r   r   r   r   r   r   r   r   ry   r   r9   r   r&   r&   rL   r'   r   Z  s   
 r   c                   @  sT   e Zd ZdZG dd deZdd ddZd!ddZd"ddZd#ddZ	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)r6   r;   r<   r>   r&   r&   r&   r'   	CacheInfo  s
   
 r      funcCallable[P, T]max_sizer   r   r   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__argsP.argskwargsP.kwargsr   c                 O  s   |rt d|  | j& || jv r-| j| |  jd7  _| j| W  d    S W d    n1 s7w   Y  | j|i |}| j, || j|< |  jd7  _t| j| j	krk| jj
dd W d    |S W d    |S 1 svw   Y  |S )Nz Got unexpected keyword argument rN   Flast)	TypeErrorr   r   r   move_to_endr   r   r   rs   r   popitem)r%   r   r   resultr&   r&   r'   __call__  s.   



zUpdatableLRU.__call__r   r   c                 G  s4   | j  || jv W  d    S 1 sw   Y  d S rG   )r   r   )r%   r   r&   r&   r'   is_key_cached  s   $zUpdatableLRU.is_key_cachedr   c                 G  sd   | j % || j|< t| j| jkr | jjdd W d    d S W d    d S 1 s+w   Y  d S )NFr   )r   r   rs   r   r   )r%   r   r   r&   r&   r'   add_key  s   
"zUpdatableLRU.add_keyr   c                 C  sH   | j  | j| jt| j| j| jdW  d    S 1 sw   Y  d S )N)r   r   r   r   )r   r   r   rs   r   r   r   r0   r&   r&   r'   r     s   $zUpdatableLRU.cache_infoN)r   )r   r   r   r   r   r   )r   r   r   r   r   r   )r   r   r   r   )r   r   r   r   r   r   r   r   )r6   r;   r<   r=   r   r   r(   r   r   r   r   r&   r&   r&   r'   r     s    


r   c                      sv   e Zd ZU dZdZded< 	d(d) fddZd*ddZd+ddZd,ddZ	d-ddZ
d.d/ fd"d#Zd0d&d'Z  ZS )1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   r   r   r   r   c                   sZ   t  ||| t|| | _|| _t| j|| _t	dd| _
d | _d | _t | _d S )NrN   max_workers)rH   r(   r   r   r    r   r   r   r   r   _thread_executor_fetch_future_block_number_fetch_futurer   r   _fetch_future_lockr   rL   r&   r'   r(     s   zBackgroundBlockCache.__init__r   c                 C  r   r   r   r0   r&   r&   r'   r   $  r   zBackgroundBlockCache.cache_infor   c                 C  s(   | j }|d= |d= |d= |d= |d= |S )Nr   r  r  r  r  r   r   r&   r&   r'   r   /  s   z!BackgroundBlockCache.__getstate__c                 C  sD   | j | t| j|d | _tdd| _d | _d | _t	
 | _d S )Nr   rN   r  )r   rr   r   r   r   r   r  r  r  r   r   r  r   r&   r&   r'   r   8  s   z!BackgroundBlockCache.__setstate__r)   r*   r\   r,   c           
      C  s  |d u rd}|d u r| j }|| j ks||krdS || j }|| j }d }d }| jM | jd uro| jd us6J | j rRtd | j	| j
 | j d | _d | _nt|| j  ko]|kn  }|ro| j}| j}d | _d | _W d    n1 syw   Y  |d urtd | j	|
 | t||d D ]}| | q|d }	| j% | jd u r|	| jkr| j|	s|	| _| j| j|	d| _W d    n1 sw   Y  | j||||dS )Nr   r-   z3BlockCache joined background fetch without waiting.z(BlockCache waiting for background fetch.rN   asyncr   )r   r   r  r  r  doneri   r   r   r   r   r   rk   r    r   r  submitr   r   )
r%   r)   r\   r   r   fetch_future_block_numberfetch_future	must_joinr   end_block_plus_1r&   r&   r'   r/   @  sv   








zBackgroundBlockCache._fetchsyncr   log_infor2   c                   sv   || j krtd| d| j  d|| j }|| j }td|| |  j|| 7  _|  jd7  _t ||}|S )r   r   r   rh   z!BlockCache fetching block (%s) %drN   )	r    r   r   ri   r   r#   r"   rH   r/   )r%   r   r  r)   r\   r   rL   r&   r'   r     s   


z!BackgroundBlockCache._fetch_blockr   r   c           	      C  r   r   r   r   r&   r&   r'   r     s   



z BackgroundBlockCache._read_cacher   r   r   r   r:   r   )r  )r   r   r  r2   r   r,   r   )r6   r;   r<   r=   r   r>   r(   r   r   r   r/   r   r   r   r&   r&   rL   r'   r     s   
 


	
Lr   z!dict[str | None, type[BaseCache]]cachesFclstype[BaseCache]clobberr   r   r   c                 C  s6   | j }|s|tv 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)r  r  r  r   r   r   )4
__future__r   r   r   loggingr   rR   r   r   concurrent.futuresr   r   	itertoolsr   operatorr   typingr   r   r	   r
   r   r   r   r   r   r@   typing_extensionsr   r   r   	getLoggerri   r   r,   r   listMultiFetcherr   r?   r   r   r   r   r   r   r   r   r  r>   r  cr&   r&   r&   r'   <module>   sb    ,

? .. 
ee< Q
