o
    _ZŽh?!  ã                   @  sÄ   U d dl mZ d dlZd dlZd dlZd dlmZ d dlmZ zd dl	Z
W n ey4   es2d dl
Z
Y nw erYd dlmZmZmZmZ d dlmZ ddlmZ eeef Zd	ed
< G dd„ dƒZdS )é    )ÚannotationsN)ÚTYPE_CHECKING)Úatomic_write)ÚAnyÚDictÚIteratorÚLiteral)Ú	TypeAliasé   )ÚCachingFileSystemr	   ÚDetailc                   @  s‚   e Zd ZdZd0dd„Zd1d
d„Zd2dd„Z	d3d4dd„Zd5dd„Zd6dd „Z	d7d!d"„Z
d8d%d&„Zd9d(d)„Zd7d*d+„Zd:d-d.„Zd/S );ÚCacheMetadataa\  Cache metadata.

    All reading and writing of cache metadata is performed by this class,
    accessing the cached files and blocks is not.

    Metadata is stored in a single file per storage directory in JSON format.
    For backward compatibility, also reads metadata stored in pickle format
    which is converted to JSON when next saved.
    Ústorageú	list[str]c                 C  s$   |st dƒ‚|| _i g| _d| _dS )zá

        Parameters
        ----------
        storage: list[str]
            Directories containing cached files, must be at least one. Metadata
            is stored in the last of these directories by convention.
        z3CacheMetadata expects at least one storage locationFN)Ú
ValueErrorÚ_storageÚcached_filesÚ_force_save_pickle)Úselfr   © r   úT/var/www/auris/lib/python3.10/site-packages/fsspec/implementations/cache_metadata.pyÚ__init__%   s
   	
zCacheMetadata.__init__ÚfnÚstrÚreturnr   c                 C  s²   zt |dƒ}t |¡}W d  ƒ n1 sw   Y  W n# ty?   t |dƒ}t |¡}W d  ƒ n1 s8w   Y  Y nw | ¡ D ]}t| d¡tƒrVt	|d ƒ|d< qD|S )z6Low-level function to load metadata from specific fileÚrNÚrbÚblocks)
ÚopenÚjsonÚloadr   ÚpickleÚvaluesÚ
isinstanceÚgetÚlistÚset)r   r   ÚfZloadedÚcr   r   r   Ú_load8   s    ÿ€ÿ€ÿ€zCacheMetadata._loadÚmetadata_to_saveÚNonec                 C  s~   | j r t|ƒ}t ||¡ W d  ƒ dS 1 sw   Y  dS t|dd}t ||¡ W d  ƒ dS 1 s8w   Y  dS )z4Low-level function to save metadata to specific fileNÚw)Úmode)r   r   r!   Údumpr   )r   r*   r   r'   r   r   r   Ú_saveE   s   
"ÿ"ÿzCacheMetadata._saveFÚwritable_onlyÚboolúIterator[tuple[str, str, bool]]c                 c  sP    t | jƒ}t| jƒD ]\}}||d k}|r|sqtj |d¡||fV  qdS )a  Yield locations (filenames) where metadata is stored, and whether
        writable or not.

        Parameters
        ----------
        writable: bool
            Set to True to only yield writable locations.

        Returns
        -------
        Yields (str, str, bool)
        r
   ÚcacheN)Úlenr   Ú	enumerateÚosÚpathÚjoin)r   r0   ÚnÚir   Úwritabler   r   r   Ú_scan_locationsN   s   €
üzCacheMetadata._scan_locationsr7   ÚcfsúCachingFileSystem | Noneú#Literal[False] | tuple[Detail, str]c                 C  s¦   t |  ¡ | jƒD ]H\\}}}}||vrq||  ¡ }|dur;|jr,|d |j |¡kr,q|jr;t ¡ |d  |jkr;qt	j
 ||d ¡}t	j
 |¡rP||f  S qdS )zõIf path is in cache return its details, otherwise return ``False``.

        If the optional CachingFileSystem is specified then it is used to
        perform extra checks to reject possible matches, such as if they are
        too old.
        NÚuidÚtimer   F)Úzipr<   r   ÚcopyZcheck_filesÚfsZukeyZexpiryrA   r6   r7   r8   Úexists)r   r7   r=   r   ÚbaseÚ_r3   Údetailr   r   r   Ú
