
    ɯei]                       d dl mZ d dlZd dlZd dlZd dlZd dlZd dlZd dlZd dl	Z	d dl
mZ d dlmZmZ d dlmZ d dlmZmZmZ d dlmZmZ d dlmZmZ d	d
lmZ d	dlmZ ej                  j:                  Zej                  j<                  Z ed      Z ej@                  e!      Z" ejF                  ed      jI                         dk(  Z% G d deee         Z& ed      Z' ed      Z(ddZ) G d dee'e(f         Z* G d de*      Z+y)    )annotationsN)Iterator)makedirspath)Lock)GenericNoReturnTypeVar)FileLockTimeout)
NamedTupleSelf   )	constants)ENV_VAR_TEST_MODET truec                  "    e Zd ZU ded<   ded<   y)
CacheEntrydatetime.datetimeexpiryr   entryN)__name__
__module____qualname____annotations__     [/var/www/html/glpi_dashboard/venv/lib/python3.12/site-packages/snowflake/connector/cache.pyr   r       s    Hr   r   KVc                    t               | k\  S N)now)ds    r    
is_expiredr'   )   s    5A:r   c                     e Zd ZdZej
                  f	 	 	 d dZd!dZe	 	 	 	 d"d       Z	dd	 	 	 	 	 d#dZ
e
Zd$dZ	 	 	 	 d%d	Z	 	 	 	 	 	 d$d
Zd&dZd'dZd(dZd)dZ	 d*	 	 	 	 	 d+dZd,dZ	 	 	 	 d-dZ	 	 	 	 d-dZ	 	 	 	 d.dZ	 d/	 	 	 	 	 d0dZ	 d/	 	 	 	 	 d0dZ	 	 	 	 d1dZd,dZd,dZd,dZd2dZd2dZd2dZ d3dZ!d,dZ"y)4SFDictCachezA generic in-memory cache that acts somewhat like a dictionary.

    Unlike normal dictionaries keys(), values() and items() return list materialized
    at call time, unlike normal dictionaries that return a view object.
    c                    t        j                  |      | _        i | _        t	               | _        | j                          y)z"Inits a SFDictCache with lifetime.)secondsN)datetime	timedelta_entry_lifetime_cacher   _lock_reset_telemetry)selfentry_lifetimes     r    __init__zSFDictCache.__init__4   s3    
  (11.I.0V
r   c                p    | j                   5  t        | j                        cd d d        S # 1 sw Y   y xY wr$   )r0   lenr/   r2   s    r    __len__zSFDictCache.__len__>   s*    ZZ 	$t{{#	$ 	$ 	$s   ,5c                8     | di |}|j                  |       |S )zCreate an dictionary cache from an already existing dictionary.

        Note that the same references will be stored in the cache than in
        the dictionary provided.
        r   )update)cls_dictkwcaches       r    	from_dictzSFDictCache.from_dictB   s      	b	Ur   Tshould_record_hitsc                  t         r!| j                  j                         sJ d       	 | j                  |   \  }}t        |      r| j                  |       |r| j                  |       |S # t        $ r | j                  |        w xY w)zNon-locking version of __getitem__.

        This should only be used by internal functions when already
        holding self._lock.
        4The mutex self._lock should be locked by this thread)		test_moder0   lockedr/   KeyError_missr'   _expire_hit)r2   krA   tvs        r    _getitemzSFDictCache._getitemQ   s     

!!#FEF#	;;q>DAq a=LLOIIaL  	JJqM	s   A, ,Bc                    t         r!| j                  j                         sJ d       t        t	               | j
                  z   |      | j                  |<   | j                          y)zNon-locking version of __setitem__.

        This should only be used by internal functions when already
        holding self._lock.
        rC   r   r   N)rD   r0   rE   r   r%   r.   r/   _add_or_remover2   rJ   rL   s      r    _setitemzSFDictCache._setitemn   s\     

