HEX
Server: LiteSpeed
System: Linux shams.tasjeel.ae 5.14.0-611.5.1.el9_7.x86_64 #1 SMP PREEMPT_DYNAMIC Tue Nov 11 08:09:09 EST 2025 x86_64
User: infowars (1469)
PHP: 8.2.29
Disabled: NONE
Upload Files
File: //lib64/python3.9/site-packages/borg/__pycache__/repository.cpython-39.pyc
a

HZ�h�C�@s�ddlZddlZddlZddlZddlZddlZddlZddlmZm	Z	ddl
mZddlm
Z
ddlmZddlmZddlTdd	lmZdd
lmZmZmZmZmZddlmZddlmZdd
lmZddlmZmZddlm Z ddlm!Z!ddlm"Z"ddl#m$Z$m%Z%m&Z&ddl'm(Z(ddl)m*Z*ddl+m,Z,m-Z-m.Z.m/Z/ddl0m1Z1ddl2m3Z3m4Z4e(e5�Z'dZ6e7e6�Z8dZ9e7e9�e8k�s�J�dZ:dZ;dZ<dZ=eee>�Z?Gdd�d�Z@Gdd�d�ZAeAjBjCd k�s�J�dS)!�N)�hexlify�	unhexlify)�defaultdict)�ConfigParser)�partial)�islice�)�*)�NSIndex)�Error�ErrorWithTraceback�IntegrityError�format_file_size�parse_file_size)�Location)�ProgressIndicatorPercent)�
bin_to_hex)�secure_erase�safe_unlink)�Manifest)�msgpack)�utcnow)�Lock�	LockError�
LockErrorT)�
create_logger)�LRUCache)�SaveFile�SyncFile�sync_dir�safe_fadvise)�crc32)�IntegrityCheckedFile�FileIntegrityErrorsBORG_SEGsATTICSEG��c@sdeZdZdZGdd�de�ZGdd�de�ZGdd�de�ZGdd	�d	e�ZGd
d�de�Z	Gdd
�d
e�Z
Gdd�de�ZGdd�de�Z
Gdd�de�ZGdd�de�ZGdd�de�Zd}dd�Zdd�Zdd �Zd!d"�Zd#d$�Zed%d&��Zed'd(��Zd)d*�Zd+d,�Zd-d.�Zd/d0�Zd1d2�Zd3d4�Zd5d6�Z d7d8�Z!d9d:�Z"d;d<�Z#d=d>�Z$d?d@�Z%dAdB�Z&d~dCdD�Z'dEdF�Z(ddHdI�Z)dJdK�Z*d�dLdM�Z+d�dNdO�Z,dPdQ�Z-dRdS�Z.dTdU�Z/dVdW�Z0dXdY�Z1d�dZd[�Z2d\d]�Z3d�d_d`�Z4d�dadb�Z5dcdd�Z6dedf�Z7dgdh�Z8didj�Z9d�dkdl�Z:d�dmdn�Z;dodp�Z<d�dqdr�Z=d�dsdt�Z>d�dudv�Z?dwdx�Z@d�dydz�ZAd{d|�ZBdS)��
Repositorya�
    Filesystem based transactional key value store

    Transactionality is achieved by using a log (aka journal) to record changes. The log is a series of numbered files
    called segments. Each segment is a series of log entries. The segment number together with the offset of each
    entry relative to its segment start establishes an ordering of the log entries. This is the "definition" of
    time for the purposes of the log.

    Log entries are either PUT, DELETE or COMMIT.

    A COMMIT is always the final log entry in a segment and marks all data from the beginning of the log until the
    segment ending with the COMMIT as committed and consistent. The segment number of a segment ending with a COMMIT
    is called the transaction ID of that commit, and a segment ending with a COMMIT is called committed.

    When reading from a repository it is first checked whether the last segment is committed. If it is not, then
    all segments after the last committed segment are deleted; they contain log entries whose consistency is not
    established by a COMMIT.

    Note that the COMMIT can't establish consistency by itself, but only manages to do so with proper support from
    the platform (including the hardware). See platform.base.SyncFile for details.

    A PUT inserts a key-value pair. The value is stored in the log entry, hence the repository implements
    full data logging, meaning that all data is consistent, not just metadata (which is common in file systems).

    A DELETE marks a key as deleted.

    For a given key only the last entry regarding the key, which is called current (all other entries are called
    superseded), is relevant: If there is no entry or the last entry is a DELETE then the key does not exist.
    Otherwise the last PUT defines the value of the key.

    By superseding a PUT (with either another PUT or a DELETE) the log entry becomes obsolete. A segment containing
    such obsolete entries is called sparse, while a segment containing no such entries is called compact.

    Sparse segments can be compacted and thereby disk space freed. This destroys the transaction for which the
    superseded entries where current.

    On disk layout:

    dir/README
    dir/config
    dir/data/<X // SEGMENTS_PER_DIR>/<X>
    dir/index.X
    dir/hints.X

    File system interaction
    -----------------------

    LoggedIO generally tries to rely on common behaviours across transactional file systems.

    Segments that are deleted are truncated first, which avoids problems if the FS needs to
    allocate space to delete the dirent of the segment. This mostly affects CoW file systems,
    traditional journaling file systems have a fairly good grip on this problem.

    Note that deletion, i.e. unlink(2), is atomic on every file system that uses inode reference
    counts, which includes pretty much all of them. To remove a dirent the inodes refcount has
    to be decreased, but you can't decrease the refcount before removing the dirent nor can you
    decrease the refcount after removing the dirent. File systems solve this with a lock,
    and by ensuring it all stays within the same FS transaction.

    Truncation is generally not atomic in itself, and combining truncate(2) and unlink(2) is of
    course never guaranteed to be atomic. Truncation in a classic extent-based FS is done in
    roughly two phases, first the extents are removed then the inode is updated. (In practice
    this is of course way more complex).

    LoggedIO gracefully handles truncate/unlink splits as long as the truncate resulted in
    a zero length file. Zero length segments are considered to not exist, while LoggedIO.cleanup()
    will still get rid of them.
    c@seZdZdZdS)zRepository.DoesNotExistzRepository {} does not exist.N��__name__�
