
    Je9                         d Z ddlZddlZddlmZmZmZ ddlmZm	Z	m
Z
 	 ddlmZmZmZmZ d Z G d	 d
e      Z G d de      Zedk(  rddlZ ej.                          yy# e$ r	  ed      w xY w)a
  This module implements a bloom filter probabilistic data structure and
an a Scalable Bloom Filter that grows in size as your add more items to it
without increasing the false positive error_rate.

Requires the bitarray library: http://pypi.python.org/pypi/bitarray/
    N   )range_fnis_string_iorunning_python_3)unpackpackcalcsize)	QBitArrayQFileQDataStream	QIODevicez&pybloom_pyqt requires QtCore.QBitArrayc                    	
 dk\  rd\  }}ndk\  rd\  }}nd\  }}d z  |z  }|dkD  rt         j                  	nR|dkD  rt         j                  	n<|d	kD  rt         j                  	n&|d
kD  rt         j                  	nt         j
                  	| 	       j                  |z  z  t         t                    \  }}|r|dz  }t        	fdt        d|      D              
 
fd}|	fS )Nl        )Q   i   )I   )H   r   i           r   c           	   3   j   K   | ]*  }  t        d |            j                                , yw)r   N)r   digest).0ihashfns     L/usr/lib/python3/dist-packages/spyder/utils/external/pybloom_pyqt/pybloom.py	<genexpr>z!make_hashfuncs.<locals>.<genexpr>)   s2      3 S!-4467 3s   03r   c              3     K   t         r=t        | t              r| j                  d      } nHt        |       j                  d      } n-t        | t              r| j                  d      } nt        |       } d}D ]V  }|j                         }|j                  |        t        |j                               D ]  }|z   |dz  }|k\  s  y  X y w)Nzutf-8r   r   )	r   
isinstancestrencodeunicodecopyupdater   r   )	keyr   salthuintfmtnum_bits
num_slicessaltss	        r   _hash_makerz#make_hashfuncs.<locals>._hash_maker,   s     #s#jj)#hoog.#w'jj)#h 	D		AHHSMsAHHJ/ Xo%Q
?		s   CCC)hashlibsha512sha384sha256sha1md5digest_sizedivmodlentupler   )r,   r+   fmt_code
chunk_sizetotal_hash_bits	num_saltsextrar.   r*   r   r-   s   ``      @@@r   make_hashfuncsr>      s    G%*	g	%*%**nz1O	3		3		3	
fh**j8
9Cj#c(3IuQ	 3#Ay13 3E*     c                   r    e Zd ZdZddZd Zd Zd ZddZd Z	d Z
d	 Zd
 Zd Zd Zed        Zd Zd Zy)BloomFilters   <dQQQQc           
         d|cxk  rdk  st        d       t        d      |dkD  st        d      t        t        j                  t        j                  d|z  d                  }t        t        j                  |t        t        j                  |            z  |t        j                  d      dz  z  z              }| j                  ||||d       t        | j                        | _	        y)a  Implements a space-efficient probabilistic data structure

        capacity
            this BloomFilter must be able to store at least *capacity* elements
            while maintaining no more than *error_rate* chance of false
            positives
        error_rate
            the error_rate of the filter returning false positives. This
            determines the filters capacity. Inserting more than capacity
            elements greatly increases the chance of false positives.
        r   r   z#Error_Rate must be between 0 and 1.zCapacity must be > 0g      ?r   N)

ValueErrorintmathceillogabs_setupr
   r+   bitarray)selfcapacity
