
    =wgb                        d Z ddlZddlZddlmZ ddlmZ ddlmZ ddl	m
Z
mZ ddl	mZ ddlmZ dd	lmZmZ  G d
 de      Zd Zd Zd ZeeefZ ej0                  d      Z ej0                  d      Z ej0                  d      Zdej8                  z  Z G d de      Z G d de      Z  G d de      Z! G d de       Z" G d de      Z# G d de       Z$y)zThis module defines writer and reader classes for a fast, immutable
on-disk key-value database format. The current format is based heavily on
D. J. Bernstein's CDB format (http://cr.yp.to/cdb.html).
    Ncrc32)bisect_left)md5)b
bytes_type)xrange)GrowableArray)	_INT_SIZE
emptybytesc                       e Zd Zy)FileFormatErrorN)__name__
__module____qualname__     O/var/www/horilla/myenv/lib/python3.12/site-packages/whoosh/filedb/filetables.pyr   r   .   s    r   r   c                 F    d}| D ]  }||dz  z   dz  t        |      z  } |S )Ni         )ord)keyhcs      r   cdb_hashr   4   s6    A 1!q&\Z'#a&01Hr   c                 N    t        t        |       j                         d      dz  S )N   r   )intr   	hexdigestr   s    r   md5_hashr"   ;   s!    s3x!!#R(:55r   c                     t        |       dz  S )Nr   r   r!   s    r   crc_hashr$   ?   s    :
""r   z!iiz!Iqz!qi   c                   R    e Zd ZdZ ed      dfdZd Zd Zd Zd Z	d	 Z
d
 Zd Zy)
HashWritera  Implements a fast on-disk key-value store. This hash uses a two-level
    hashing scheme, where a key is hashed, the low eight bits of the hash value
    are used to index into one of 256 hash tables. This is basically the CDB
    algorithm, but unlike CDB this object writes all data serially (it doesn't
    seek backwards to overwrite information at the end).

    Also unlike CDB, this format uses 64-bit file pointers, so the file length
    is essentially unlimited. However, each key and value must be less than
    2 GB in length.
    HSH3r   c                 x   || _         || _        t        | j                     | _        i | _        |j                         | _        |j                  |       |j                  | j                         |j                  d       |j                  d       t        d      D cg c]  }g  c}| _        g | _        yc c}w )aR  
        :param dbfile: a :class:`~whoosh.filedb.structfile.StructFile` object
            to write to.
        :param magic: the format tag bytes to write at the start of the file.
        :param hashtype: an integer indicating which hashing algorithm to use.
            Possible values are 0 (MD5), 1 (CRC32), or 2 (CDB hash).
        r   r%   N)dbfilehashtype_hash_functionshashfnextrastellstartoffsetwrite