__module__�__qualname__�__doc__�r,r,�5/usr/lib64/python3.9/site-packages/borg/repository.py�DoesNotExist{sr.c@seZdZdZdS)zRepository.AlreadyExistsz"A repository already exists at {}.Nr'r,r,r,r-�
AlreadyExists~sr/c@seZdZdZdS)zRepository.PathAlreadyExistsz!There is already something at {}.Nr'r,r,r,r-�PathAlreadyExists�sr0c@seZdZdZdS)z!Repository.ParentPathDoesNotExistz:The parent path of the repo directory [{}] does not exist.Nr'r,r,r,r-�ParentPathDoesNotExist�sr1c@seZdZdZdS)zRepository.InvalidRepositoryz0{} is not a valid repository. Check repo config.Nr'r,r,r,r-�InvalidRepository�sr2c@seZdZdZdS)z"Repository.InvalidRepositoryConfigz?{} does not have a valid configuration. Check repo config [{}].Nr'r,r,r,r-�InvalidRepositoryConfig�sr3c@seZdZdZdS)zRepository.AtticRepositoryz8Attic repository detected. Please run "borg upgrade {}".Nr'r,r,r,r-�AtticRepository�sr4c@seZdZdZdS)zRepository.CheckNeededz3Inconsistency detected. Please run "borg check {}".Nr'r,r,r,r-�CheckNeeded�sr5cs eZdZdZ�fdd�Z�ZS)zRepository.ObjectNotFoundz.Object with key {} not found in repository {}.cs$t|t�rt|�}t��||�dS�N)�
isinstance�bytesr�super�__init__)�self�idZrepo��	__class__r,r-r:�s
z"Repository.ObjectNotFound.__init__)r(r)r*r+r:�
__classcell__r,r,r=r-�ObjectNotFound�sr@c@seZdZdZdS)z%Repository.InsufficientFreeSpaceErrorzNInsufficient free space to complete transaction (required: {}, available: {}).Nr'r,r,r,r-�InsufficientFreeSpaceError�srAc@seZdZdZdS)zRepository.StorageQuotaExceededzJThe storage quota ({}) has been exceeded ({}). Try deleting some archives.Nr'r,r,r,r-�StorageQuotaExceeded�srBFNTc

Cs�tj�|�|_td|j�|_d|_d|_d|_i|_d|_	||_
||_||_d|_
||_||_||_d|_d|_||_|	|_dS)Nz	file://%sFr)�os�path�abspathrZ	_location�io�lock�index�shadow_index�_active_txn�	lock_wait�do_lock�	do_create�created�	exclusive�append_only�
storage_quota�storage_quota_use�transaction_doomed�check_segment_magic�make_parent_dirs)
r;rD�createrOrKrGrPrQrTrUr,r,r-r:�s$zRepository.__init__cCs|jr|��dsJd��dS)NFz&cleanup happened in Repository.__del__)rG�close�r;r,r,r-�__del__�szRepository.__del__cCsd|jj�d|j�d�S)N�<� �>)r>r(rDrXr,r,r-�__repr__�szRepository.__repr__cCs@|jrd|_|�|j�d|_|j|jt|j�|j|jd�|S)NFT)rKrG)	rMrVrDrN�open�boolrOrKrLrXr,r,r-�	__enter__�szRepository.__enter__cCsR|durF|tuo|jtjk}|jr6|r6t�d�d}nd}|j|d�|��dS)NzGNo space left on device, cleaning up partial transaction to free space.TF��cleanup)�OSError�errno�ENOSPCrJ�logger�warning�	_rollbackrW)r;�exc_typeZexc_valZexc_tbZno_space_left_on_devicerbr,r,r-�__exit__�s

zRepository.__exit__cCs
t|j�Sr6)rr<rXr,r,r-�id_str�szRepository.id_strcCsnzTttj�|d�d��,}|�d�}d|vp0d|vWd�WS1sH0YWntyhYdS0dS)z;Check whether there is already a Borg repository at *path*.�README�rb�dsBorg Backup repositorysBorg repositoryNF)r^rCrD�join�readrc)rD�fdZreadme_headr,r,r-�
is_repository�s
4zRepository.is_repositorycCs�zt�|�}Wnty Yn60|�|�r6|�|��t�|j�rLt�|�rV|�|��|}tj	�
tj	�|tj��}||kr|q�|�|�rV|�|��qVdS)a�
        Raise an exception if a repository already exists at *path* or any parent directory.

        Checking parent directories is done for two reasons:
        (1) It's just a weird thing to do, and usually not intended. A Borg using the "parent" repository
            may be confused, or we may accidentally put stuff into the "data/" or "data/<n>/" directories.
        (2) When implementing repository quotas (which we currently don't), it's important to prohibit
            folks from creating quota-free repositories. Since no one can create a repository within another
            repository, user's can only use the quota'd repository, when their --restrict-to-path points
            at the user's repository.
        N)
rC�stat�FileNotFoundErrorrrr/�S_ISDIR�st_mode�listdirr0rDrEro�pardir)r;rD�stZ
previous_pathr,r,r-�check_can_create_repository�s



z&Repository.check_can_create_repositoryc
Cs�|�|�|jr.tj�|tj�}tj|dd�tj�|�szzt�|�Wn0t	yx}z|�
|�|�WYd}~n
d}~00ttj�|d�d��}|�t
�Wd�n1s�0Yt�tj�|d��tdd�}|�d�|�dd	d
�|�ddtt��|�ddtt��|�dd
tt|j���|j�rH|�ddt|j��n|�ddd�|�ddd�|�ddtt�d���|�||�dS)z0Create a new empty repository at `path`
        T)�exist_okNrl�w�data�Z
interpolation�
repository�version�1�segments_per_dir�max_segment_sizerPrQ�0�additional_free_spacer<� )rzrUrCrDrorx�makedirs�exists�mkdirrtr1r^�writeZREPOSITORY_READMErZadd_section�set�strZDEFAULT_SEGMENTS_PER_DIRZDEFAULT_MAX_SEGMENT_SIZE�intrPrQr�urandom�save_config)r;rD�parent_path�errrq�configr,r,r-rVs0
"(

zRepository.createc
Csjtj�|d�}tj�|d�}tj�|�r>t�d�t|dd�tj�|�r�d}zt�||�Wnnty�}z<|j	t	j
t	jt	jt	j
t	jt	jfvr�t�|�n�WYd}~n$d}~0ty�t�|�Yn0z6t|��}|�|�Wd�n1s�0YWnFt�yJ}z,|j�r �t�d|j|jf�WYd}~n
d}~00tj�|��rft|dd�dS)Nr�z
config.oldz=Old config file not securely erased on previous config updateT)Zavoid_collateral_damagez�Failed to securely erase old repository config file (hardlinks not supported). Old repokey data, if any, might persist on physical storage.�T%s: Failed writing to '%s'. This is expected when working on read-only repositories.)rCrDro�isfilerfrgr�linkrcrdZEMLINKZENOSYS�EPERMZEACCES�ENOTSUPZEIO�AttributeErrorrr��PermissionErrorrL�strerror�filename)r;rDr�Zconfig_pathZold_config_pathZlink_error_msg�erqr,r,r-r�.s4
"
,
�zRepository.save_configcCs8|js
J�|�d�}|j�dd|�|�|j|j�dS)N�utf-8r�key)r��decoder�r�rD�r;Zkeydatar,r,r-�save_keyQs

