
    j;                        d Z ddlmZ ddlZddlmZ ddlZddlm	Z	  G d de          Z
dZ	 ddlZd	Zn# e$ r dZY nw xY w G d
 d          Z G d d          Z G d d          ZdS )a  Pluggable vector search abstraction for face embeddings.

Uses **hnswlib** when available for O(log N) approximate nearest-neighbor
search.  Falls back transparently to numpy brute-force (exact) search when
hnswlib is not installed.

Usage::

    from modules.face.services.vector_store import VectorIndex

    idx = VectorIndex(dim=512)
    idx.build(embeddings_matrix)           # np.ndarray  (N, 512)
    labels, scores = idx.query(probe, k=5) # probe: (512,) float32

Both backends return **cosine similarity** scores in descending order.
    )annotationsN)Protocol)loggerc                  6    e Zd ZddZdd
Zedd            ZdS )_Indexmatrix
np.ndarrayreturnNonec                    d S N selfr   s     D/home/longshao/multi-rider-rag/modules/face/services/vector_store.pybuildz_Index.build!             probekinttuple[np.ndarray, np.ndarray]c                    d S r   r   r   r   r   s      r   queryz_Index.query"   r   r   c                    d S r   r   r   s    r   sizez_Index.size#   s    3r   Nr   r	   r
   r   r   r	   r   r   r
   r   r
   r   )__name__
__module____qualname__r   r   propertyr   r   r   r   r   r       s>        4444TTTT Xr   r   FTc                  D    e Zd ZdZdddZddZddZedd            ZdS )
_HnswIndexzHhnswlib-backed approximate nearest-neighbor index (inner-product space).      dimr   ef_constructionMc                L    || _         || _        || _        d | _        d| _        d S Nr   )_dim_ef_construction_M_index_size)r   r*   r+   r,   s       r   __init__z_HnswIndex.__init__7   s*    	 /-1


r   r   r	   r
   r   c           	        |j         d         }t          j        d| j                  }|                    t          |d          | j        | j                   |dk    rE|                    |	                    t          j                  t          j        |                     |                    t          dt          |d                               || _        || _        d S )Nr   ip)spacer*      )max_elementsr+   r,   2   r(   )shape_hnswlibIndexr/   
init_indexmaxr0   r1   	add_itemsastypenpfloat32arangeset_efminr2   r3   )r   r   nidxs       r   r   z_HnswIndex.build>   s    LOn4TY777C1IIt?TX\X_```q55MM&--
33RYq\\BBB

3r3q#;;''(((


r   r   r   r   c                   | j         | j        dk    r@t          j        g t          j                  t          j        g t          j                  fS t          || j                  }| j                             |                    dd          	                    t          j                  |          \  }}d|d         z
  }|d         	                    t          j                  |	                    t          j                  fS )Nr   dtyper8   )r   g      ?)
r2   r3   rB   arrayint64rC   rF   	knn_queryreshaperA   )r   r   r   labels	distancesscoress         r   r   z_HnswIndex.queryH   s    ;$*//8Bbh///"BJ1O1O1OOO4: K11%--22F2F2M2Mbj2Y2Y]^1__	y|#ay))6==+D+DDDr   c                    | j         S r   )r3   r   s    r   r   z_HnswIndex.sizeQ   s
    zr   N)r(   r)   )r*   r   r+   r   r,   r   r   r    r!   	r"   r#   r$   __doc__r4   r   r   r%   r   r   r   r   r'   r'   4   s        RR       E E E E    X  r   r'   c                  B    e Zd ZdZddZdd	ZddZedd            ZdS )_NumpyIndexz:Exact brute-force cosine search via matrix multiplication.r*   r   c                b    || _         t          j        d|ft          j                  | _        d S )Nr   rJ   )r/   rB   emptyrC   _matrixr   r*   s     r   r4   z_NumpyIndex.__init__^   s)    	#%8QHBJ#G#G#Gr   r   r	   r
   r   c                N    |                     t          j                  | _        d S r   )rA   rB   rC   r[   r   s     r   r   z_NumpyIndex.buildb   s    }}RZ00r   r   r   r   c                B   | j         j        dk    r@t          j        g t          j                  t          j        g t          j                  fS | j         |                    t          j                  z  }t          |t          |                    }t          j	        ||           | d          }|t          j
        ||                   d d d                  }|                    t          j                  ||                             t          j                  fS )Nr   rJ   rL   )r[   r   rB   rM   rN   rC   rA   rF   lenargpartitionargsort)r   r   r   rS   top_idxs        r   r   z_NumpyIndex.querye   s    <!!8Bbh///"BJ1O1O1OOORZ 8 883v;;/&1"--qbcc2"*VG_55ddd;<~~bh'')?)?
)K)KKKr   c                &    | j         j        d         S r.   )r[   r;   r   s    r   r   z_NumpyIndex.sizen   s    |!!$$r   Nr*   r   r   r    r!   rU   r   r   r   rX   rX   [   s~        DDH H H H1 1 1 1L L L L % % % X% % %r   rX   c                  ^    e Zd ZdZdddZdd
ZdddZedd            Zedd            Z	dS )VectorIndexz;Facade that picks the best available backend automatically.   r*   r   c                    t          j                    | _        t          r*t	          j        d           t          |          | _        d S t	          j        d           t          |          | _        d S )Nz"VectorIndex: using hnswlib backendz;VectorIndex: hnswlib not installed, using numpy brute-force)		threadingLock_lock_HAS_HNSWLIBr   infor'   _implrX   r\   s     r   r4   zVectorIndex.__init__{   s_    ^%%
 	*K<===!+CDJJJKUVVV$S))DJJJr   r   r	   r
   r   c                z    | j         5  | j                            |           d d d            d S # 1 swxY w Y   d S r   )rk   rn   r   r   s     r   r   zVectorIndex.build   s    Z 	% 	%JV$$$	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	% 	%   044   r   r   r   c                z    | j         5  | j                            ||          cd d d            S # 1 swxY w Y   d S r   )rk   rn   r   r   s      r   r   zVectorIndex.query   s    Z 	. 	.:##E1--	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	. 	.rp   c                    | j         j        S r   )rn   r   r   s    r   r   zVectorIndex.size   s    zr   strc                >    t          | j        t                    rdndS )Nhnswlibnumpy)
isinstancern   r'   r   s    r   backendzVectorIndex.backend   s    &tz:>>KyyGKr   N)rg   rd   r   )rq   r    r!   )r
   rt   )
r"   r#   r$   rV   r4   r   r   r%   r   ry   r   r   r   rf   rf   x   s        EE* * * * *% % % %. . . . .    X L L L XL L Lr   rf   )rV   
__future__r   ri   typingr   rw   rB   shared.config.configr   r   rl   rv   r<   ImportErrorr'   rX   rf   r   r   r   <module>r~      sY   " # " " " " "               ' ' ' ' ' '    X    LL   HHH       N% % % % % % % %:L L L L L L L L L Ls   5 ??