!!#FEF##54///
A 	r   c                l    | j                   5  | j                  |d      cddd       S # 1 sw Y   yxY w)AReturns an element if it hasn't expired yet in a thread-safe way.Tr@   N)r0   rM   r2   rJ   s     r    __getitem__zSFDictCache.__getitem__~   s0    
 ZZ 	===t=<	= 	= 	=   *3c                j    | j                   5  | j                  ||       ddd       y# 1 sw Y   yxY w)z(Inserts an element in a thread-safe way.N)r0   rR   rQ   s      r    __setitem__zSFDictCache.__setitem__   s.     ZZ 	 MM!Q	  	  	 s   )2c                4    t        | j                               S r$   )iterkeysr7   s    r    __iter__zSFDictCache.__iter__   s    DIIK  r   c                T    | j                         D cg c]  \  }}|	 c}}S c c}}w r$   items)r2   rJ   _s      r    r\   zSFDictCache.keys        "jjl+da+++   $c           	        | j                   5  g }t        | j                  j                               D ]'  }	 |j	                  || j                  |d      f       ) 	 d d d        |S # t        $ r Y @w xY w# 1 sw Y   S xY w)NFr@   )r0   listr/   r\   appendrM   rF   )r2   valuesrJ   s      r    r`   zSFDictCache.items   s    ZZ 	(*F$++**,- MM1dmmA%m&P"QR	    	 s.   )A7$A(A7(	A41A73A44A77Bc                T    | j                         D cg c]  \  }}|	 c}}S c c}}w r$   r_   )r2   ra   rL   s      r    rg   zSFDictCache.values   rb   rc   Nc                0    	 | |   S # t         $ r |cY S w xY wr$   )rF   )r2   rJ   defaults      r    getzSFDictCache.get   s$    
	7N 	N	s    c                    | j                   5  | j                  j                          | j                          d d d        y # 1 sw Y   y xY wr$   )r0   r/   clearr1   r7   s    r    rm   zSFDictCache.clear   s:    ZZ 	$KK!!#	$ 	$ 	$s   +AA
c                    t         r!| j                  j                         sJ d       | j                  |= | j	                          y)zNon-locking version of __delitem__.

        This should only be used by internal functions when already
        holding self._lock.
        rC   N)rD   r0   rE   r/   rP   r2   keys     r    _delitemzSFDictCache._delitem   sA     

!!#FEF#KKr   c                h    | j                   5  | j                  |       d d d        y # 1 sw Y   y xY wr$   )r0   rq   ro   s     r    __delitem__zSFDictCache.__delitem__   s,     ZZ 	MM#	 	 	s   (1c                    | j                   5  	 | j                  |d       	 d d d        y# t        $ r Y d d d        yw xY w# 1 sw Y   y xY w)NTr@   F)r0   rM   rF   ro   s     r    __contains__zSFDictCache.__contains__   s[     ZZ 	cd;	 	  	 			 	s$   A,	A AA  AAc           	     N   t         r!| j                  j                         sJ d       | j                          t	        |t
        t        f      r}t               | j                  z   }t	        |t
              rt        |      }n)t	        |t              rt        |j                               }D ci c]  \  }}|t        ||       }}}nt	        |t              r|j                          t        |j                  j                               }|D ci c]>  \  }}|| j                  vs(|r&| j                  |   j                  |j                  k  r||@ }}}nt         | j                  j#                  |       |r| j%                          t'        |      dkD  S c c}}w c c}}w )zNon-locking version of update.

        This should only be used by internal functions when already
        holding self._lock and other._lock.
        rC   rO   r   )rD   r0   rE   _clear_expired_entries