zRepository.save_keycCs |jjdddd���}|�d�S)Nrr����fallbackr�)r��get�strip�encoder�r,r,r-�load_keyWszRepository.load_keycCs�|jr|j��std��tj�|jd�}zDt|��(}tj	t
|���dd�Wd�WS1s`0YWnty�YdS0dS)N�-bug in code, exclusive lock should exist here�nonce�big��	byteorder)
rLrG�got_exclusive_lock�AssertionErrorrCrDror^r��
from_bytesrrprt)r;�
nonce_pathrqr,r,r-�get_free_nonce\s
:zRepository.get_free_noncec
Cs�|jr|j��std��|��|kr,td��tj�|jd�}zHt	|dd��(}|�
t|jddd���Wd�n1sx0YWnBt
y�}z*|jr��t�d	|j|jf�WYd}~n
d}~00dS)
Nr�z6nonce space reservation with mismatched previous stater�F�Zbinary�r�r�r�)rLrGr�r�r��	ExceptionrCrDrorr�r�to_bytesr�rfrgr�r�)r;Znext_unreservedZstart_noncer�rqr�r,r,r-�commit_nonce_reservationgs:
�z#Repository.commit_nonce_reservationcCsB|jrt|jd��|��t�tj�|jd��t�|j�dS)z.Destroy the repository at `self.path`
        � is in append-only moder�N)	rP�
ValueErrorrDrWrC�removero�shutil�rmtreerXr,r,r-�destroyxs
zRepository.destroycs2t�fdd�t��j�D��}|r*|dSdSdS)Nc3sT|]L}|�d�r|dd���rt�tj��j|��jdkrt|dd��VqdS)�index.�Nr)�
startswith�isdigitrCrsrDro�st_sizer�)�.0�fnrXr,r-�	<genexpr>�s6�z6Repository.get_index_transaction_id.<locals>.<genexpr>���)�sortedrCrwrD)r;�indicesr,rXr-�get_index_transaction_id�s
�z#Repository.get_index_transaction_idcCsh|��}|j��}|dur6|dur6d|j}|�|��||krd|durT||krTd}n|}|�||�dS)Nz,%s" - although likely this is "beyond repair)r�rF�get_segments_transaction_idrDr5�replay_segments)r;�index_transaction_id�segments_transaction_id�msgZreplay_fromr,r,r-�check_transaction�s


zRepository.check_transactioncCs|��|��Sr6)r�r�rXr,r,r-�get_transaction_id�szRepository.get_transaction_idcCsttj�|jd����dS)NrG)rrCrDro�
break_lockrXr,r,r-r��szRepository.break_lockcCs|jdur|j�||�dSr6)rG�migrate_lock)r;Zold_idZnew_idr,r,r-r��s
zRepository.migrate_lockc	CsN||_zt�|�}Wnty0|�|��Yn0t�|j�sH|�|��|rlttj�	|d�||d��
�|_nd|_tdd�|_
zDttj�	|jd���}|j
�|�Wd�n1s�0YWn&ty�|��|�|j��Yn0d|j
��v�r|��|�|d��|j
�dd�}|dk�r>|��|�|d	|��t|j
�dd
��|_|jtk�rv|��|�|dt��|j
�dd�|_t|j
jdd
dd��|_|j�p�|j
jdddd�|_|jdu�r�t|j
jdddd��|_t|j
�dd����|_t |j|j|j�|_!|j"�rJ|j!�#�}|du�rJ|j!�$|�t%k�rJ|��|�&|��dS)NrG)�timeoutr~r�rzno repository section foundr�rz;repository version %d is not supported by this borg versionr�zmax_segment_size >= %dr�r�rr�rPFrQr<)'rDrCrsrtr.rurvr2rro�acquirerGrr�r^Z	read_filerWZsectionsr3�getintrr�r�ZMAX_SEGMENT_SIZE_LIMITr�r�rPZ
getbooleanrQrr�r<�LoggedIOrFrT�get_latest_segment�get_segment_magic�ATTIC_MAGICr4)	r;rDrOrKrGryrqZrepo_version�segmentr,r,r-r^�sV
 .
�
zRepository.opencCs0|jr,|jr|j��d|_|j��d|_dSr6)rGrFrW�releaserXr,r,r-rW�s

zRepository.close皙�����?cCs�|jr|j}|��|�|��|��|j��}|j�|d�|j|t	j
j7<|r�|js�|r�|j�
�D]0\}}tj�|�dkrnd|j|<t	j
j|j|<qn|�|�|��|��dS)zCommit transaction
        r�N)rS�rollback�check_free_space�log_storage_quotarF�write_commit�segments�
setdefault�compactr��
header_fmt�sizerP�segment_iteratorrCrD�getsize�compact_segments�write_index)r;�
save_spacer��	thresholdZcleanup_commits�	exceptionr�r�r,r,r-�commit�s$



zRepository.commitcCs�d|}tj�|j|�}z8t|d��}t�|�}Wd�n1sD0YWntydYdS0|�d�dkr�t�	d|�d�|�dS||�
�S)N�integrity.%drm�versionr$z'Unknown integrity data version %r in %s)rCrDror^r�unpackrtr�rfrgr�)r;�transaction_idr��integrity_fileZintegrity_pathrq�	integrityr,r,r-�_read_integrity�s,zRepository._read_integrityc
Cs�|durt�Stj�|jd|�}|�|d�}z>t|d|d��}t�|�Wd�WS1s`0YWnnttt	fy�}zPt
�d|�t�|�|s��|�
|���|jdd�|�|���WYd}~Sd}~00dS)N�index.%d�indexF�r��integrity_datazARepository index missing or corrupted, trying to recover from: %s)r�)r
rCrDror�r"rpr�rcr#rfrg�unlink�prepare_txnr�r��
open_index)r;r��auto_recover�
index_pathr�rq�excr,r,r-r�
s.
zRepository.open_indexc

