o
    NZh!                     @  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   \/var/www/html/lang_env/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   W S 1 sw   Y  W dS  tyD   t |d}t|W  d    Y S 1 s<w   Y  Y dS w )z6Low-level function to load metadata from specific filerNrb)openjsonloadr   pickle)r   r   fr   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   _saveA   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   r)   nir   writabler   r   r   _scan_locationsJ   s   
zCacheMetadata._scan_locationsr0   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 )zIf 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)zipr5   r   copyZcheck_filesfsZukeyZexpiryr:   r/   r0   r1   exists)r   r0   r6   r   base_r,   detailr   r   r   
check_file`   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 )zRemove 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.
        r:   r    z)Cache metadata does not contain 'fn' for r,   )r   r<   itemsr:   getRuntimeErrorr/   r0   r1   r   appendpopr(   )r   rC   Zexpired_filesr0   rA   r   
cache_pathZwritable_cache_emptyr   r   r   clear_expired{   s"   

zCacheMetadata.clear_expiredc                 C  s   g }|   D ]1\}}}tj|r2| |}| D ]}t|d tr+t|d |d< q|	| q|	i  q|p<i g| _
dS )z>Load all metadata from disk and store in ``self.cached_files``blocksN)r5   r/   r0   r>   r"   values
isinstancelistsetrK   r   )r   r   r   r@   Zloaded_cached_filescr   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 )zPerform side-effect actions on closing a cached file.

        The actual closing of the file is the responsibility of the caller.
        rF   rO   TN)r   r-   	blocksizesize)r   r!   r0   rT   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)zRemove 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.
        NrF   z<Can only delete cached file in last, writable cache location)rB   
startswithr   r   rL   savePermissionError)r   r0   detailsr@   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rt|d |d< q| || || jd< qdS )	zSave metadata to diskrO   Tr:   r9   c                 S  s   i | ]	\}}||  qS r   )r<   ).0kvr   r   r   
<dictcomp>   s    z&CacheMetadata.save.<locals>.<dictcomp>rF   N)r;   r5   r   r/   r0   r>   r"   rH   updatemaxrP   rQ   rS   rR   r(   )	r   r   r@   r4   r,   r   r_   rT   rO   r   r   r   rZ      s:   

zCacheMetadata.saverA   c                 C  s   || j d |< dS )z8Update metadata for specific file in memory, do not saverF   N)r   )r   r0   rA   r   r   r   update_file   s   zCacheMetadata.update_fileN)r   r   )r   r   r   r   )r#   r   r   r   r   r$   )F)r)   r*   r   r+   )r0   r   r6   r7   r   r8   )rC   rD   r   rE   )r   r$   )r!   r   r0   r   r   r$   )r0   r   r   rX   )r0   r   rA   r   r   r$   )__name__
__module____qualname____doc__r   r"   r(   r5   rB   rN   r   rW   r]   rZ   rd   r   r   r   r   r      s    



	







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