isinstancere   dictr%   r.   r[   r`   r   r)   clear_expired_entriesr/   r   	TypeErrorr:   rP   r6   )	r2   otherupdate_newer_onlyr   grJ   rL   	to_insertothers_itemss	            r    _updatezSFDictCache._update   sh    

!!#FEF# 	##%edD\*UT111F%&KE4('KLM41aJfA>>MIM{+'') 2 2 45L
 )Aq T[[(-{{1~,,qxx7 1I  O9%!9~!!1 Ns   /FAF!c                j    | j                   5  | j                  ||      cddd       S # 1 sw Y   yxY w)a  Insert multiple values at the same time, if self could learn from the other.

        If this function is given a dictionary, or list expiration timestamps
        will be all the same a self._entry_lifetime form now. If it's
        given another SFDictCache then the timestamps will be taken
        from the other cache.

        Returns a boolean. It describes whether self learnt anything from other.

        Note that clear_expired_entries will be called on both caches. To
        prevent deadlocks this is done without acquiring other._lock. The
        intended behavior is to use this function with an unpickled/unused cache.
        If live caches are being merged then use .items() on them first and merge those
        into the other caches.
        Nr0   r   )r2   r|   r}   s      r    r:   zSFDictCache.update  s/    ( ZZ 	:<<'89	: 	: 	:s   )2c                l    | j                   5  | j                  |d      cddd       S # 1 sw Y   yxY w)zAThis function is like update, but it only updates newer elements.Tr}   Nr   )r2   r|   s     r    update_newerzSFDictCache.update_newer  s7    
 ZZ 	<<"&   	 	 	rW   c                   t         r!| j                  j                         sJ d       d}t        | j                  j                               D ]  }	 | j                  |d        |r| j                          y y # t        $ r d}Y :w xY w)NrC   Fr@   T)	rD   r0   rE   re   r/   r\   rM   rF   rP   )r2   cache_updatedrJ   s      r    rw   z"SFDictCache._clear_expired_entries&  s    

!!#FEF#dkk&&() 	%A%aE:	% ! 	  % !%%s   A::BBc                f    | j                   5  | j                          ddd       y# 1 sw Y   yxY w)z&Remove expired entries from the cache.N)r0   rw   r7   s    r    rz   z!SFDictCache.clear_expired_entries6  s*    ZZ 	*'')	* 	* 	*s   '0c                    ddddd| _         y)z(Re)set telemetry fields.

        This function will be called by the initalizer and other functions that should
        reset telemtry entries.
        r   )hitmiss
expirationsizeN	telemetryr7   s    r    r1   zSFDictCache._reset_telemetry<  s     	
r   c                2    | j                   dxx   dz  cc<   y)a  This function gets called when a hit occurs.

        Functions that hit every entry (like values) is not going to count.

        Note that while this function does not interact with lock, but it's only
        called from contexts where the lock is already held.
        r   r   Nr   rU   s     r    rI   zSFDictCache._hitI  s     	u"r   c                2    | j                   dxx   dz  cc<   y)zThis function gets called when a miss occurs.

        Note that while this function does not interact with lock, but it's only
        called from contexts where the lock is already held.
        r   r   Nr   rU   s     r    rG   zSFDictCache._missS  s     	v!#r   c                2    | j                   dxx   dz  cc<   y)zThis function gets called when an expiration occurs.

        Note that while this function does not interact with lock, but it's only
        called from contexts where the lock is already held.
        r   r   Nr   rU   s     r    _expirationzSFDictCache._expiration[  s     	|$)$r   c                R    | j                  |       | j                  |       t        )z7Helper function to call _expiration and delete an item.)r   rq   rF   rU   s     r    rH   zSFDictCache._expirec  s!    ar   c                H    t        | j                        | j                  d<   y)This function gets called when an element is added, or removed.

        Note that while this function does not interact with lock, but it's only
        called from contexts where the lock is already held.
        r   N)r6   r/   r   r7   s    r    rP   zSFDictCache._add_or_removei  s     "%T[[!1vr   )r3   intreturnNone)r   r   )r<   z
dict[K, V]r   r   rJ   r!   rA   boolr   r"   rJ   r!   rL   r"   r   r   rJ   r!   r   r"   )r   zIterator[K])r   zlist[K])r   zlist[tuple[K, V]])r   zlist[V]r$   )rJ   r!   rj   V | Noner   r   r   r   )rp   r!   r   r   )rp   r!   r   r   )F)r|   2dict[K, V] | list[tuple[K, V]] | SFDictCache[K, V]r}   r   r   r   )r|   r   r   r   )rJ   r!   r   r   )rJ   r!   r   r	   )#r   r   r   __doc__r   DAY_IN_SECONDSr4   r8   classmethodr?   rM   _getitem_non_lockingrR   rV   rY   r]   r\   r`   rg   rk   rm   rq   rs   ru   r   r:   r   rw   rz   r1   rI   rG   r   rH   rP   r   r   r    r)   r)   -   s    (66   
 $  
	 $ $(	 !	
 
6 $ == 
=     
	 !,, !  
	$
 
  


 

 #(."A."  ." 
	."f #(:A:  : 
	:.	A	 
	" *
#$*2r   r)   c                      e Zd ZdZdZej                  ddf	 	 	 	 	 	 	 	 	 d fdZdd	 	 	 	 	 ddZddZ	d fd	Z
dd
ZddZd Zed        ZdddZdd dZddZddZddZddZd! fdZd"dZd#dZd! fdZ xZS )$SFDictFileCache	   )r.   r/   r   	file_pathfile_timeout_file_lock_pathlast_loadedr   Tc                @   t         |   |       t        |t              r%t        j
                  j                  |      | _        nwt        j                         j                         }|||vr(t        t        |j                                     | _        n't        j
                  j                  ||         | _        dj                  d t        d      D              }t        j
                  j!                  | j                        }t        j"                  |      s	 t%        |d       	 t-        j.                  |	      \  }	}
	 t7        |	d      5 }|j9                  |       ddd       	 t7        |
      5 }|j;                         |k7  rt'        d       ddd       t        j
                  j#                  |
      r5t        j
                  j=                  |
      rt	        j>                  |
       	 || _         | j                   d| _!        tE        | jB                  | j@                        | _#        d| _$        t        j
                  j#                  | j                        r/|r-| jJ                  5  | jM                          ddd       d| _'        yd| _'        y# t&        $ r"}t(        j+                  d||       Y d}~d}~ww xY w# t0        $ r}t3        |j4                  d