Cs�d|_|jrV|j��sV|jdur(td��z|j��WnttfyTd|_�Yn0|j	rd|dur�z|j
|dd�|_	WnNttt
fy�}z0t�d|�|��|j
|dd�|_	WYd}~n
d}~00|dur�i|_t�|_d|_|j���n�|�r|j�|�tj�|jd|�}tj�|jd|�}|�|d	�}z>t|d|d
��}t�|�}Wd�n1�sj0YWnntj t!t
f�y�}	zLt�d|	�t"|	t!��s�t�#|�t�#|�|��|�$|�WYd}	~	dSd}	~	00|dd
k�rTt�%d|�|d|_t�|_d|_i|_t&|d�D]}
t�%d|
�|�'|
��q*t�%d�nT|ddk�rttd|d��n4|d|_t|d�|_|�(dd�|_|�(di�|_|�)�|j�*�D].\}}t+|�D]}
|
|k�r�|�,|
��qʐq�dS)NTr�F)r�z9Checking repository transaction due to previous error: %sr�hints.%dr��hintsr�zARepository hints file missing or corrupted, trying to recover: %sr�rzUpgrading from v1 hints.%d�segments�compactz%Rebuilding sparse info for segment %dzUpgrade to v2 hints completer$zUnknown hints file version: %d�storage_quota_use�shadow_index)-rJrLrGr�rOr�ZupgraderrrHr�r�rcr#rfrgr�r��	FreeSpacer�rRrI�clearrFrbrCrDror�r"rr�ZUnpackExceptionrtr7r�r��debugr��_rebuild_sparser�r��items�listr�)
r;r��
do_cleanupr�Z
hints_pathr�r�rq�hintsr�r�r�Zshadowed_segmentsr,r,r-r�st
&.





zRepository.prepare_txncCsTdd�}dd�}d|j|j|j|jd�}ddi}|j��}|dusFJ�|jr�ttj	�
|j	d�d	��,}td
|t��
t�f|d�Wd�n1s�0Yd|}tj	�
|j	|�}t|d
|dd��$}	t�||	�||	�Wd�n1s�0Y|	j|d<d|}
tj	�
|j	|
�}t|d
|
dd��$}	|j�|	�||	�Wd�n1�s\0Y|	j|d<d|}tj	�
|j	|�}
t|
d
d��$}	t�||	�||	�Wd�n1�s�0Y||
�t|j	�||�||�t|j	�d|}t�|j	�D]<}|�d��s �q|�|��r0�qt�tj	�
|j	|���qd|_dS)NcSs|��t�|���dSr6)�flushrC�fsync�fileno�rqr,r,r-�flush_and_syncfsz.Repository.write_index.<locals>.flush_and_synccSst�|d|�dS)N�.tmp)rC�replace��filer,r,r-�
rename_tmpjsz*Repository.write_index.<locals>.rename_tmpr$)r�rrrrr�Ztransactions�aztransaction %d, UTC time %srrrT)r�r�rr�r�r��wbz.%d)r�zhints.z
integrity.)r�r�rRrIrFr�rPr^rCrDro�printr�strftimeZ
ISO_FORMATr"r�packr�rHr�rrwr��endswithr�)r;rrr
r�r��logZ
hints_nameZ
hints_filerqZ
index_nameZ
index_fileZintegrity_namer��current�namer,r,r-r�esb�
�
��$&
(
(

zRepository.write_indexc
Cs�|j��d}t|j�dt|j�dd}||7}||j7}|js�|jt}t|j�dkr�d}|j�	�D]4\}}z||j
�|�|7}Wqlty�Yql0qlt
�d�t||�}t
�d|�||7}n||7}zt�|j�j}Wn:t�y }z t
�dt|��WYd}~dSd}~00t
�d	|�d
|���||k�r�|j�r^t
�d�|��n|jdd
�t|�}	t|�}
|�|	|
��dS)zJPre-commit check for sufficient free space to actually perform the commit.��
irzAcheck_free_space: few segments, not requiring a full free segmentzBcheck_free_space: calculated working space for compact as %d bytesz.Failed to check free space before committing: Nz!check_free_space: required bytes z
, free bytes z@Not enough free space to initialize repository at this location.Tra)rHr��lenr�r�r�rPr��MAX_OBJECT_SIZEr
rF�segment_sizertrfr�minr��
disk_usagerD�freercrgr�rN�errorr�rhrrA)r;Zrequired_free_spaceZ
hints_sizeZfull_segment_sizeZcompact_working_spacer�r(Z
free_spaceZos_errorZformatted_requiredZformatted_freer,r,r-r��s@
 







zRepository.check_free_spacecCs$|jr t�dt|j�t|j��dS)Nz!Storage quota: %s out of %s used.)rQrf�inforrRrXr,r,r-r��s�zRepository.log_storage_quotacs��jst�d�dS�j}���}�j}g�d��fdd�	}t�d|d�tt�j�dd	d
d�}t�j�	��D�]�\�}�j
���s�t�d���j�=|�
�qp�j
���}d
||}	|	|ks�t�d�|	d|�|�
�qp|��d�t�d�|�|	d|��j
j�dd�D�] \}
}}}
|
tk�r4�q�j�|�}|�|fk}|
tk�r�|�r�z�j
j||
dd�\}}Wn.tj�y�|��j
�||
�\}}Yn0||f�j|<|�|d�||d	7<|�d	8<�q|
tk�r@|�s@z�j|���Wnttf�y Yn0�jt|
��j
jj8_n�|
tk�r|�s|�jv}|�pzt�fdd��j|D��}|du�p��|k}|�s�|�rz�j
j |dd�\}}Wn,tj�y�|��j
� |�\}}Yn0�j||7<|�|d�n8t�dt!|��||||�j�|���j|�s�j|=�q|�dk�sRJd����"��|�
�qp|�#�|dd��j
�$��j}t�%dt&||��t�d�dS)zBCompact sparse segments by copying data into new segments
        znothing to do: compact emptyNTcs��jj|d�}�j�|d��j|tjj7<t�	d|r@dnd|��D]@}t�	d|��j�
|�}|dksxJd���j�|��j|=qLg�dS)N��intermediaterz+complete_xfer: wrote %scommit at segment %dz
intermediate r�z)complete_xfer: deleting unused segment %d�<Corrupted segment reference count - corrupted index or hints)rFr�r�r�r�r�r�r�rfr�pop�delete_segment)r,r��count)r;�unusedr,r-�
complete_xfer�s
z2Repository.compact_segments.<locals>.complete_xferz'Compaction started (threshold is %i%%).rnzCompacting segments %3.0f%%rzrepository.compact_segments��totalr��step�msgidz3segment %d not found, but listed in compaction datag�?z>not compacting segment %d (maybe freeable: %2.2f%% [%d bytes])gY@rzNcompacting segment %d with usage count %d (maybe freeable: %2.2f%% [%d bytes]))�include_data)�
raise_fullc3s|]}|�kVqdSr6r,)r�Zshadowed�r�r,r-r�:sz.Repository.compact_segments.<locals>.<genexpr>zIdropping DEL for id %s - seg %d, iti %r, knisi %r, spe %r, dins %r, si %rr-Fr+z+compaction freed about %s repository space.zcompaction completed.)T)'r�rfrrRr�r�rr#r�r
rF�segment_existsrg�showr%r��iter_objects�
TAG_COMMITrHr��TAG_PUT�	write_putr��SegmentFullrIr��KeyErrorr��put_header_fmtr��
TAG_DELETE�any�write_deleter�append�finish�clear_empty_dirsr*r)r;r�Zquota_use_beforer�r�r2�piZfreeable_spacer%Zfreeable_ratio�tagr��offsetr}Zin_indexZis_index_objectZnew_segmentZkey_not_in_shadow_indexZshadowed_put_existsZdelete_is_not_stabler�Zquota_use_afterr,)r�r;r1r-r��s�
�
��

�"

�



zRepository.compact_segmentsc
Cs�|j}d|_|j|dd�z�tdd�|j��D��}t|ddd�}t|j���D]L\}\}}|�|�|durx||krxqP||kr�q�|j�|�}	|�	||	�qP|�
�|��W||_|��n||_|��0dS)NF)rcss|]
}dVqdS�rNr,�r��_r,r,r-r���z-Repository.replay_segments.<locals>.<genexpr>zReplaying segments %3.0f%%zrepository.replay_segments)r4r�r6)
rOr��sumrFr�r�	enumerater;r<�
_update_indexrGr�r�)
r;r�r�Zremember_exclusive�
segment_countrI�ir�r��objectsr,r,r-r�zs,�


�zRepository.replay_segmentsc	Cs�d|j|<|D�]l\}}}}|tkr�zJ|j|\}}	|j||7<|j|d8<|j�|g��|�Wnty�Yn0||f|j|<|j|d7<|j|7_q|t	k�r@z|j�
|�\}}Wnty�Yn\0|j�|��r||j|d8<|jj
|||dd�}|j||7<|j�|g��|�q|tk�rNqqd|�d|��}
|du�rt|�|
��q||
�q|j|dk�r�|j�|�|j|<dS)z2some code shared between replay_segments and checkrrF��	read_datazUnexpected tag z in segment N)r�r>rHr�rIr�rFrArRrCr.rFr:rpr=r5r%)r;r�rU�reportrJr�rKr��srNr�r,r,r-rR�s>




zRepository._update_indexcCs�z|j�|�}Wn ty0|j�|�YdS0|j|dkrN||j|<dSd|j|<|jj|dd�D]X\}}}}|tkr�|j�	|d�||fkr�|j||7<qh|t
krh|j||7<qhdS)zNRebuild sparse bytes count for a single segment relative to the current index.NrFrV)r�r�)rFr%rtr�r.r�r<r>rHr�rC)r;r�r%rJr�rKr�r,r,r-r	�s

zRepository._rebuild_sparsercs�|jr|rt|jd��d��fdd�}t�d�|jr<J�z"|��}|�|�}t�d|�Wn>t	y�}z&|j
��}d}t�d|�WYd}~n
d}~00|dur�t�d	�|��}|dur�t�d
�|j
�
�}|dur�|d�dS|r�|j
�|�|j
��}t�d|�t�d
|�|�d�tdd�|j
��D��}	t�d|	�t|�}
|�r`|
�r`J�|
�rjdnd}|
�r�|jjdddd�}t�d|d�n"d}|j�dd�|�|j|j�t��}
t|	dddd�}d}t|j
���D�]\}\}}|�|�||k�r
�q�||k�r�q�t�d|�zt|j
�|��}WnZt�y�}z@|t|��g}|�r~|j
� ||�t|j
�|��}WYd}~n
d}~00|
�s�|�!|||�|
�r�t��|
|k�r�t�d|�|j�"ddt|��|�|j|j��q$�q�t�d|�|j�dd�|�|j|j�|�#�|�r`|du�r`|d |���|d|j
_$|j
�%�|
�sdt�d!�|�rV|�sVt&|�t&|j'�k�r�|d"�|d#t&|��|d$t&|j'��n
t�d%�d&}d'}|j'�(�D]2\}}|�)||�}||k�r�||t*|�||��q�|�(�D]D\}}||j'v�r(�q|j'�)||�}||k�r||t*|�||��q|�rd|�+�|�,���r�|�r�t�d(|�nt�-d)|�nt�d*|���p�|S)+z�Check repository consistency

        This method verifies all segment checksums and makes sure
        the index is consistent with the data stored in the segments.
        r�Fcsd�tj|g|�R�dS)NT)rfr))r��args�Zerror_foundr,r-�report_error�sz&Repository.check.<locals>.report_errorzStarting repository checkz&Read committed index of transaction %dNz#Failed to read committed index (%s)zNo segments transaction foundz1No index transaction found, trying latest segmentz'This repository contains no valid data.zSegment transaction is    %szDetermined transaction is %scss|]
}dVqdSrLr,rMr,r,r-r��rOz#Repository.check.<locals>.<genexpr>zFound %d segmentsrZfullr�last_segment_checkedr�r�zskipping to segments >= %drzChecking segments %3.1f%%r�zrepository.checkr3zchecking segment file %s...z:finished partial segment check, last segment checked is %dz$finished segment check at segment %dzAdding commit tag to segment zStarting repository index checkzIndex object count mismatch.zcommitted index: %d objectszrebuilt index:   %d objectszIndex object count match.z5ID: %-64s rebuilt index: %-16s committed index: %-16sz<not found>z8Finished %s repository check, errors found and repaired.z+Finished %s repository check, errors found.z0Finished %s repository check, no problems found.).rPr�rDrfr*rJr�r�rr�rFr�r�r�rbr�rPr�r_r�r�Z
remove_optionr��time�	monotonicrrQr;rr<r
r��recover_segmentrRr�rGr�r�r#rH�	iteritemsr�rr�r�r))r;Zrepairr�Zmax_durationr\r�Z
current_indexr�r�rSr�moder]Zt_startrIr�rTr�rUr�Zline_formatZ	not_foundr��valueZ
current_valuer,r[r-�check�s�




"




�


&





zRepository.checkc
cs�|jj|d�D]�\}}|dur*||kr*q�zL|jj||p:ddd�D]0\}}}}|durb||krbqt|||||fVqBWqty�}	z$t�d||t|	�f�WYd}	~	qd}	~	00qdS)a	Very low level scan over all segment file entries.

        It does NOT care about what's committed and what not.
        It does NOT care whether an object might be deleted or superseded later.
        It just yields anything it finds in the segment files.

        This is intended as a last-resort way to get access to all repo contents of damaged repos,
        when there is uncommitted, but valuable data in there...

        When segment or segment+offset is given, limit processing to this location only.
        r9NrT)r�rKr7z6Segment %d (%s) has IntegrityError(s) [%s] - skipping.)rFr�r<r