write_byte	write_intr	   buckets	directory)selfr*   magicr+   _s        r   __init__zHashWriter.__init__`   s      %dmm4!;;=U$--( %+3K0q0 1s   	B7c                 6    | j                   j                         S N)r*   r/   r6   s    r   r/   zHashWriter.tell}   s    {{!!r   c                    t        |t              sJ t        |t              sJ | j                  }|j                         }|j	                  t
        j                  t        |      t        |                   |j	                  |       |j	                  |       | j                  |      }| j                  |dz     j                  ||f       y)zAdds a key/value pair to the file. Note that keys DO NOT need to be
        unique. You can store multiple values under the same key and retrieve
        them using :meth:`HashReader.all`.
           N)
isinstancer   r*   r/   r1   _lengthspacklenr-   r4   append)r6   r   valuer*   posr   s         r   addzHashWriter.add   s     #z***%,,,kkmX]]3s8SZ89SU KKQW$$aX.r   c                 B    | j                   }|D ]  \  }} |||        y)zConvenience method to add a sequence of ``(key, value)`` pairs. This
        is the same as calling :meth:`HashWriter.add` on each pair in the
        sequence.
        N)rF   )r6   itemsrF   r   rD   s        r   add_allzHashWriter.add_all   s)     hh 	JCUO	r   c                    | j                   }d}| j                  D ]  }|j                         }dt        |      z  }| j                  j                  ||f       |g|z  }|D ]-  \  }}|dz	  |z  }	||	   |k7  r|	dz   |z  }	||	   |k7  r||f||	<   / |D ]*  \  }}|j                  t        j                  ||             ,  y )N)r   r            )	r*   r4   r/   rB   r5   rC   r1   _pointerrA   )
r6   r*   nullentriesrE   numslots	hashtablehashvalpositionslots
             r   _write_hasheszHashWriter._write_hashes   s      || 	?G++-C3w<'HNN!!3/2 )I%, 6!10o- 1H0D  o- $+H"5	$6 &/ ?!X]]7H=>?)	?r   c                     | j                   }| j                  D ]*  \  }}|j                  t        j	                  ||             , y r;   )r*   r5   r1   
_dir_entryrA   )r6   r*   rT   rQ   s       r   _write_directoryzHashWriter._write_directory   s<     "&.. 	>HhLL8<=	>r   c                 N    | j                   j                  | j                         y r;   )r*   write_pickler.   r<   s    r   _write_extraszHashWriter._write_extras   s      -r   c                 "   | j                   }| j                          | j                          |j                         }| j	                          |j                  |j                         |z
         |j                         }|j                          |S r;   )r*   rV   rY   r/   r\   r3   close)r6   r*   exposendposs       r   r^   zHashWriter.close   sn     	./r   N)r   r   r   __doc__r   r9   r/   rF   rI   rV   rY   r\   r^   r   r   r   r'   r'   T   s:    	 &'vY :"/(?>>.r   r'   c                       e Zd ZdZd ed      dfdZed        Zd Zd Z	d	 Z
d
 Zd ZddZd Zd Zd Zd Zd Zd ZddZd Zd Zd Zy)
HashReaderzTReader for the fast on-disk key-value files created by
    :class:`HashWriter`.
    Nr(   r   c                 x   || _         || _        d| _        |3|j                  dt        j
                         |j                         |z
  }|j                  |       |j                  d      }||k7  rt        d|z        |j                         | _
        t        | j                     | _        |j                          |j                          |j                         | _        ||z   t        z
  }|j!                  |      }||z
  }|j                  |       | j#                          |j                  |t$        z
         g | _        t(        j*                  }	t(        j,                  }
t/        d      D ]2  }| j&                  j1                   |
|j                  |	                   4 | j&                  d   d   | _        y)a  
        :param dbfile: a :class:`~whoosh.filedb.structfile.StructFile` object
            to read from.
        :param length: the length of the file data. This is necessary since the
            hashing information is written at the end of the file.
        :param magic: the format tag bytes to look for at the start of the
            file. If the file's format tag does not match these bytes, the
            object raises a :class:`FileFormatError` exception.
        :param startoffset: the starting point of the file data.
        FNr      zUnknown file header %rr%   )r*   r0   	is_closedseekosSEEK_ENDr/   readr   	read_byter+   r,   r-   read_intstartofdatar   get_int_read_extras_directory_sizetablesrX   sizeunpackr	   rC   	endofdata)r6   r*   lengthr7   r0   	filemagicexptrexlenr_   	entrysizeunpackentryr8   s               r   r9   zHashReader.__init__   sl    &>KK2;;'[[][0FK KKN	!":Y"FGG((*%dmm4!;;=f$y0u%E 	EO+,OO	 '' 	DAKK{6;;y+ABC	D Q*r   c                 X    |j                  |      }|j                  |      } | ||      S )zConvenience method to open a hash file given a
        :class:`whoosh.filedb.filestore.Storage` object and a name. This takes
        care of opening the file and passing its length to the initializer.
        )file_length	open_file)clsstoragenameru   r*   s        r   openzHashReader.open  s1     $$T*""4(66""r   c                     | j                   S r;   )r*   r<   s    r   filezHashReader.file  s    {{r   c                 p    	 | j                   j                         | _        y # t        $ r
 i | _        Y y w xY wr;   )r*   read_pickler.   EOFErrorr<   s    r   ro   zHashReader._read_extras"  s1    	++113DK 	DK	s   " 55c                 z    | j                   rt        d| z        | j                  j                          d| _         y )NzTried to close %r twiceT)rf   	Exceptionr*   r^   r<   s    r   r^   zHashReader.close(  s1    >>5<==r   c                     | j                   }|j                  |      }|j                  |t        j                  z   |      S r;   )r*   get_uintgetr@   rr   )r6   rE   r*   keylens       r   key_atzHashReader.key_at.  s5     %zz#-v66r   c                     | j                   }t        j                  }|| j                  k\  ry t        j	                  |j                  ||            \  }}|j                  ||z   |      }||z   |z   }|||fS r;   )r*   r@   rr   rt   rs   r   )r6   rE   r*   lenssizer   datalenkeybytesdataposs           r   key_and_range_atzHashReader.key_and_range_at5  sq     ==$.. "//&**S(*CD::cHnf5.6)'))r   c              #      K   | j                   }|xs | j                  }|xs | j                  }t        j                  }t        j
                  }||k  r9 ||j                  ||            \  }}||z   }||z   }	|||	|f |	|z   }||k  r8y y wr;   )r*   rm   rt   r@   rr   rs   r   )
r6   rE   eodr*   r   
unpacklensr   r   keyposr   s
             r   _rangeszHashReader._rangesC  s      %T%%#T^^==__
Ci(C)BCOFG8^FvoG67G44G#C Cis   B	BBc                 J    | j                  |      D ]  }|c S  t        |      r;   )allKeyErrorr6   r   rD   s      r   __getitem__zHashReader.__getitem__S  s(    XXc] 	EL	smr   c              #      K   | j                   }| j                         D ]1  \  }}}}|j                  ||      }|j                  ||      }||f 3 y wr;   r*   r   r   )r6   r*   r   r   r   r   r   rD   s           r   __iter__zHashReader.__iter__X  sW     04 	,FFGW**VV,CJJw0E,	   AAc                 2    | j                  |      D ]  } y yNTF)ranges_for_key)r6   r   r8   s      r   __contains__zHashReader.__contains___  s"    $$S) 	A	r   c              #      K   | j                   }| j                         D ]  \  }}}}|j                  ||        y wr;   r   )r6   r*   r   r   r8   s        r   keyszHashReader.keysd  s>     $(LLN 	- FFAq**VV,,	-   <>c              #      K   | j                   }| j                         D ]  \  }}}}|j                  ||        y wr;   r   )r6   r*   r8   r   r   s        r   valueszHashReader.valuesi  s>     &*lln 	/"Aq'7**Wg..	/r   c              #      K   | j                   }| j                         D ]-  \  }}}}|j                  ||      |j                  ||      f / y wr;   r   )r6   r*   r   r   r   r   s         r   rH   zHashReader.itemsn  sP     04 	M,FFGW::ff-vzz'7/KLL	Ms   AAc                 8    | j                  |      D ]  }|c S  |S r;   )r   )r6   r   defaultrD   s       r   r   zHashReader.gets  s#    XXc] 	EL	r   c              #   ~   K   | j                   }| j                  |      D ]  \  }}|j                  ||        yw)zCYields a sequence of values associated with the given key.
        N)r*   r   r   )r6   r   r*   r   r   s        r   r   zHashReader.allx  sA       $ 3 3C 8 	/GW**Wg..	/s   ;=c              #   t  K   t        |t              st        d|z        | j                  }| j	                  |      }| j
                  |dz     \  }}|syt        j                  }t        j                  }t        j                  }t        j                  }	||dz	  |z  |z  z   }
t        |      D ]  } ||j                  |
|            \  }}|s y||k(  rL |	|j                  ||            \  }}|t        |      k(  r#||z   }||j                  ||      k(  r	||z   |f |
|z  }
|
|||z  z   k(  s|}
 yw)zeYields a sequence of ``(datapos, datalength)`` tuples associated
        with the given key.
        Key %r should be bytesr>   NrL   )r?   r   	TypeErrorr*   r-   rq   rN   rr   rs   r@   r	   r   rB   )r6   r   r*   keyhash
tablestartrQ   ptrsize	unpackptrr   r   slotposr8   slothashitemposr   r   keystarts                    r   r   zHashReader.ranges_for_key  sJ    
 #z*4s:;; ++c"  ${{7S=9
H--OO	==__
 'Q,(!:g EF! 	%A )&**Wg*F GHg 7"",VZZ-J"KSX%&1Hfjj6::'&0'::wG*7(:;;$+	%s   D0D83D8c                 J    | j                  |      D ]  }|c S  t        |      r;   )r   r   )r6   r   items      r   range_for_keyzHashReader.range_for_key  s+    '', 	DK	smr   NNr;   )r   r   r   ra   r   r9   classmethodr   r   ro   r^   r   r   r   r   r   r   r   r   rH   r   r   r   r   r   r   r   rc   rc      s     '+!F) 3+j # #7*$ 

-
/
M

//%br   rc   c                   "    e Zd ZdZd Zd Zd Zy)OrderedHashWriterzImplements an on-disk hash, but requires that keys be added in order.
    An :class:`OrderedHashReader` can then look up "nearest keys" based on
    the ordering.
    c                 f    t         j                  | |       t        d      | _        t        | _        y NH)r'   r9   r
   indexr   lastkeyr6   r*   s     r   r9   zOrderedHashWriter.__init__  s%    D&)"3'
!r   c                     || j                   k  rt        d| j                   d|      | j                  j                  | j                  j                                t        j                  | ||       || _         y NzKeys must increase: z..)r   
ValueErrorr   rC   r*   r/   r'   rF   r   s      r   rF   zOrderedHashWriter.add  s_    $,, $c3 4 4

$++**,-tS%(r   c                     | j                   }| j                  }|j                  | j                  d<   t	        |      | j                  d<   t
        j                  |        |j                  |       y )N	indextypeindexlen)r*   r   typecoder.   rB   r'   r\   to_file)r6   r*   r   s      r   r\   zOrderedHashWriter._write_extras  sT    

 $)>>K "%e*J  &fr   N)r   r   r   ra   r9   rF   r\   r   r   r   r   r     s    
"
r   r   c                   0    e Zd Zd Zd Zd Zd Zd Zd Zy)OrderedHashReaderc                 L    | j                  |      }|y| j                  |      S )zReturns the closest key equal to or greater than the given key. If
        there is no key in the file equal to or greater than the given key,
        returns None.
        N)closest_key_posr   )r6   r   rE   s      r   closest_keyzOrderedHashReader.closest_key  s+     ""3';{{3r   c              #   j   K   | j                  |      }|y| j                  |      D ]  }|  yw)zYields a series of ``(keypos, keylen, datapos, datalen)`` tuples
        for the ordered series of keys equal or greater than the given key.
        N)rE   )r   r   )r6   r   rE   r   s       r   ranges_fromzOrderedHashReader.ranges_from  s?     
 ""3';LLSL) 	DJ	s   13c              #      K   | j                   }| j                  |      D ]  \  }}}}|j                  ||        yw)zYYields an ordered series of keys equal to or greater than the given
        key.
        Nr*   r   r   )r6   r   r*   r   r   r8   s         r   	keys_fromzOrderedHashReader.keys_from  sE     
 $($4$4S$9 	- FFAq**VV,,	-s   =?c              #      K   | j                   }| j                  |      D ]-  \  }}}}|j                  ||      |j                  ||      f / yw)zuYields an ordered series of ``(key, value)`` tuples for keys equal
        to or greater than the given key.
        Nr   )r6   r   r*   r   r   r   r   s          r   
items_fromzOrderedHashReader.items_from  sW     
 040@0@0E 	M,FFGW::ff-vzz'7/KLL	Ms   AAc                    | j                   }t        j                  |        | j                  d   }|j	                         | _        | j                  d   | _        t        j                  |      | _	        |dk(  r|j                  | _        y |dk(  r|j                  | _        y |dk(  r|j                  | _        y |dk(  r|j                  | _        y |dk(  r|j                  | _        y t!        d|z        )	Nr   r   Br   iIqUnknown index type %r)r*   rc   ro   r.   r/   	indexbaser   structcalcsize	indexsizeget_byte_get_pos
get_ushortrn   r   get_longr   )r6   r*   r   s      r   ro   zOrderedHashReader._read_extras  s     	% KK,	J/3"OODM#"--DM#"NNDM#"OODM#"OODM3i?@@r   c                 ^   t        |t              st        d|z        | j                  }| j                  }| j
                  }| j                  }d}| j                  }||k  r/||z   dz  } | ||||z  z               }	|	|k  r|dz   }n|}||k  r/|| j                  k(  ry  ||||z  z         S )Nr   r   rK   rM   )r?   r   r   r   r   r   r   r   )
r6   r   r   r   r   r   lohimidmidkeys
             r   r   z!OrderedHashReader.closest_key_pos  s     #z*4s:;;NN	NN	== ]]2g7q.CHYy%@ABF|1W 2g 	BN233r   N)	r   r   r   r   r   r   r   ro   r   r   r   r   r   r     s"    	 
-MA24r   r   c                   (    e Zd ZdZd Zd Zd Zd Zy)FieldedOrderedHashWriterzYImplements an on-disk hash, but writes separate position indexes for
    each field.
    c                 r    t         j                  | |       i x| _        | j                  d<   t        | _        y Nfieldmap)r'   r9   r   r.   r   r   r   s     r   r9   z!FieldedOrderedHashWriter.__init__B  s0    D&)244J/ "r   c                     | j                   j                         | _        || _        t	        d      | _        t        | _        y r   )r*   r/   
fieldstart	fieldnamer
   posesr   r   r6   r   s     r   start_fieldz$FieldedOrderedHashWriter.start_fieldJ  s0    ++**,""3'
!r   c                    || j                   k  rt        d| j                   d|      | j                  j                  | j                  j                         | j                  z
         t        j                  | ||       || _         y r   )	r   r   r   rC   r*   r/   r   r'   rF   r   s      r   rF   zFieldedOrderedHashWriter.addQ  sh    $,, $c3 4 4

$++**,t>?tS%(r   c                     | j                   }| j                  }| j                  }| j                  |j	                         t        |      |j                  f| j                  |<   |j                  |       y r;   )	r*   r   r   r   r/   rB   r   r   r   )r6   r*   r   r   s       r   	end_fieldz"FieldedOrderedHashWriter.end_fieldY  sU    NN	

$(OOV[[]CJ$)NN$4i fr   N)r   r   r   ra   r9   r   rF   r   r   r   r   r   r   =  s    ""r   r   c                   d    e Zd Zd Zd ZddZd Zd Zd Zd Z	d	 Z
dd
Zd Zd Zd Zd Zd Zy)FieldedOrderedHashReaderc                     t        j                  | g|i | | j                  d   | _        g | _        t        | j                  j                               D ]4  }| j                  |   \  }}}}| j                  j                  |||f       6 y r   )rc   r9   r.   r   	fieldlistsortedr   rC   )r6   argskwargsr   startposixposixsizeixtypes           r   r9   z!FieldedOrderedHashReader.__init__c  s    D24262J/ 2 2 45 	@I.2mmI.F+HeVVNN!!9h">?	@r   c                 &    | j                   |   d   S )Nr   )r   r   s     r   field_startz$FieldedOrderedHashReader.field_startl  s    }}Y'**r   Nc              #      K   | j                   }d}||   \  }}}| j                  ||      D ]#  \  }}	}
}||k\  r|dz  }||   \  }}}|||	|
|f % y w)Nr   rM   )r   r   )r6   rE   r   flistfposr   startendr   r   r   r   s               r   fielded_rangesz'FieldedOrderedHashReader.fielded_rangeso  sx      %d	5#04S#0F 	>,FFGW}	(-d%	5#VVWg==		>s   AAc              #      K   | j                   j                  }| j                         D ]  \  }}}}}| |||      f  y wr;   r*   r   r  )r6   r   r   r   r   r8   s         r   
iter_termsz#FieldedOrderedHashReader.iter_termsy  sH     kkoo/3/B/B/D 	1+Ivvq!S000	1s   A Ac              #      K   | j                   j                  }| j                         D ]  }|\  }}}}}| |||       |||      f ! y wr;   r  )r6   r   r   r   r   r   r   r   s           r   iter_term_itemsz(FieldedOrderedHashReader.iter_term_items~  sX     kkoo'') 	HD:>7IvvwS0#gw2GGG	Hs   A
Ac                 H    	 | j                  ||      }y# t        $ r Y yw xY wr   )range_for_termr   )r6   r   btextxs       r   contains_termz&FieldedOrderedHashReader.contains_term  s.    	##Iu5A 		s    	!!c                     | j                   |   \  }}}}| j                  |      D ]  \  }}||cxk  r|k  sn ||fc S  t        ||f      r;   )r   r   r   )	r6   r   r  r  r  r  coder   r   s	            r   r  z'FieldedOrderedHashReader.range_for_term  sb    %)]]9%="ufd $ 3 3E : 	(GWw&&''	( 	5)**r   c                 d    | j                  ||      \  }}| j                  j                  ||      S r;   )r  r*   r   )r6   r   r  r   r   s        r   	term_dataz"FieldedOrderedHashReader.term_data  s.    ..y%@{{w00r   c                 J    	 | j                  ||      S # t        $ r |cY S w xY wr;   )r  r   )r6   r   r  r   s       r   term_getz!FieldedOrderedHashReader.term_get  s,    	>>)U33 	N	s    ""c                 
   t        |t              st        d|z        | j                  }| j                  }| j
                  |   \  }}}}|dk(  r|j                  }	nV|dk(  r|j                  }	nD|dk(  r|j                  }	n2|dk(  r|j                  }	n |dk(  r|j                  }	nt        d|z        d}
|}|
|k  r2|
|z   d	z  } || |	|||z  z         z         }||k  r|d
z   }
n|}|
|k  r2|
|k(  ry | |	||
|z  z         z   S )Nr   r   r   r   r   r   r   r   rK   rM   )r?   r   r   r*   r   r   r   r   rn   r   r   r   )r6   r   r   r*   r   r  r  r  r  get_posr   r   r   r   s                 r   closest_term_posz)FieldedOrderedHashReader.closest_term_pos  s+    #z*4s:;;*.--	*B'%S=ooGs]''Gs]nnGs]ooGs]ooG3f<== 2g7q.CHwusV|/C'DDEF|1W 2g <'%"v+"5666r   c                 N    | j                  ||      }|y | j                  |      S r;   )r!  r   )r6   r   r  rE   s       r   closest_termz%FieldedOrderedHashReader.closest_term  s+    ##Iu5;{{3r   c              #      K   | j                  ||      }|y | j                  |   \  }}}}| j                  ||      D ]  }|  y wr;   )r!  r   r   )	r6   r   r  rE   r  r  r  r  r   s	            r   term_ranges_fromz)FieldedOrderedHashReader.term_ranges_from  sV     ##Iu5;*.--	*B'%LLe, 	DJ	s   AAc              #      K   | j                   }| j                  ||      D ]  \  }}}}|j                  ||        y wr;   r*   r%  r   )r6   r   r  r*   r   r   r8   s          r   
terms_fromz#FieldedOrderedHashReader.terms_from  sE     $($9$9)U$K 	- FFAq**VV,,	-s   >A c              #      K   | j                   }| j                  ||      D ]/  }|\  }}}}|j                  ||      |j                  ||      f 1 y wr;   r'  )	r6   r   r  r*   r   r   r   r   r   s	            r   term_items_fromz(FieldedOrderedHashReader.term_items_from  s\     )))U; 	MD/3,FFGW::ff-vzz'7/KLL	Mr   r   r;   )r   r   r   r9   r  r  r  r  r  r  r  r  r!  r#  r%  r(  r*  r   r   r   r   r   b  sL    @+>1
H+1&7P -
Mr   r   )%ra   rh   r   binasciir   bisectr   hashlibr   whoosh.compatr   r   r	   whoosh.util.numlistsr
   whoosh.systemr   r   r   r   r   r"   r$   r,   Structr@   rN   rX   rr   rp   objectr'   rc   r   r   r   r   r   r   r   <module>r3     s   8
     '   . /
	i 	6# Xx0 6==6==V]]5!

'
C CLZ Z~
 D]4
 ]4D"z "JzMz zMr   