|      d}~ww xY w# 1 sw Y   xY w# 1 sw Y   ixY w# t0        $ r}t3        |j4                  d|
      d}~ww xY w# t        j
                  j#                  |
      r6t        j
                  j=                  |
      rt	        j>                  |
       w w w xY w# 1 sw Y   d| _'        yxY w)a  Inits an SFDictFileCache with path, lifetime.

        File path can be a dictionary that contains different paths for different OSes,
        possible keys are: 'darwin', 'linux' and 'windows'. If a current platform
        cannot be determined, or is not in the dictionary we'll use the first value.

        Once we select a location based on file path, we write and read a random
        temporary file to check for read/write permissions. If this fails OSError might
        be thrown.
        )r3   Nr   c              3  b   K   | ]'  }t        j                  t        j                         ) y wr$   )randomchoicestringascii_letters).0ra   s     r    	<genexpr>z+SFDictFileCache.__init__.<locals>.<genexpr>  s     Vf.B.B CVs   -/   i  )modez/cannot create a cache directory: [%s], err=[%s])dirCache folder is not writeablewz-Temporary file just written has wrong contentzCache file is not readablez.locktimeoutF)(superr4   rx   strosr   
expanduserr   platformsystemlowernextr[   rg   joinrangedirnameexistsr   	ExceptionloggerdebugtempfilemkstempOSErrorPermissionErrorerrnoopenwritereadisfileunlinkr   r   r   
_file_lockr   r0   _load_cache_modified)r2   r   r3   r   load_if_file_existscurrent_platformrandom_stringcache_folderextmp_filetmp_file_patho_errw_filer_file	__class__s                 r    r4   zSFDictFileCache.__init__  s   " 	) 	 	
 i%WW//	:DN'0668'+;9+L!%d9+;+;+=&>!?!#!3!3I>N4O!P VUSTXVVwwt~~6{{<(E2		&.&6&6 '#Hm	)h$ ,]+,	-( SF{{}5!"QRS ww~~m,1N		-(("&..!17"4#7#7ARARS5977>>$..).A 

  %uW  E    	!/ 	, ,S S  %KK0!  ww~~m,1N		-( 2O,  %s   J ,K	 L3 K1$L3 -L 8K>L 2N	K$KK		K.K))K.1K;6L3 >LL 	L0L++L00L3 3AN
Nr@   c               t   || j                   vr7| j                         }|r|| j                   vr| j                  |       t        | j                   |   \  }}t	        |      rD| j                         }d}|r| j                   |   \  }}t	        |      }|r| j                  |       | j                  |       |S )a[  Non-locking version of __getitem__ of SFDictFileCache.

        This should only be used by internal functions when already
        holding self._lock.

        Note that we do not overwrite _getitem because _getitem is used by
        self._load to clear in-memory expired caches. Overwriting would cause
        infinite recursive call.
        T)r/   _load_if_shouldrG   rF   r'   rH   rI   )r2   rJ   rA   loadedrK   rL   expire_items          r    r   z$SFDictFileCache._getitem_non_locking  s     DKK))+Fq3