error_rater,   bits_per_slices        r   __init__zBloomFilter.__init__G   s     J""BCC #BCC!|344 488C*,<a#@AB
TYYDHHZ011488A;!+,./ 0 	J
NHaH!$--0r?   c                     || _         || _        || _        || _        ||z  | _        || _        t        | j                  | j                        \  | _        | _        y N)	rM   r,   rN   rL   r+   countr>   make_hashesr   )rK   rM   r,   rN   rL   rR   s         r   rI   zBloomFilter._setupd   sV    $$, "^3
(6t7;7J7J)L%$+r?   c                     | j                   }| j                  }| j                  |      }d}|D ]  }|||z      s y||z  } y)7Tests a key's membership in this bloom filter.
        r   FT)rN   rJ   rS   )rK   r&   rN   rJ   hashesoffsetks          r   __contains__zBloomFilter.__contains__n   sZ     ,,==!!#& 	%AFQJ'n$F	% r?   c                     | j                   S )z6Return the number of keys stored by this bloom filter.rR   rK   s    r   __len__zBloomFilter.__len__{   s    zzr?   c                 v   | j                   }| j                  }| j                  |      }d}| j                  | j                  kD  rt        d      d}|D ]3  }|s|r
|||z      sd}| j                   j                  ||z          ||z  }5 |r| xj                  dz  c_        y|s| xj                  dz  c_        yy)z Adds a key to this bloom filter. If the key already exists in this
        filter it will return True. Otherwise False.
        TzBloomFilter is at capacityr   Fr   )rJ   rN   rS   rR   rL   
IndexErrorsetBit)	rK   r&   
skip_checkrJ   rN   rV   found_all_bitsrW   rX   s	            r   addzBloomFilter.add   s     ==,,!!#&::%9:: 	%A.&1*9M!&MM  !,n$F		% JJ!OJJJ!OJr?   c                 z    t        | j                  | j                        }t        | j                        |_        |S )z,Return a copy of this bloom filter.
        )rA   rL   rM   r
   rJ   )rK   
new_filters     r   r$   zBloomFilter.copy   s/     !@
'6
r?   c                     | j                   |j                   k7  s| j                  |j                  k7  rt        d      | j                         }|j                  |j                  z  |_        |S )zd Calculates the union of the two underlying bitarrays and returns
        a new bloom filter object.zTUnioning filters requires both filters to have both the same capacity and error raterL   rM   rC   r$   rJ   rK   other	new_blooms      r   unionzBloomFilter.union   sc     ==ENN*5#3#33 E F FIIK	&//%..@	r?   c                 $    | j                  |      S rQ   rk   rK   ri   s     r   __or__zBloomFilter.__or__       zz%  r?   c                     | j                   |j                   k7  s| j                  |j                  k7  rt        d      | j                         }|j                  |j                  z  |_        |S )zk Calculates the intersection of the two underlying bitarrays and
        returns a new bloom filter object.zPIntersecting filters requires both filters to have equal capacity and error raterg   rh   s      r   intersectionzBloomFilter.intersection   sc     ==ENN*5#3#33 B C CIIK	&//%..@	r?   c                 $    | j                  |      S rQ   )rr   rn   s     r   __and__zBloomFilter.__and__   s      ''r?   c                    t        |      }|j                  t        j                        rt	        |      }|j                  | j                         |j                  | j                         |j                  | j                         |j                  | j                         |j                  | j                         |j                  | j                         || j                  z   |j                          |j!                          yy)zWrite the bloom filter to file object `f'. Underlying bits
        are written as machine values. This is much more space
        efficient than pickling the object.N)r   openr   	WriteOnlyr   
