
                             d Z ddlmZ ddlmZ ddlmZ ddlmZ ddlZddlZddlZej                  re
Zg dZg dZd	 Zd
Zd
ez  Zd
ez  Zdez  Zdez  Zdez  Z ed      Z e       \  ZZd Zd Zd Zd Zd ZddZd Zd Zd fdZ d Z!y)zCShared utility methods that calculate, convert, and simplify units.    )absolute_import)print_function)division)unicode_literalsN))r   Bbit)
   KiBKibitK)   MiBMibitM)   GiBGibitG)(   TiBTibitT)2   PiBPibitP)<   EiBEibitE))   k)   m)	   b)   t)   qc                  ,   d} g }i }t        t              D ]K  \  }}t        |      dd D cg c]  }|j                          }}|D ]  }|||<   	 |j	                  |       M | dj                  |      z  } t        j                  |       }||fS c c}w )z6Creates a suffix regex for human-readable byte counts.z'(?P<num>\d*\.\d+|\d+)\s*(?P<suffix>%s)?   N|)	enumerate_EXP_STRINGSlistlowerextendjoinrecompile)	human_bytes_resuffixessuffix_to_siisissi_suffixessuffixmatchers	            (platform/gsutil/gslib/utils/unit_util.py_GenerateSuffixRegexr@   3   s    =.(,&ea&*2hqrl3l1779lK3l6 OOK 	 '
 CHHX&&.JJ~&'	w	 4s   Bi         r	   iQ c                    d}|dz   t        t              k  rE| dt        |dz      d   z  k\  r0|dz  }|dz   t        t              k  r| dt        |dz      d   z  k\  r0|t        t        |       dt        |   d   z  z  d      fS )Nr   r,   rA          @)lenr/   roundfloat)numr9   s     r?   _RoundToNearestExponentrI   Q   s    !	AL!!caa!e1DQ1G.G&HFA 	
AL!!caa!e1DQ1G.G&H	
E%*sLOA$666:	::    c                 >    |dk  rd}t        |       t        |      z  S )a   Calculates throughput and checks for a small total_elapsed_time.

  Args:
    total_bytes_transferred: Total bytes transferred in a period of time.
    total_elapsed_time: The amount of time elapsed in seconds.

  Returns:
    The throughput as a float.
  g{Gz?)rG   )total_bytes_transferredtotal_elapsed_times     r?   CalculateThroughputrN   X   s)     $	&	'%0B*C	CCrJ   c                     t        t              D ](  \  }}| d|z  k\  sdt        |       d|z  z  z  }||z   c S  t        |       S )a  Creates a shorter string version for a given number of objects.

  Args:
    num: The number of objects to be shortened.
  Returns:
    shortened string version for this number. It takes the largest
    scale (thousand, million or billion) smaller than the number and divides it
    by that scale, indicated by a suffix with one decimal place. This will thus
    create a string of at most 6 characters, assuming num < 10^18.
    Example: 123456789 => 123.4m
  r	   z%.1lf)reversed_EXP_TEN_STRINGrG   str)rH   divisor_expr=   quotients       r?   DecimalShortrU   g   sQ     &o6k6
b+oE#J[89h 7 
S/rJ   c                 *    | |z  }| |z  dk7  r|dz  }|S )a  Returns ceil(dividend / divisor).

  Takes care to avoid the pitfalls of floating point arithmetic that could
  otherwise yield the wrong result for large numbers.

  Args:
    dividend: Dividend for the operation.
    divisor: Divisor for the operation.

  Returns:
    Quotient.
  r   r,    )dividenddivisorrT   s      r?   DivideAndCeilrZ   z   s)      (QMH	/rJ   c                 B   | j                         } t        j                  |       }|rkt        |j	                  d            }|j	                  d      r*t
        t        |j	                  d            d   }|d|z  z  }t        t        |            }|S t        d| z        )zTries to convert a human-readable string to a number of bytes.

  Args:
    human_string: A string supplied by user, e.g. '1M', '3 GiB'.
  Returns:
    An integer containing the number of bytes.
  Raises:
    ValueError: on an invalid string.
  rH   r=   r   rD   z!Invalid byte string specified: %s)