1{{1~1a=))+FK{{1~1(mQ		!r   c                h    | j                   5  | j                  |      cddd       S # 1 sw Y   yxY w)rT   N)r0   r   rU   s     r    rV   zSFDictFileCache.__getitem__  s,    ZZ 	0,,Q/	0 	0 	0   (1c                F    t         |   ||       | j                          y r$   )r   rR   _save_if_should)r2   rJ   rL   r   s      r    rR   zSFDictFileCache._setitem  s    Ar   c                ,   	 t        | j                  d      5 }| j                  |      }ddd       | j                  j	                          j                  | d      }| j                  j                          |j                  | j                  c| _        |_        |j                  d   | j                  d<   || _	        t               | _        y# 1 sw Y   xY w# t        t        f$ r  t        $ r }t        j!                  d|       Y d}~yd}~ww xY w)zFLoad cache from disk if possible, returns whether it was able to load.rbNTr   r   z-Fail to read cache from disk due to error: %sF)r   r   _deserializer0   releaser:   acquirer/   r   r   r%   r   AssertionErrorRuntimeErrorr   r   r   )r2   r   r|   cache_file_learntes        r    r   zSFDictFileCache._load  s    	dnnd+ Cv)-):):6)BC JJ  %"& !- ! JJ (-dkk%DK%*__V%<DNN6"#4D "uD!C C" - 	 	LLH!L	s.   C CB$C CC D3DDc                f    | j                   5  | j                         cddd       S # 1 sw Y   yxY w)zLoad cache from disk if possible, returns whether it was able to load.

        This is the public version of _load, it makes sure that all the
        necessary locks are acquired.
        N)r0   r   r7   s    r    loadzSFDictFileCache.load  s)     ZZ 	 ::<	  	  	 s   '0c                ,    t        j                  |       S r$   )pickledumpsr7   s    r    
_serializezSFDictFileCache._serialize  s    ||D!!r   c                ,    t        j                  |      S r$   )r   r   )r;   r   s     r    r   zSFDictFileCache._deserialize  s    {{6""r   c                X   t         r!| j                  j                         sJ d       | j                          | j                  s|sy	 | j
                  5  |r| j                          t        j                  j                  | j                        \  }}	 t        j                  ||      \  }}t        |d      5 }|j                  | j                                ddd       t        j                   || j                         t"        j"                  j%                  t'        | j                              | _        d| _        	 t        j                  j+                  |      r4t        j                  j-                  |      rt        j.                  |       ddd       y# 1 sw Y   xY w# t0        $ r) 	 t        j2                         n# t4        $ r Y nw xY wY n't4        $ r}t7        |j8                  d|      d}~ww xY wt        j                  j+                        rt        j                  j-                  |      rpt        j.                  |       nZ# t        j                  j+                        r6t        j                  j-                  |      rt        j.                  |       w w w xY wddd       y# 1 sw Y   yxY w# t:        $ r& t<        j?                  d| j@                   d	       Y ytB        tD        f$ r  tF        $ r }	t<        j?                  d
|	       Y d}	~	yd}	~	ww xY w)zSave cache to disk if possible, returns whether it was able to save.

        This function is non-locking when it comes to self._lock.
        rC   F)prefixr   wbNTr   z
acquiring z timed out, skipping saving...z,Fail to write cache to disk due to error: %s)$rD   r0   rE   rw   r   r   r   r   r   splitr   r   r   r   r   r   replacer,   fromtimestampgetmtimer   r   r   r   	NameErrorcloser   r   r   r   r   r   r   r   r   r   )
r2   
load_firstforce_flush_dirfnamer   r   r   r   r   s
             r    _savezSFDictFileCache._save#  s   
 