rfr)r�)
r;r�rKZcurrent_segmentr�rJr�Zcurrent_offsetr}r�r,r,r-�scan_low_levelRs�
�zRepository.scan_low_levelcCs,|r|j�|j���d|_d|_d|_dS)z	
        NF)rFrbr�rHrJrS)r;rbr,r,r-rhks
zRepository._rollbackcCs|jdd�dS)NFra)rhrXr,r,r-r�tszRepository.rollbackcCs |js|�|���|_t|j�Sr6)rHr�r�r#rXr,r,r-�__len__xszRepository.__len__cCs |js|�|���|_||jvSr6)rHr�r�)r;r<r,r,r-�__contains__}szRepository.__contains__cCs4|js|�|���|_dd�t|jj|d�|�D�S)zd
        list <limit> IDs starting from after id <marker> - in index (pseudo-random) order.
        cSsg|]\}}|�qSr,r,)r��id_rNr,r,r-�
<listcomp>�rOz#Repository.list.<locals>.<listcomp>)�marker)rHr�r�rra)r;�limitrjr,r,r-r�szRepository.listc
Cs�|dur|dkrtd��|js2|��}|�|�|_|du}|rBdn|j|\}}g}|j�|�D]�\}}	|jj||ddd�}
zt|
�\}}}
}Wntt	fy�Yq`Yn0|dkr�d}q||t
kr|||
f|j�|�kr||�|�t
|�|kr||Sq|q`|S)a�
        list <limit> IDs starting from after id <marker> - in on-disk order, so that a client
        fetching data in this order does linear reads and reuses stuff from disk cache.

        We rely on repository.check() has run already (either now or some time before) and that:

        - if we are called from a borg check command, self.index is a valid, fresh, in-sync repo index.
        - if we are called from elsewhere, either self.index or the on-disk index is valid and in-sync.
        - the repository segments are valid (no CRC errors).
          if we encounter CRC errors in segment entry headers, rest of segment is skipped.
        Nrz$please use limit > 0 or limit = None)rrF)rWr7r)r�rHr�r�rFr�r<�next�
StopIterationr
r>r�rFr#)r;rkrjr�Zat_startZ
start_segmentZstart_offset�resultr�r�Zobj_iteratorrJr<rKr�r,r,r-�scan�s,

zRepository.scancCs^|js|�|���|_z |j|\}}|j�|||�WStyX|�||j�d�Yn0dSr6)rHr�r�rFrprAr@rD)r;r<r�rKr,r,r-r��szRepository.getccs|D]}|�|�VqdSr6)r�)r;�idsZis_preloadedrhr,r,r-�get_many�szRepository.get_manycCs�|js|�|���z|j|\}}Wnty8Yn0|�|||�|j�||�\}}|jt	|�|jj
j7_|j�
|d�|j|d7<||f|j|<|jr�|j|jkr�|�t|j�t|j��|_|j�dS)z�put a repo object

        Note: when doing calls with wait=False this gets async and caller must
              deal with async results / exceptions later.
        rrN)rJr�r�rHrA�_deleterFr?rRr#rBr�r�r�rQrBrrS)r;r<r}�waitr�rKr,r,r-�put�s"�zRepository.putcCs^|js|�|���z|j�|�\}}Wn"tyJ|�||j�d�Yn0|�|||�dS)z�delete a repo object

        Note: when doing calls with wait=False this gets async and caller must
              deal with async results / exceptions later.
        N)	rJr�r�rHr.rAr@rDrr)r;r<rsr�rKr,r,r-�delete�szRepository.deletecCs�|j�|g��|�|j|d8<|jj|||dd�}|j||7<|j�|�\}}|j||7<|j�|d�dS)NrFrVr)rIr�rFr�rFrpr�rE)r;r<r�rKr�r,r,r-rr�szRepository._deletecCsdS)aCGet one async result (only applies to remote repositories).

        async commands (== calls with wait=False, e.g. delete and put) have no results,
        but may raise exceptions. These async exceptions must get collected later via
        async_response() calls. Repeat the call until it returns None.
        The previous calls might either return one (non-None) result or raise an exception.
        If wait=True is given and there are outstanding responses, it will wait for them
        to arrive. With wait=False, it will only return already received responses.
        Nr,)r;rsr,r,r-�async_response�szRepository.async_responsecCsdS)z>Preload objects (only applies to remote repositories)
        Nr,)r;rpr,r,r-�preloadszRepository.preload)FFNTFNTF)NT)FTr�F)T)T)N)FFr)NN)NN)NN)F)T)T)T)Cr(r)r*r+rr.r/r0r1r2r3r4rr5r@rArBr:rYr]r`rj�propertyrk�staticmethodrrrzrVr�r�r�r�r�r�r�r�r�r�r�r^rWr�r�r�r�r�r�r�r�r�rRr	rdrerhr�rfrgrror�rqrtrurrrvrwr,r,r,r-r&5s�E�



##		
2


IG9
)

	

+	



r&c@s�eZdZGdd�de�Ze�d�Zejdks0J�e�d�Z	e	jdksHJ�e�d�Z
e
jdks`J�e�d	�Zejd
ksxJ�e
�de
�Ze�ee��eZdDdd
�Zdd�Zdd�Zeefdd�Zeefdd�ZdEdd�Zdd�Zdd�Zdd�Zd d!�Zd"d#�ZdFd$d%�Z d&d'�Z!d(d)�Z"d*d+�Z#d,d-�Z$d.d/�Z%d0d1�Z&d2d3�Z'dGd6d7�Z(d8d9�Z)dHd:d;�Z*dId<d=�Z+dJd>d?�Z,dKd@dA�Z-dLdBdC�Z.dS)Mr�c@seZdZdZdS)zLoggedIO.SegmentFullz2raised when a segment is full, before opening nextNr'r,r,r,r-r@sr@z<IIB�	z<IIB32s�)z<IB�z<Ir!�ZcCs>||_t||jd�|_d|_||_||_d|_d|_d|_	dS)N)Zdisposer)
rDr�	_close_fd�fdsr�rkr�rK�	_write_fd�_fds_cleaned)r;rDrkr�Zcapacityr,r,r-r:szLoggedIO.__init__cCs|��|j��d|_dSr6)�
close_segmentrrrXr,r,r-rW%s
zLoggedIO.closecCs&|\}}t|��ddd�|��dS)NrZDONTNEED)r rrW)r;�ts_fd�tsrqr,r,r-r~*szLoggedIO._close_fdcs��fdd�t�|�D�}|S)z�Returns generator yielding required segment dirs in data_dir as `os.DirEntry` objects.
        Start and end are inclusive.
        c3sB|]:}|��r|j��r�t|j�kr2�krnq|VqdSr6)�is_dirr r�r��r��f��	end_index�start_indexr,r-r�3s0�z,LoggedIO.get_segment_dirs.<locals>.<genexpr>�rC�scandir)r;�data_dirr�r��segment_dirsr,r�r-�get_segment_dirs/s�zLoggedIO.get_segment_dirscs��fdd�t�|�D�}|S)z�Returns generator yielding required segment files in segment_dir as `os.DirEntry` objects.
        Start and end are inclusive.
        c3sB|]:}|��r|j��r�t|j�kr2�krnq|VqdSr6)�is_filer r�r�r�r�r,r-r�>s0�z-LoggedIO.get_segment_files.<locals>.<genexpr>r�)r;�segment_dirr�r�Z
