
    G@d9                         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 n# e$ r  ed          w xY wd Z G d	 d
e          Z G d de          Zedk    rddlZ ej                     dS dS )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k    rt           j        	nE|dk    rt           j        	n2|d	k    rt           j        	n|d
k    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      K   | ]8}  t          d |                                                              V  9dS )r   N)r   digest).0ihashfns     Jlib/python3.11/site-packages/spyder/utils/external/pybloom_pyqt/pybloom.py	<genexpr>z!make_hashfuncs.<locals>.<genexpr>)   s_       3 3 &S!--446677 3 3 3 3 3 3    r   c              3      K   t           rNt          | t                    r|                     d          } n]t          |                               d          } n:t          | t                    r|                     d          } nt          |           } d}D ]f}|                                }|                    |            t          |                                          D ]}|z  V  |dz  }|k    r  d S gd S )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))#hhoog..#w'' jj))#hh 	 	D		AHHSMMMsAHHJJ//  Xo%%%Q
??FFF #	 	r   )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		
ffhh*j8
9Cj#c((33Iu Q	 3 3 3 3#Ay113 3 3 3 3E       * r   c                   z    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dS )BloomFilters   <dQQQQMbP?c           
         d|cxk     rdk     sn t          d          |dk    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                      }|                     ||||d           t          | j                  | _	        dS )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C!||3444 48C*,<a#@#@AABB
TYDHZ0011148A;;!+,./ / 0 0 	J
NHaHHH!$-00r   c                     || _         || _        || _        || _        ||z  | _        || _        t          | j        | j                  \  | _        | _        d S N)	rN   r-   rO   rM   r,   countr?   make_hashesr   )rL   rN   r-   rO   rM   rS   s         r   rJ   zBloomFilter._setupd   s[    $$, "^3
(6t7;7J)L )L%$+++r   c                     | j         }| j        }|                     |          }d}|D ]}|||z            s dS ||z  }dS )7Tests a key's membership in this bloom filter.
        r   FT)rO   rK   rT   )rL   r'   rO   rK   hashesoffsetks          r   __contains__zBloomFilter.__contains__n   sc     ,=!!#&& 	% 	%AFQJ' uun$FFtr   c                     | j         S )z6Return the number of keys stored by this bloom filter.rS   rL   s    r   __len__zBloomFilter.__len__{   s
    zr   Fc                 R   | j         }| j        }|                     |          }d}| j        | j        k    rt          d          d}|D ]5}|s|r|||z            sd}| j                             ||z              ||z  }6|r| xj        dz  c_        dS |s| xj        dz  c_        dS dS )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   )rK   rO   rT   rS   rM   
IndexErrorsetBit)	rL   r'   
skip_checkrK   rO   rW   found_all_bitsrX   rY   s	            r   addzBloomFilter.add   s     =,!!#&&:%%9::: 	% 	%A '. '&1*9M '!&M  !,,,n$FF 	JJ!OJJ5 	JJ!OJJ54r   c                 l    t          | j        | j                  }t          | j                  |_        |S )z,Return a copy of this bloom filter.
        )rA   rM   rN   r
   rK   )rL   
new_filters     r   r%   zBloomFilter.copy   s/     !@@
'66
r   c                     | j         |j         k    s| j        |j        k    rt          d          |                                 }|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rM   rN   rD   r%   rK   rL   other	new_blooms      r   unionzBloomFilter.union   sc     =EN**5#333 E F F FIIKK	&/%.@	r   c                 ,    |                      |          S rR   rl   rL   rj   s     r   __or__zBloomFilter.__or__       zz%   r   c                     | j         |j         k    s| j        |j        k    rt          d          |                                 }|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 raterh   ri   s      r   intersectionzBloomFilter.intersection   sc     =EN**5#333 B C C CIIKK	&/%.@	r   c                 ,    |                      |          S rR   )rs   ro   s     r   __and__zBloomFilter.__and__   s      '''r   c                     t          |          }|                    t          j                  rt	          |          }|                    | j                   |                    | j                   |	                    | j
                   |	                    | j                   |	                    | j                   |	                    | j                   || j        z   |                                 |                                 dS dS )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