!!#FEF###%##K2	L )1((* ggmmDNN;e%1.6.>.>$ /+Hm h- 8T__%678 JJ}dnn='/'8'8'F'F 0(D$ ,1D(  ww~~m49V		-0S)1 )18 8 ! *"  )7  ww~~m49V		-0 ww~~m49V		-0 :W4Q)1d e)1d   	LLT1122PQ 	 - 	 	LLLGKK	Ls   K ?J8&F): FA&F)AJ8K F&	"F))	G>3G	G>		GG>GG>IG>"G99G>>IAJ8AJ,,J8/K 8K=K K ,L)2L)	L$$L)c                h    | j                   5  | j                  |      cddd       S # 1 sw Y   yxY w)zSave cache to disk if possible, returns whether it was able to save.

        This is the public version of _save, it makes sure that all the
        necessary locks are acquired.
        N)r0   r  )r2   r  s     r    savezSFDictFileCache.savee  s,     ZZ 	*::j)	* 	* 	*r   c                D    | j                         r| j                         S y)zSaves file to disk if necessary and returns whether it saved.

        Uses self._should_save to decide whether to save.
        F)_should_saver  r7   s    r    r   zSFDictFileCache._save_if_shouldn      
 ::<r   c                D    | j                         r| j                         S y)zLoad file to disk if necessary and returns whether it loaded.

        Uses self._should_load to decide whether to load.
        F)_should_loadr   r7   s    r    r   zSFDictFileCache._load_if_shouldw  r  r   c                H    t        j                  d| j                        dk(  S )zDecide whether we should save.

        This is a simple random number generator to randomize writes across processes
        that are possibly saving the same values in this cache.
        r   )r   randintMAX_RAND_INTr7   s    r    r  zSFDictFileCache._should_save  s      ~~a!2!23q88r   c                @   t         j                  j                  | j                        rut         j                  j	                  | j                        rL| j
                  yt        j                  j                  t        | j                              | j
                  kD  S y)z{Decide whether we should load.

        We should load if the file on disk has changed since we have last read it.
        TF)	r   r   r   r   r   r   r,   r   r  r7   s    r    r  zSFDictFileCache._should_load  st    
 77>>$..)bggnnT^^.L'!!//T^^, ""# r   c                   t         |           | j                  5  t        j                  j                  | j                        rHt        j                  j                  | j                        rt        j                  | j                         d d d        | j                  5  | j                  dd       d d d        y # 1 sw Y   2xY w# 1 sw Y   y xY w)NFT)r  r  )r   rm   r   r   r   r   r   r   r   r0   r  r2   r   s    r    rm   zSFDictFileCache.clear  s    __ 	*ww~~dnn-"''..2P		$..)	* ZZ 	;JJ%TJ:	; 	;		* 	*	; 	;s   A2B?"C?CCc                    | j                   j                         D ci c]  \  }}|t        j                  v r|| c}}S c c}}w r$   )__dict__r`   r   _ATTRIBUTES_TO_PICKLErQ   s      r    __getstate__zSFDictFileCache.__getstate__  sG     ++-
1O999 qD
 	
 
s   Ac                    | j                   j                  |       d| _        t               | _        t        | j                  | j                        | _        y )NFr   )	r  r:   r   r   r0   r   r   r   r   )r2   states     r    __setstate__zSFDictFileCache.__setstate__  s?    U#$V
"4#7#7ARARSr   c                0    t         |           d| _        y)r   TN)r   rP   r   r  s    r    rP   zSFDictFileCache._add_or_remove  s     	 #r   )
r   zstr | dict[str, str]r3   r   r   r   r   r   r   r   r   r   r   )r   r   )TF)r  r   r  r   r   r   )T)r  r   r   r   r   )r   ry   )r  ry   r   r   )r   r   r   r  r  r   r   r4   r   rV   rR   r   r   r   r   r   r  r
  r   r   r  r  rm   r  r  rP   __classcell__)r   s   @r    r   r   r  s    L (66$(N%'N% N% 	N%
 "N% 
N%h $(	 !	
 
B0
4 " # #@D*9 ;
T$ $r   r   )r&   r   r   r   ),
__future__r   r,   loggingr   r   r   r   r   r   collections.abcr   r   r   	threadingr   typingr   r	   r
   filelockr   r   typing_extensionsr   r   r   r   r   r%   r  r   	getLoggerr   r   getenvr   rD   r   r!   r"   r'   r)   r   r   r   r    <module>r(     s    "   	      $   - - & .  (77CL			8	$BII',224>	WQZ 
 CLCLB2'!Q$- B2J
F$k F$r   