segment_filesr,r�r-�get_segment_files:s�zLoggedIO.get_segment_filesNFc	cs�|dur|stnt}||j}tj�|jd�}|sB|j||d�}n|j||d�}t|dd�|d�}|D]T}|s~|j||d�}n|j||d�}t|dd�|d�}|D]}t	|j
�|jfVq�qfdS)Nr})r�)r�cSs
t|j�Sr6�r�r )�dirr,r,r-�<lambda>NrOz+LoggedIO.segment_iterator.<locals>.<lambda>)r��reversecSs
t|j�Sr6r�rr,r,r-r�TrO)�MIN_SEGMENT_INDEX�MAX_SEGMENT_INDEXr�rCrDror�r�r�r�r )	r;r�r�Zstart_segment_dirZ	data_path�dirsr��filesrr,r,r-r�Es
zLoggedIO.segment_iteratorcCs |jdd�D]\}}|SdS)NT�r�)r��r;r�r�r,r,r-r�ZszLoggedIO.get_latest_segmentcCs,|jdd�D]\}}|�|�r|SqdS)z+Return the last committed segment.
        Tr�N)r��is_committed_segmentr�r,r,r-r�_s

z$LoggedIO.get_segments_transaction_idcCs^|��|d|_d}|jdd�D](\}}||krF|�|�|d7}q"qLq"t�d||�dS)z:Delete segment files left by aborted transactions
        rrTr�zICleaned up %d uncommitted segment files (== everything after segment %d).N)r�r�r�r/rfr)r;r�r0r�r�r,r,r-rbgs


�zLoggedIO.cleanupc
CsFz|�|�}Wnty"YdS0t|�|�d���}z|�|jjtj�WnNt	y�}z6|j
t
jkr�WYd}~Wd�dS|�WYd}~n
d}~00|�|jj�|j
kr�Wd�dSWd�n1s�0Yd}zt|�\}}}}	Wn.t�yYdSt�y&Y�qBYn0|tk�r8d}q�|r�dSq�|S)z4Check if segment ends with a COMMIT_TAG tag
        FrmNT)r<r
r^�segment_filename�seekr�r�rC�SEEK_ENDrcrd�EINVALrp�COMMITrlrmr=)
r;r��iteratorrqr�Zseen_commitrJr�rKrNr,r,r-r�vs4.
zLoggedIO.is_committed_segmentcCs"tj�|jdt||j�t|��S)Nr})rCrDror�r��r;r�r,r,r-r��szLoggedIO.segment_filenamecCs�|s,|s|jr,|j|jkr,|r$|j�|��|js�|j|jdkr�tj�	|jdt
|j|j��}tj�|�s�t�|�t
tj�	|jd��t|�|j�dd�|_|j�t�t|_|j|jvr�|j|j=|jS)Nrr}Tr�)rKrkr@r�r�r�r�rCrDror�r�r�rrr�r��MAGIC�	MAGIC_LENr)r;�no_new�want_newr8�dirnamer,r,r-�get_write_fd�s 

zLoggedIO.get_write_fdcsnt������fdd�}��fdd�}|�z�j�\}}WntyV|�}Yn0�j���|f�|S)Ncs"t����d�}�|f�j�<|S)Nrm)r^r�rr��nowr�r;r,r-�open_fd�sz LoggedIO.get_fd.<locals>.open_fdcsP��jtdkrL��_t�j���D]$\}}|\}}�|tkr&�j|=q&dS)Nr�)r�Z
FD_MAX_AGErrr
)�kr�r�rq)r�r;r,r-�	clean_old�sz"LoggedIO.get_fd.<locals>.clean_old)r^r_rrAZupd)r;r�r�r�r�rqr,r�r-�get_fd�szLoggedIO.get_fdcCs6|jd}|_|dur2|jd7_d|_|��dS)Nrr)r�r�rKrW)r;rqr,r,r-r��s
zLoggedIO.close_segmentcCs<||jvr|j|=zt|�|��Wnty6Yn0dSr6)rrr�rtr�r,r,r-r/�s
zLoggedIO.delete_segmentc	CsRtj�|jd�}|�|�}|D]&}zt�|�WqtyBYq0qt|�dS)zDDelete empty segment dirs, i.e those with no segment files.
        r}N)rCrDror��rmdirrcr)r;r�r�r�r,r,r-rH�s