writeBytesFILE_FMT
writeFloatrM   writeIntr,   rN   rL   rR   rJ   flushclose)rK   pathfouts       r   tofilezBloomFilter.tofile   s     $K66)%%&a.CNN4==)NN4??+LL)LL,,-LL'LL$4== GGIGGI 'r?   c                 
   t        |      }|j                  t        j                        st	        d|z         t        |      }|j                         }|| j                  k7  rt	        d      |j                         }|j                         }|j                         }|j                         }|j                         }	t               }
 | d      }|j                  |||||	       t               |_        ||j                  z	   |S )zYRead a bloom filter from file-object `f' serialized with
        ``BloomFilter.tofile''. zunable to open file zunexpected file formatr   )r   rv   r   ReadOnlyrC   r   	readBytesry   	readFloatreadIntr
   rI   rJ   )clsr~   r   datafile_fmtrM   r,   rN   rL   rR   rJ   filters               r   fromfilezBloomFilter.fromfile   s     $Kvvi(()3d:;;1~>>#s||#566^^%
\\^
<<>;Qj*nhN#+r?   c                 @    | j                   j                         }|d= |S )NrS   )__dict__r$   rK   ds     r   __getstate__zBloomFilter.__getstate__   s!    MM mr?   c                     | j                   j                  |       t        | j                  | j                        \  | _        | _        y rQ   )r   r%   r>   r,   rN   rS   r   r   s     r   __setstate__zBloomFilter.__setstate__   s8    Q(6t7;7J7J)L%$+r?   N)MbP?)F)__name__
__module____qualname__ry   rO   rI   rY   r]   rc   r$   rk   ro   rr   rt   r   classmethodr   r   r    r?   r   rA   rA   D   s^    H1:L4	!	((  4
Lr?   rA   c                       e Zd ZdZdZdZddefdZd Zd Zd	 Z	d
 Z
d Zd Zed        Zed        Zd Zed        Zd Zy)ScalableBloomFilterr   r   z<idQdd   r   c                 ^    |r|dk  rt        d      | j                  |d||       g | _        y)a  Implements a space-efficient probabilistic data structure that
        grows as more items are added while maintaining a steady false
        positive rate

        initial_capacity
            the initial capacity of the filter
        error_rate
            the error_rate of the filter returning false positives. This
            determines the filters capacity. Going over capacity greatly
            increases the chance of false positives.
        mode
            can be either ScalableBloomFilter.SMALL_SET_GROWTH or
            ScalableBloomFilter.LARGE_SET_GROWTH. SMALL_SET_GROWTH is slower
            but uses less memory. LARGE_SET_GROWTH is faster but consumes
            memory faster.
        r   z)Error_Rate must be a decimal less than 0.g?N)rC   rI   filters)rK   initial_capacityrM   modes       r   rO   zScalableBloomFilter.__init__   s3    $ Z!^HIID#/<r?   c                 <    || _         || _        || _        || _        y rQ   )scaleratior   rM   )rK   r   r   r   rM   s        r   rI   zScalableBloomFilter._setup  s    

 0$r?   c                 D    t        | j                        D ]  }||v s y y)rU   TF)reversedr   )rK   r&   r   s      r   rY   z ScalableBloomFilter.__contains__  s+     $,,' 	Aax	 r?   c                    || v ry| j                   sJt        | j                  | j                  | j                  z        }| j                   j                  |       n~| j                   d   }|j                  |j                  k\  rVt        |j                  | j                  z  |j                  | j                  z        }| j                   j                  |       |j                  |d       y)zAdds a key to this bloom filter.
        If the key already exists in this filter it will return True.
        Otherwise False.
        T)rL   rM   )ra   F)
r   rA   r   rM   r   appendrR   rL   r   rc   )rK   r&   r   s      r   rc   zScalableBloomFilter.add   s    
 $;|| ..??TZZ79F LL'\\"%F||v.$#__tzz9%004::=? ##F+

34
(r?   c                     t        | j                  | j                  | j                        }| j                  D ]+  }|j                  j                  |j                                - |S )z Returns a clone of this instance.
        This is used instead of copy.deepcopy because QBitArray
        is not pickle-able (error can't pickle QBitArray objects) )r   r   rM   r   r   r   r$   )rK   clonedr   s      r   r$   zScalableBloomFilter.copy6  sV     %T%:%:%)__%)ZZ1  	,ANN!!!&&(+	,r?   c                    | j                   |j                   k7  s2| j                  |j                  k7  s| j                  |j                  k7  rt        d      t	        | j
                        t	        |j
                        kD  r| j                         }|}n|j                         }| }g }t        t	        |j
                              D ]2  }|j
                  |   |j
                  |   z  }|j                  |       4 t        t	        |j
                        t	        |j
                              D ]   }|j                  |j
                  |          " ||_        |S )zu Calculates the union of the underlying classic bloom filters and
        returns a new scalable bloom filter object.zuUnioning two scalable bloom filters requires both filters to have both the same mode, initial capacity and error rate)	r   r   rM   rC   r7   r   r$   ranger   )rK   ri   
larger_sbfsmaller_sbfnew_filtersr   re   s          r   rk   zScalableBloomFilter.unionA  s1    ::$%%)?)??5#3#33 ? @ @ t||s5==11JKJKs;../0 	+A#++A.1D1DQ1GGJz*	+ s;../Z5G5G1HI 	6Az11!45	6(
r?   c                 $    | j                  |      S rQ   rm   rn   s     r   ro   zScalableBloomFilter.__or__[  rp   r?   c                 :    t        d | j                  D              S )z6Returns the total capacity for all filters in this SBFc              3   4   K   | ]  }|j                     y wrQ   )rL   r   r   s     r   r   z/ScalableBloomFilter.capacity.<locals>.<genexpr>a  s     4!1::4   sumr   r\   s    r   rL   zScalableBloomFilter.capacity^  s     4t||444r?   c                     t        |       S rQ   )r7   r\   s    r   rR   zScalableBloomFilter.countc  s    4yr?   c           	         |j                  t        | j                  | j                  | j                  | j
                  | j                               |j                  t        dt        | j                                     t        | j                        dkD  r|j                         }ddt        | j                        z  z   }|j                  dt        |      z         g }| j                  D ]E  }|j                         }|j                  |       |j                  |j                         |z
         G |j                  |       |j                  t        |g|        yy)zDSerialize this ScalableBloomFilter into the file-object
        `f'.   <lr      <   Q   .N)writer   ry   r   r   r   rM   r7   r   tellr	   r   r   seek)rK   r   	headerpos	headerfmtfilter_sizesr   begins          r   r   zScalableBloomFilter.tofileg  s    	
