U
    楡c>                     @   s   d Z ddlZddlZddlmZmZ ddlmZ ddddd	d
gZdd Zdd ZG dd dZ	G dd dZ
G dd	 d	eZdS )zlModule containing a memory memory manager which provides a sliding window on a number of memory mapped files    N)mmapACCESS_READALLOCATIONGRANULARITYalign_to_mmap	is_64_bit	MapWindow	MapRegionMapRegionListr   c                 C   s$   | t  t  }|r || kr |t 7 }|S )a=  
    Align the given integer number to the closest page offset, which usually is 4096 bytes.

    :param round_up: if True, the next higher multiple of page size is used, otherwise
        the lower page_size will be used (i.e. if True, 1 becomes 4096, otherwise it becomes 0)
    :return: num rounded to closest pager   )numZround_upres r   ./tmp/pip-unpacked-wheel-tps8jdza/smmap/util.pyr      s    c                   C   s
   t jdkS )zO:return: True if the system is 64 bit. Otherwise it can be assumed to be 32 bitl    )sysmaxsizer   r   r   r   r      s    c                   @   sP   e Zd ZdZdZdd Zdd Zedd Zd	d
 Z	dd Z
dd Zdd ZdS )r   zWUtility type which is used to snap windows towards each other, and to adjust their sizeofssizec                 C   s   || _ || _d S Nr   )selfoffsetr   r   r   r   __init__-   s    zMapWindow.__init__c                 C   s   d| j | jf S )NzMapWindow(%i, %i)r   r   r   r   r   __repr__1   s    zMapWindow.__repr__c                 C   s   | |j | S )z!:return: new window from a region_br   )clsZregionr   r   r   from_region4   s    zMapWindow.from_regionc                 C   s   | j | j S r   r   r   r   r   r   ofs_end9   s    zMapWindow.ofs_endc                 C   s8   t | jd}|  j| j| 7  _|| _t | jd| _dS )z<Assures the previous window area is contained in the new oner      N)r   r   r   )r   Znofsr   r   r   align<   s    zMapWindow.alignc                 C   sH   | j |  }|| j }||t|| 8 }| j | | _ |  j|7  _dS )zAdjust the offset to start where the given window on our left ends if possible,
        but don't make yourself larger than max_size.
        The resize will assure that the new window still contains the old window areaN)r   r   r   min)r   windowmax_sizeZrofsZnsizer   r   r   extend_left_toC   s
    
zMapWindow.extend_left_toc                 C   s    t | j|j|    || _dS )zpAdjust the size to make our window end where the right window begins, but don't
        get larger than max_sizeN)r!   r   r   r   )r   r"   r#   r   r   r   extend_right_toM   s    zMapWindow.extend_right_toN)__name__
__module____qualname____doc__	__slots__r   r   classmethodr   r   r    r$   r%   r   r   r   r   r   %   s   

c                   @   sz   e Zd ZdZdddddgZd 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S )"r	   z{Defines a mapped region of memory, aligned to pagesizes

    **Note:** deallocates used region automatically on destructionr   _mf_uc_size__weakref__r   c           
   	   C   s   || _ d| _d| _t|tr"|}nt|tjttddB |B }zJtt|d}|}|}tt|j| |}	t||	f|| _t| j| _W 5 t|t	rt
| X |   dS )a  Initialize a region, allocate the memory map
        :param path_or_fd: path to the file to map, or the opened file descriptor
        :param ofs: **aligned** offset into the file to be mapped
        :param size: if size is larger then the file on disk, the whole file will be
            allocated the the size automatically adjusted
        :param flags: additional flags to be given when opening the file.
        :raise Exception: if no memory can be allocatedr   O_BINARY)accessr   N)r   r.   r-   
isinstanceintosopenO_RDONLYgetattrstrclosedictr   r!   fstatst_sizer   r,   lenincrement_client_count)
r   
path_or_fdr   r   flagsfdkwargsZcorrected_sizeZsizeofsZactual_sizer   r   r   r   c   s     

zMapRegion.__init__c                 C   s   d| j |  f S )NzMapRegion<%i, %i>r   r   r   r   r   r      s    zMapRegion.__repr__c                 C   s   | j S )z':return: a buffer containing the memoryr,   r   r   r   r   buffer   s    zMapRegion.bufferc                 C   s   | j S )z+:return: a memory map containing the memoryrC   r   r   r   r   map   s    zMapRegion.mapc                 C   s   | j S )z>:return: absolute byte offset to the first byte of the mapping)r   r   r   r   r   	ofs_begin   s    zMapRegion.ofs_beginc                 C   s   | j S )z1:return: total size of the mapped region in bytes)r.   r   r   r   r   r      s    zMapRegion.sizec                 C   s   | j | j S )zE:return: Absolute offset to one byte beyond the mapping into the filer   r.   r   r   r   r   r      s    zMapRegion.ofs_endc                 C   s"   | j |  ko| j | j k S   S )zB:return: True if the given offset can be read in our mapped regionrG   r   r   r   r   r   includes_ofs   s    zMapRegion.includes_ofsc                 C   s   | j S )z6:return: number of clients currently using this region)r-   r   r   r   r   client_count   s    zMapRegion.client_countr   c                 C   sF   |  j |7  _ | j dks&td| j  |  dkr>|   dS dS dS )zAdjust the usage count by the given positive or negative offset.
        If usage count equals 0, we will auto-release our resources
        :return: True if we released resources, False otherwise. In the latter case, we can still be usedz<Increments must match decrements, usage counter negative: %ir   TFN)r-   AssertionErrorrJ   releaserH   r   r   r   r>      s    z MapRegion.increment_client_countc                 C   s   | j   dS )zbRelease all resources this instance might hold. Must only be called if there usage_count() is zeroN)r,   r9   r   r   r   r   rM      s    zMapRegion.releaseN)r   )r   )r&   r'   r(   r)   r*   r   r   rD   rE   rF   r   r   rI   rJ   r>   rM   r   r   r   r   r	   S   s$   
'
c                       s<   e Zd ZdZdZ fddZdd Zdd Zd	d
 Z  Z	S )r
   zFList of MapRegion instances associating a path with a list of regions._path_or_fd
_file_sizec                    s   t  | S r   )super__new__)r   path	__class__r   r   rR      s    zMapRegionList.__new__c                 C   s   || _ d | _d S r   rN   )r   r?   r   r   r   r      s    zMapRegionList.__init__c                 C   s   | j S )z3:return: path or file descriptor we are attached to)rO   r   r   r   r   r?      s    zMapRegionList.path_or_fdc                 C   s>   | j dkr8t| jtr(t| jj| _ nt| jj| _ | j S )z :return: size of file we managerN)rP   r2   rO   r8   r4   statr<   r;   r   r   r   r   	file_size   s
    
zMapRegionList.file_size)
r&   r'   r(   r)   r*   rR   r   r?   rW   __classcell__r   r   rT   r   r
      s   )r)   r4   r   r   r   r   __all__r   r   r   r	   listr
   r   r   r   r   <module>   s      	.m