zLoggedIO.clear_empty_dirscCs"|�|�}tj�|�o tj�|�Sr6)r�rCrDr�r�r�r,r,r-r:�s
zLoggedIO.segment_existscCstj�|�|��Sr6)rCrDr�r�r�r,r,r-r%�szLoggedIO.segment_sizecCs|�|�}|�d�|�t�S)Nr)r�r�rpr�)r;r�rqr,r,r-r��s

zLoggedIO.get_segment_magicrTc	cs�|�|�}|�|�|dkrD|�t�tkr@td|�dd�d���t}|�|jj�}|r�|j||j|||t	t
tf|d�\}}}	}
|r�||	||
fVn||	||fV||7}|�|�}|�|�|�|jj�}qRdS)a7
        Return object iterator for *segment*.

        If read_data is False then include_data must be False as well.
        Integrity checks are skipped: all data obtained from the iterator must be considered informational.

        The iterator returns four-tuples of (tag, key, offset, data|size).
        rzInvalid segment magic [segment z	, offset �]rVN)r�r�rpr�r�r
r�r��_readr>rCr=)r;r�rKr7rWrq�headerr�rJr�r}r,r,r-r<�s&	

�

zLoggedIO.iter_objectscCs�t�d|�||jvr |j|=tj�|�t|jjkrrt	|dd��}|�
t�Wd�n1sd0YdSt	|dd���P}t|d���"}t
j
|��dt
jd���}t|�}|}z�|�
t�t|�|jjk�rh|j�|d|jj��\}	}
}|
tk�s:|tk�s:|
|jjk�s:|
t|�k�s:t|d|
��d@|	k�rH|d	d�}q�|�
|d|
��||
d�}q�W~|��n~|��0Wd�n1�s�0YWd�n1�s�0YWd�n1�s�0YdS)
Nzattempting to recover Tr�rmr)�accessr!���r)rfr*rrCrDr�r�r�r�rr�r�r^�mmaprZACCESS_READ�
memoryviewr#r�r$�
MAX_TAG_IDr!r�)r;r�r�rqZdst_fdZsrc_fdZmmr}�d�crcr�rJr,r,r-r`"s:
(
"
��
�zLoggedIO.recover_segmentc	Cs�||jkr|jr|j��|�|�}|�|�|�|jj�}|�||j|||t	f|�\}}}	}
||	krvt
d�||���|r~|
S|S)z�
        Read entry from *segment* at *offset* with *id*.

        If read_data is False the size of the entry is returned instead and integrity checks are skipped.
        The return value should thus be considered informational.
        zJInvalid segment entry header, is not for wanted id [segment {}, offset {}])r�r��syncr�r�rprBr�r�r>r
�format)r;r�rKr<rWrqr�r�rJr�r}r,r,r-rpAs


"�z
LoggedIO.readc
Cs(t|�tksJd��z|�|�}Wn:tjy\}	z td�|||	��d�WYd}	~	n
d}	~	00||jurv|\}
}}}
n"||jur�|\}
}}d}
nt	d��|t
kr�td�|||���||jkr�td�|||���||j}|�rv|�|�}t
|�|k�rtd�|||t
|����t|tt|�dd���d@|
k�rBtd	�||���|
du�r|ttfv�r|dd
�|d
d�}
}n�|
du�r�|ttfv�r�|�d
�}
|d
8}t
|
�d
k�r�td�||d
t
|
����|��}|�|tj�|}d}||k�rtd�||||���||v�rtd
�||���|||
|fS)Nz7Exceeding MAX_TAG_ID will break backwards compatibilityz8Invalid segment entry header [segment {}, offset {}]: {}z$_read called with unsupported formatz?Invalid segment entry size {} - too big [segment {}, offset {}]zAInvalid segment entry size {} - too small [segment {}, offset {}]zPSegment entry data short read [segment {}, offset {}]: expected {}, got {} bytesr!r�z7Segment entry checksum mismatch [segment {}, offset {}]r�zOSegment entry key short read [segment {}, offset {}]: expected {}, got {} byteszPSegment entry data short seek [segment {}, offset {}]: expected {}, got {} byteszPInvalid segment entry header, did not get acceptable tag [segment {}, offset {}])�maxr�r��structr)r
r�rBr��	TypeErrorr$r�rpr#r!r�r>rC�tellr�rC�SEEK_CUR)r;rq�fmtr�r�rKZacceptable_tagsrWZ	hdr_tupler�r�r�rJr��lengthr}ZoldposZseekedr,r,r-r�Ssn��


�
�

�$�
�
�
�zLoggedIO._readc
Cs�t|�}|tkr&td|�dt�d���|j|tjk|d�}||jj}|j}|j	�
|t�}|j�
t
|t
|t
|���d@�}	|�d�|	|||f��|j|7_|j|fS)NzMore than allowed put data [z > r��r�r8r�rO)r#Z
MAX_DATA_SIZEr
r�r�MANIFEST_IDrBr�rK�header_no_crc_fmtrr>�crc_fmtr!r�ror�)
r;r<r}r8�	data_sizerqr�rKr�r�r,r,r-r?�s zLoggedIO.write_putcCsv|j|tjk|d�}|j�|jjt�}|j�t	|t	|��d@�}|�
d�|||f��|j|jj7_|j
|jjfS)Nr�r�rO)r�rr�r�rrBr�rCr�r!r�rorKr�)r;r<r8rqr�r�r,r,r-rE�szLoggedIO.write_deletecCsh|j||d�}|r|��|j�|jjt�}|j�t|�d@�}|�	d�
||f��|��|jdS)N)r�r�r�rOr)
r�r�r�rr�r�r=r�r!r�ror�r�)r;r,rqr�r�r,r,r-r��szLoggedIO.write_commit)r})NF)FFF)rFT)T)T)F)F)F)/r(r)r*r�r@r��Structr�r�rBr�r�rr=Z_commitr!r�r:rWr~ZMIN_SEGMENT_DIR_INDEXZMAX_SEGMENT_DIR_INDEXr�r�r�r�r�r�r�rbr�r�r�r�r�r/rHr:r%r�r<r`rpr�r?rEr�r,r,r,r-r�
sJ






 
 
%

7

r�r{)Drdr�rCr�rsr�r^Zbinasciirr�collectionsrZconfigparserr�	functoolsr�	itertoolsrZ	constantsZ	hashindexr
Zhelpersrrr
rrrrrrrrrrZlockingrrrrfrZlrucacher�platformrrrr Zalgorithms.checksumsr!Zcrypto.file_integrityr"r#r(r�r#r�r�r>rCr=r�r�rr&r�rBr�r,r,r,r-�<module>sh	
^&