check_filed   s   	ÿzCacheMetadata.check_fileÚexpiry_timeÚintútuple[list[str], bool]c                 C  sÄ   g }| j d  ¡  ¡ D ]4\}}t ¡ |d  |kr?| dd¡}|s(td|› ƒ‚tj | j	d |¡}| 
|¡ | j d  |¡ q| j d rXtj | j	d d¡}|  | j d |¡ | j d  }||fS )zûRemove expired metadata from the cache.

        Returns names of files corresponding to expired metadata and a boolean
        flag indicating whether the writable cache is empty. Caller is
        responsible for deleting the expired files.
        éÿÿÿÿrA   r   Ú z)Cache metadata does not contain 'fn' for r3   )r   rC   ÚitemsrA   r$   ÚRuntimeErrorr6   r7   r8   r   ÚappendÚpopr/   )r   rJ   Zexpired_filesr7   rH   r   Ú
cache_pathZwritable_cache_emptyr   r   r   Úclear_expired   s"   ÿ
€
zCacheMetadata.clear_expiredc                 C  sP   g }|   ¡ D ]\}}}tj |¡r| |  |¡¡ q| i ¡ q|p$i g| _dS )z>Load all metadata from disk and store in ``self.cached_files``N)r<   r6   r7   rE   rQ   r)   r   )r   r   r   rG   r   r   r   r    ™   s   zCacheMetadata.loadr'   r   c                 C  sF   | j d | }|d durt|d ƒ|j |jkr!d|d< dS dS dS )z‹Perform side-effect actions on closing a cached file.

        The actual closing of the file is the responsibility of the caller.
        rM   r   TN)r   r4   Ú	blocksizeÚsize)r   r'   r7   r(   r   r   r   Úon_close_cached_file¤   s   $ÿz"CacheMetadata.on_close_cached_fileú
str | Nonec                 C  sP   |   |d¡}|s
dS |\}}| | jd ¡r$| jd  |¡ |  ¡  |S tdƒ‚)zÒRemove metadata of cached file.

        If path is in the cache, return the filename of the cached file,
        otherwise return ``None``.  Caller is responsible for deleting the
        cached file.
        NrM   z<Can only delete cached file in last, writable cache location)rI   Ú
startswithr   r   rR   ÚsaveÚPermissionError)r   r7   ÚdetailsrG   r   r   r   r   Úpop_file®   s   ýÿzCacheMetadata.pop_filec           	      C  sH  t |  ¡ | jƒD ]™\\}}}}|sqtj |¡ru|  |¡}| ¡ D ]A\}}||v rb|d du s7|| d du r<d|d< n|| d }| |d ¡ ||d< t	|d || d ƒ|d< || d |d< q!| ¡ D ]\}}||vrs|||< qgn|}dd„ | ¡ D ƒ}| 
¡ D ]}t|d tƒr•t|d ƒ|d< q„|  ||¡ || jd< qdS )	zSave metadata to diskr   TrA   r@   c                 S  s   i | ]	\}}||  ¡ “qS r   )rC   )Ú.0ÚkÚvr   r   r   Ú
<dictcomp>ß   s    z&CacheMetadata.save.<locals>.<dictcomp>rM   N)rB   r<   r   r6   r7   rE   r)   rO   ÚupdateÚmaxr"   r#   r&   r%   r/   )	r   r   rG   r;   r3   r   r_   r(   r   r   r   r   rZ   Â   s:   

€€þ€àzCacheMetadata.saverH   c                 C  s   || j d |< dS )z8Update metadata for specific file in memory, do not saverM   N)r   )r   r7   rH   r   r   r   Úupdate_fileæ   s   zCacheMetadata.update_fileN)r   r   )r   r   r   r   )r*   r   r   r   r   r+   )F)r0   r1   r   r2   )r7   r   r=   r>   r   r?   )rJ   rK   r   rL   )r   r+   )r'   r   r7   r   r   r+   )r7   r   r   rX   )r7   r   rH   r   r   r+   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   r)   r/   r<   rI   rT   r    rW   r]   rZ   rd   r   r   r   r   r      s    




ÿ






$r   )Ú
__future__r   r6   r!   rA   Útypingr   Zfsspec.utilsr   Zujsonr   ÚImportErrorr   r   r   r   Ztyping_extensionsr	   Úcachedr   r   r   Ú__annotations__r   r   r   r   r   Ú<module>   s&    €þ