writeFloatrN   writeIntr-   rO   rM   rS   rK   flushclose)rL   pathfouts       r   tofilezBloomFilter.tofile   s     $KK66)%&& 
	a..CNN4=)))NN4?+++LL)))LL,---LL'''LL$$$4=  GGIIIGGIIIII
	 
	r   c                 f   t          |          }|                    t          j                  st	          d|z             t          |          }|                                }|| j        k    rt	          d          |                                }|	                                }|	                                }|	                                }|	                                }	t                      }
 | d          }|                    |||||	           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   rw   r   ReadOnlyrD   r   	readBytesrz   	readFloatreadIntr
   rJ   rK   )clsr   r   datafile_fmtrN   r-   rO   rM   rS   rK   filters               r   fromfilezBloomFilter.fromfile   s     $KKvvi()) 	<3d:;;;1~~>>##s|##5666^^%%
\\^^
<<>>;;Qj*nhNNN#++r   c                 >    | j                                         }|d= |S )NrT   )__dict__r%   rL   ds     r   __getstate__zBloomFilter.__getstate__   s"    M  mr   c                     | j                             |           t          | j        | j                  \  | _        | _        d S rR   )r   r&   r?   r-   rO   rT   r   r   s     r   __setstate__zBloomFilter.__setstate__   sA    Q(6t7;7J)L )L%$+++r   N)rB   )F)__name__
__module____qualname__rz   rP   rJ   rZ   r^   rd   r%   rl   rp   rs   ru   r   classmethodr   r   r    r   r   rA   rA   D   s	       H1 1 1 1:L L L       4  	 	 	! ! !	 	 	( ( (  (   [4  
L L L L 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dS )ScalableBloomFilterr   r   z<idQdd   rB   c                 r    |r|dk     rt          d          |                     |d||           g | _        dS )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)rD   rJ   filters)rL   initial_capacityrN   modes       r   rP   zScalableBloomFilter.__init__   sH    $  	JZ!^^HIIID#/<<<r   c                 >    || _         || _        || _        || _        d S rR   )scaleratior   rN   )rL   r   r   r   rN   s        r   rJ   zScalableBloomFilter._setup  s#    

 0$r   c                 B    t          | j                  D ]	}||v r dS 
dS )rV   TF)reversedr   )rL   r'   r   s      r   rZ   z ScalableBloomFilter.__contains__  s7     $,'' 	 	Aaxxtt ur   c                    || v rdS | j         s>t          | j        | j        | j        z            }| j                             |           nb| j         d         }|j        |j        k    rEt          |j        | j        z  |j        | j        z            }| j                             |           |	                    |d           dS )zAdds a key to this bloom filter.
        If the key already exists in this filter it will return True.
        Otherwise False.
        T)rM   rN   )rb   F)
r   rA   r   rN   r   appendrS   rM   r   rd   )rL   r'   r   s      r   rd   zScalableBloomFilter.add   s    
 $;;4| 	, .?TZ79 9 9F L''''\"%F|v..$#_tz9%04:=? ? ? ##F+++

