o
    hu                     @   s~   d Z ddlmZmZmZ ddlmZ ddlmZm	Z	m
Z
 ddlmZ ddlmZ ddlZddlZdZG d	d
 d
eeeeZdS )z/Module containing a database to deal with packs    )
FileDBBase	ObjectDBR	CachingDB)	LazyMixin)	BadObjectUnsupportedOperationAmbiguousObjectName)
PackEntity)reduceN)PackedDBc                       s   e Zd ZdZdZ fddZdd Zdd Zd	d
 Zdd Z	dd Z
dd Zdd Zdd Zdd ZdddZdd Zdd Z  ZS )r   z-A database operating on a set of object packsi  c                    s   t  | d| _d| _d S Nr   )super__init__
_hit_count	_st_mtime)self	root_path	__class__ A/var/www/vscode/kcb/lib/python3.10/site-packages/gitdb/db/pack.pyr   )   s   
zPackedDB.__init__c                 C   s$   |dkrt  | _| jdd d S d S )N	_entitiesT)force)listr   update_cache)r   attrr   r   r   _set_cache_3   s   zPackedDB._set_cache_c                 C   s   | j jdd dd d S )Nc                 S   s   | d S r   r   )lr   r   r   <lambda>:       z)PackedDB._sort_entities.<locals>.<lambda>T)keyreverse)r   sortr   r   r   r   _sort_entities9   s   zPackedDB._sort_entitiesc                 C   sn   | j | j dkr|   | jD ]#}|d |}|dur2|d  d7  < |  j d7  _ |d |f  S qt|)a  :return: tuple(entity, index) for an item at the given sha
        :param sha: 20 or 40 byte sha
        :raise BadObject:
        **Note:** This method is not thread-safe, but may be hit in multi-threaded
            operation. The worst thing that can happen though is a counter that
            was not incremented, or the list being in wrong order. So we safe
            the time for locking here, lets see how that goesr      N   )r   _sort_intervalr$   r   r   )r   shaitemindexr   r   r   
_pack_info<   s   	

zPackedDB._pack_infoc                 C   s&   z|  | W dS  ty   Y dS w )NTF)r+   r   )r   r(   r   r   r   
has_objectY   s   
zPackedDB.has_objectc                 C      |  |\}}||S N)r+   info_at_indexr   r(   entityr*   r   r   r   infoa      
zPackedDB.infoc                 C   r-   r.   )r+   stream_at_indexr0   r   r   r   streame   r3   zPackedDB.streamc                 c   s>    |   D ]}| }|j}t| D ]}||V  qqd S r.   )entitiesr*   r(   rangesize)r   r1   r*   sha_by_indexr   r   r   sha_iteri   s   zPackedDB.sha_iterc                 C   s    dd | j D }tdd |dS )Nc                 S   s   g | ]
}|d     qS r&   )r*   r8   .0r)   r   r   r   
<listcomp>s       z!PackedDB.size.<locals>.<listcomp>c                 S   s   | | S r.   r   )xyr   r   r   r   t   r   zPackedDB.size.<locals>.<lambda>r   )r   r
   )r   sizesr   r   r   r8   r   s   zPackedDB.sizec                 C   s   t  )zStoring individual objects is not feasible as a pack is designed to
        hold multiple objects. Writing or rewriting packs for single objects is
        inefficient)r   )r   istreamr   r   r   storez   s   zPackedDB.storeFc           
      C   s   t |  }|s|j| jkrdS |j| _ttt j|  d}dd | j	D }|| D ]}t
|}| j	|  || jg q/|| D ]&}d}t| j	D ]\}}	|	d   |kre|} nqS|dkslJ | j	|= qJ|   dS )a  
        Update our cache with the actually existing packs on disk. Add new ones,
        and remove deleted ones. We keep the unchanged ones

        :param force: If True, the cache will be updated even though the directory
            does not appear to have changed according to its modification timestamp.
        :return: True if the packs have been updated so there is new information,
            False if there was no change to the pack databaseFzpack-*.packc                 S   s   h | ]
}|d     qS r;   )packpathr<   r   r   r   	<setcomp>   r?   z(PackedDB.update_cache.<locals>.<setcomp>r&   T)osstatr   st_mtimer   setglobrF   joinr   r	   appendrE   r8   r*   sha_to_index	enumerater$   )
r   r   rJ   
pack_filesour_pack_files	pack_filer1   	del_indexir)   r   r   r   r      s(   	"
zPackedDB.update_cachec                 C   s   dd | j D S )z=:return: list of pack entities operated upon by this databasec                 S   s   g | ]}|d  qS r;   r   r<   r   r   r   r>      s    z%PackedDB.entities.<locals>.<listcomp>)r   r#   r   r   r   r6      s   zPackedDB.entitiesc                 C   sf   d}| j D ]%}|d  ||}|dur*|d  |}|r(||kr(t||}q|r/|S t|)a  :return: 20 byte sha as inferred by the given partial binary sha
        :param partial_binsha: binary sha with less than 20 bytes
        :param canonical_length: length of the corresponding canonical representation.
            It is required as binary sha's cannot display whether the original hex sha
            had an odd or even number of characters
        :raise AmbiguousObjectName:
        :raise BadObject: Nr&   )r   r*   partial_sha_to_indexr(   r   r   )r   partial_binshacanonical_length	candidater)   
item_indexr(   r   r   r   partial_to_complete_sha   s   
z PackedDB.partial_to_complete_sha)F)__name__
__module____qualname____doc__r'   r   r   r$   r+   r,   r2   r5   r:   r8   rD   r   r6   r\   __classcell__r   r   r   r   r       s     
	

-r   )r`   gitdb.db.baser   r   r   
gitdb.utilr   	gitdb.excr   r   r   
gitdb.packr	   	functoolsr
   rI   rM   __all__r   r   r   r   r   <module>   s   