T]]DJJ

**DOO= 	> 	
UC-./t||q  Its4<<'899IGGD8I../L,, 6a ##AFFHu$456
 FF9GGD2\23 !r?   c           
          |        } |j                   t        | j                  |j                  t	        | j                                      t        d|j                  t	        d                  \  }|dkD  rfdd|z  z   }|j                  t	        |            }t        ||      }|D ]1  }|j
                  j                  t        j                  ||             3 |S g |_        |S )z7Deserialize the ScalableBloomFilter in file object `f'.r   r   r   r   )	rI   r   ry   readr	   r   r   rA   r   )r   r   r   nfilters
header_fmtbytesfilter_lengthsfls           r   r   zScalableBloomFilter.fromfile  s     vcllAFF8CLL3I,JKL5!&&%"9:	a<x/JFF8J/0E#J6N$ C%%k&:&:1b&ABC
   FNr?   c                 :    t        d | j                  D              S )z7Returns the total number of elements stored in this SBFc              3   4   K   | ]  }|j                     y wrQ   r[   r   s     r   r   z.ScalableBloomFilter.__len__.<locals>.<genexpr>  s     1q1771r   r   r\   s    r   r]   zScalableBloomFilter.__len__  s    1DLL111r?   N)r   r   r   SMALL_SET_GROWTHLARGE_SET_GROWTHry   rO   rI   rY   rc   r$   rk   ro   propertyrL   rR   r   r   r   r]   r   r?   r   r   r      s    H(+&.%,	4! 5 5  40   2r?   r   __main__)__doc__rE   r/   utilsr   r   r   structr   r   r	   qtpy.QtCorer
   r   r   r   ImportErrorr>   objectrA   r   r   doctesttestmodr   r?   r   <module>r      s      ; ; ) )@DD
/doL& oLd\2& \2~ zGOO O  @
>
??@s   A! !A/