34
(((ur   c                     t          | j        | j        | j                  }| j        D ].}|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   rN   r   r   r   r%   )rL   clonedr   s      r   r%   zScalableBloomFilter.copy6  s[     %T%:%)_%)Z1 1  	, 	,AN!!!&&((++++r   c                    | j         |j         k    s | j        |j        k    s| j        |j        k    rt          d          t	          | j                  t	          |j                  k    r|                                 }|}n|                                }| }g }t          t	          |j                            D ]2}|j        |         |j        |         z  }|                    |           3t          t	          |j                  t	          |j                            D ]"}|                    |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   rN   rD   r8   r   r%   ranger   )rL   rj   
larger_sbfsmaller_sbfnew_filtersr   rf   s          r   rl   zScalableBloomFilter.unionA  sI    :$$%)???5#333 ? @ @ @ t|s5=1111JKKJKs;.//00 	+ 	+A#+A.1DQ1GGJz****s;.//Z5G1H1HII 	6 	6Az1!45555(
r   c                 ,    |                      |          S rR   rn   ro   s     r   rp   zScalableBloomFilter.__or__[  rq   r   c                 >    t          d | j        D                       S )z6Returns the total capacity for all filters in this SBFc              3   $   K   | ]}|j         V  d S rR   )rM   r   r   s     r   r   z/ScalableBloomFilter.capacity.<locals>.<genexpr>a  s$      44!1:444444r   sumr   r]   s    r   rM   zScalableBloomFilter.capacity^  s#     44t|444444r   c                      t          |           S rR   )r8   r]   s    r   rS   zScalableBloomFilter.countc  s    4yyr   c           	         |                     t          | j        | j        | j        | j        | j                             |                     t          dt          | j                                       t          | j                  dk    r|	                                }ddt          | j                  z  z   }|                     dt          |          z             g }| j        D ]U}|	                                }|                    |           |                    |	                                |z
             V|                    |           |                     t          |g|R             dS dS )zDSerialize this ScalableBloomFilter into the file-object
        `f'.   <lr      <   Q   .N)writer   rz   r   r   r   rN   r8   r   tellr	   r   r   seek)rL   r   	headerpos	headerfmtfilter_sizesr   begins          r   r   zScalableBloomFilter.tofileg  s[    	
T]DJ
*DO= = 	> 	> 	> 	
UC--..///t|q   Its4<'8'899IGGD8I...///L, 6 6a   ##AFFHHu$45555FF9GGD2\22233333 ! r   c           
          |             } |j         t          | j        |                    t	          | j                                        t          d|                    t	          d                              \  }|dk    rsdd|z  z   }|                    t	          |                    }t          ||          }|D ]5}|j                            t                              ||                     6ng |_        |S )z7Deserialize the ScalableBloomFilter in file object `f'.r   r   r   r   )	rJ   r   rz   readr	   r   r   rA   r   )r   r   r   nfilters
header_fmtbytesfilter_lengthsfls           r   r   zScalableBloomFilter.fromfile  s     vclAFF8CL3I3I,J,JKKLL5!&&%"9"9::	a<<x/JFF8J//00E#J66N$ C C%%k&:&:1b&A&ABBBBC  FNr   c                 >    t          d | j        D                       S )z7Returns the total number of elements stored in this SBFc              3   $   K   | ]}|j         V  d S rR   r\   r   s     r   r   z.ScalableBloomFilter.__len__.<locals>.<genexpr>  s$      11q17111111r   r   r]   s    r   r^   zScalableBloomFilter.__len__  s!    11DL111111r   N)r   r   r   SMALL_SET_GROWTHLARGE_SET_GROWTHrz   rP   rJ   rZ   rd   r%   rl   rp   propertyrM   rS   r   r   r   r^   r   r   r   r   r      s
       H(+&   .% % %    ,	 	 	  4! ! ! 5 5 X5   X4 4 40   [ 2 2 2 2 2r   r   __main__)__doc__rF   r0   utilsr   r   r   structr   r   r	   qtpy.QtCorer
   r   r   r   ImportErrorr?   objectrA   r   r   doctesttestmodr   r   r   <module>r      sn      ; ; ; ; ; ; ; ; ; ; ) ) ) ) ) ) ) ) ) )@DDDDDDDDDDDDD @ @ @
+>
?
??@/ / /doL oL oL oL oL& oL oL oLd\2 \2 \2 \2 \2& \2 \2 \2~ zNNNGO s   - >