r1   MATCH_HUMAN_BYTESmatchrG   groupr/   SUFFIX_TO_SIintrF   
ValueError)human_stringr$   rH   powers       r?   HumanReadableToBytesrd      s     ##%,l+!

Cwwx<(9:;A>e	c5jc
eCj/CJ6EFFrJ   c                 0   t        |       j                         }t        t        t	        d|z  t        |d         z                    }|dk(  rd|rdd|z  z   ndz   |d<   n&t        |      }|r|d||z
   dz   |||z
  d z   }||d<   dj                  |      S )a  Creates a human readable format for bytes with fixed decimal places.

  Args:
    number: The number of bytes.
    decimal_places: The number of decimal places.
  Returns:
    String representing a readable format for number with decimal_places
     decimal places.
  r	   r   0. N )MakeHumanReadablesplitrR   r`   rF   rG   rE   r3   )numberdecimal_placesnumber_formatrH   
num_lengths        r?   HumanReadableWithDecimalPlacesrp      s     $F+113-Cb.(5q1A+BBCDE#CZ5C /1IKMM! SJ-*~-.4n,-./cM!	-	  rJ   c                 @    t        |       \  }}d|t        |   d   fz  S )zGenerates human readable string for a number of bits.

  Args:
    num: The number, in bits.

  Returns:
    A string form of the number using bit size abbreviations (kbit, Mbit, etc.)
  %g %srA   rI   r/   rH   r9   rounded_vals      r?   MakeBitsHumanReadablerv      +     +3/.![	Ka!34	44rJ   c                 @    t        |       \  }}d|t        |   d   fz  S )zGenerates human readable string for a number of bytes.

  Args:
    num: The number, in bytes.

  Returns:
    A string form of the number using size abbreviations (KiB, MiB, etc.).
  rr   r,   rs   rt   s      r?   rj   rj      rw   rJ   c                     | S )NrW   )xs    r?   <lambda>r{      s    arJ   c                 "   | syt        |       dz
  |z  }t        j                  |      }t        j                  |      }||k(  r || t	        |               S  || t	        |               ||z
  z  } || t	        |               ||z
  z  }||z   S )a  Find the percentile of a list of values.

  Taken from: http://code.activestate.com/recipes/511478/

  Args:
    values: a list of numeric values. Note that the values MUST BE already
            sorted.
    percent: a float value from 0.0 to 1.0.
    key: optional key function to compute value from each element of the list
         of values.

  Returns:
    The percentile of the values.
  Nr,   )rE   mathfloorceilr`   )valuespercentkeyr"   fcd0d1s           r?   
Percentiler      s     

6{Q'!!
jjm!
iil!!Vvc!f~
6#a&>a!e$"
6#a&>a!e$"	b.rJ   c                     t        t        |             } | dz  }|dk\  rdt        |d      z  S | d|z  z  } | dz  }| d|z  z  } | }t        d|z        dz   t        d|z        z   dz   t        d|z        z   S )aD  Creates a standard version for a given remaining time in seconds.

  Created over using strftime because strftime seems to be
    more suitable for a datetime object, rather than just a number of
    seconds remaining.
  Args:
    remaining_time: The number of seconds remaining as a float, or a
      string/None value indicating time was not correctly calculated.
  Returns:
    if remaining_time is a valid float, %H:%M:%D time remaining format with
    the nearest integer from remaining_time (%H might be higher than 23).
    Else, it returns the same message it received.
  i  d   z%d+ hrsi  r   z%02d:)r`   rF   minrR   )remaining_timehoursminutessecondss       r?   
PrettyTimer      s     u^,-.
D
 %
c\ s5#&&TE\".b 'R'\".'
fun

#c&7*:&;
;c
A
fw
  !rJ   )r,   )"__doc__
__future__r   r   r   r   r}   r4   sixPY3r`   longr/   rQ   r@   ONE_KIBONE_MIBONE_GIBTWO_MIB	EIGHT_MIBTEN_MIBSECONDS_PER_DAYr_   r\   rI   rN   rU   rZ   rd   rp   rv   rj   r   r   rW   rJ   r?   <module>r      s    J & %  '  	 
77	$" 
.
. g+K	
w,|$"6"8 ;D&&G,!2
5
5 %0 6!rJ   