
    \jB                         d 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
 ddlmZmZ ddlmZ  G d d	      Z G d
 dee      Z G d d      Zy)aD  
This submodule contains basic classes related to the feature store.

The feature store is the SDK component that holds the last known state of all feature flags, as
received from LaunchDarkly. This submodule does not include specific integrations with external
storage systems; those are in :class:`ldclient.integrations`.
    )CallableAny)OrderedDictdefaultdict)ReadWriteLock)log)DiagnosticDescriptionFeatureStore)VersionedDataKindc                       e Zd ZdZdZdZeefdedefdZe	dd       Z
e	dd	       Zedefd
       Zedefd       Zedefd       Zy)CacheConfigzbEncapsulates caching parameters for feature store implementations that support local caching.
    g      .@i  
expirationcapacityc                      || _         || _        y)a  Constructs an instance of CacheConfig.

        :param expiration: the cache TTL, in seconds. Items will be evicted from the cache after
          this amount of time from the time when they were originally cached. If the time is less than or
          equal to zero, caching is disabled.
        :param capacity: the maximum number of items that can be in the cache at a time
        N)_expiration	_capacity)selfr   r   s      @/root/env/lib/python3.12/site-packages/ldclient/feature_store.py__init__zCacheConfig.__init__   s     &!    returnc                      t               S )zReturns an instance of CacheConfig with default properties. By default, caching is enabled.
        This is the same as calling the constructor with no parameters.
        r    r   r   defaultzCacheConfig.default&   s    
 }r   c                      t        d      S )zWReturns an instance of CacheConfig specifying that caching should be disabled.
        r   )r   r   r   r   r   disabledzCacheConfig.disabled-   s     **r   c                      | j                   dkD  S )zBReturns True if caching is enabled in this configuration.
        r   r   r   s    r   enabledzCacheConfig.enabled3   s     !##r   c                     | j                   S )z6Returns the configured cache TTL, in seconds.
        r   r    s    r   r   zCacheConfig.expiration9   s     r   c                     | j                   S )zBReturns the configured maximum number of cacheable items.
        )r   r    s    r   r   zCacheConfig.capacity?   s     ~~r   N)r   r   )__name__
__module____qualname____doc__DEFAULT_EXPIRATIONDEFAULT_CAPACITYfloatintr   staticmethodr   r   propertyboolr!   r   r   r   r   r   r   r      s      &8!1""""   + +
 $ $ $
  E    
 #  r   r   c            	       ~    e Zd ZdZd Zd fdededeegef   defdZ	d	 Z
d
 ZdedefdZd Zedefd       Zd Zy)InMemoryFeatureStoreznThe default feature store implementation, which holds all data in a thread-safe data structure in memory.
    c                 X    t               | _        d| _        t        t              | _        y)z8Constructs an instance of InMemoryFeatureStore.
        FN)r   _lock_initializedr   dict_itemsr    s    r   r   zInMemoryFeatureStore.__init__J   s!     #_
!!$'r   c                     | S )Nr   )xs    r   <lambda>zInMemoryFeatureStore.<lambda>Q   s    ^_ r   kindkeycallbackr   c                    	 | j                   j                          | j                  |   }|j                  |      }|Ct	        j
                  d||j                          |d      | j                   j                          S d|v rH|d   rCt	        j
                  d||j                          |d      | j                   j                          S  ||      | j                   j                          S # | j                   j                          w xY w)	
        Nz7Attempted to get missing key %s in '%s', returning Nonedeletedz7Attempted to get deleted key %s in '%s', returning None)r2   rlockr5   getr   debug	namespacerunlock)r   r9   r:   r;   itemsOfKinditems         r   r@   zInMemoryFeatureStore.getQ   s    	!JJ++d+K??3'D|		SUXZ^ZhZhi~ JJ  D T)_		SUXZ^ZhZhi~ JJ  D>JJ DJJ s   A$C/ 1C/ C/ /Dc                    	 | j                   j                          | j                  |   } |t        d |j	                         D                    | j                   j                          S # | j                   j                          w xY w)r=   c              3   >   K   | ]  \  }}d |vs|d    r||f  yw)r>   Nr   ).0kis      r   	<genexpr>z+InMemoryFeatureStore.all.<locals>.<genexpr>h   s)      tDAqI]^L^ghirgs!Q ts   	)r2   r?   r5   r4   itemsrC   )r   r9   r;   rD   s       r   allzInMemoryFeatureStore.allb   sb    	!JJ++d+KD tK4E4E4G ttuJJ DJJ    AA+ +Bc           	      (   i }|j                         D ]8  \  }}i }|j                         D ]  \  }}|j                  |      ||<    |||<   : 	 | j                  j                          | j                  j                          | j                  j                  |       d| _        |D ]/  }t        j                  d|j                  t        ||                1 	 | j                  j                          y# | j                  j                          w xY w)r=   Tz$Initialized '%s' store with %d itemsN)rL   decoder2   r?   r5   clearupdater3   r   rA   rB   lenrC   )	r   all_dataall_decodedr9   rL   items_decodedr:   rE   rI   s	            r   initzInMemoryFeatureStore.initl   s     #>>+ 	.KD%M"[[] 7	T%)[[%6c"7 -K		.
	!JJKKKK{+ $D a		@!++sS[\]S^O_`a JJ DJJ s   B
C5 5Dversionc                    	 | j                   j                          | j                  |   }|j                  |      }||d   |k  r
d|d}|||<   | j                   j	                          y# | j                   j	                          w xY w)r=   NrX   T)r>   rX   )r2   r?   r5   r@   rC   )r   r9   r:   rX   rD   rJ   s         r   deletezInMemoryFeatureStore.delete   sx    	!JJ++d+K$AyAiL72 $9#$C JJ DJJ rN   c                    |j                  |      }|d   }	 | j                  j                          | j                  |   }|j	                  |      }||d   |d   k  r*|||<   t        j                  d||j                  |d          | j                  j                          y# | j                  j                          w xY w)r=   r:   NrX   z Updated %s in '%s' to version %d)	rP   r2   r?   r5   r@   r   rA   rB   rC   )r   r9   rE   decoded_itemr:   rD   rJ   s          r   upsertzInMemoryFeatureStore.upsert   s     {{4(5k	!JJ++d+K$AyAiL4	?:#/C 		<c4>>SWXaSbcJJ DJJ s   A1B$ $C c                     	 | j                   j                          | j                  | j                   j                          S # | j                   j                          w xY w)r=   )r2   r?   r3   rC   r    s    r   initializedz InMemoryFeatureStore.initialized   sA    	!JJ$$JJ DJJ s   %A Ac                      y)Nmemoryr   )r   configs     r   describe_configurationz+InMemoryFeatureStore.describe_configuration   s    r   N)r$   r%   r&   r'   r   r   strr   r   r@   rM   rW   r+   rZ   r]   r-   r.   r_   rc   r   r   r   r0   r0   F   s    ( U` !) ! !xs
?S !dg !"!!(! !c !! !T ! !r   r0   c                   @    e Zd ZdZed        Zed        Zed        Zy)_FeatureStoreDataSetSorterz
    Implements a dependency graph ordering for data to be stored in a feature store. We must use this
    on every data set that will be passed to the feature store's init() method.
    c                     t               }t        | j                               }d }|j                  |       |D ]   }| |   }t        j                  ||      ||<   " |S )a   Returns a copy of the input data that has the following guarantees: the iteration order of the outer
        dictionary will be in ascending order by the VersionDataKind's :priority property (if any), and for each
        data kind that has a "get_dependency_keys" function, the inner dictionary will have an iteration order
        where B is before A if A has a dependency on B.
        c                 \    t        | d      r| j                  S t        | j                        S )Npriority)hasattrri   rS   rB   )r9   s    r   priority_orderzG_FeatureStoreDataSetSorter.sort_all_collections.<locals>.priority_order   s%    tZ(}}$t~~&&r   )r:   )r   listkeyssortrf   _sort_collection)rT   
outer_hashkindsrk   r9   rL   s         r   sort_all_collectionsz/_FeatureStoreDataSetSorter.sort_all_collections   sj     !]
X]]_%	' 	

~
& 	XDTNE9JJ4QVWJt	X r   c                 J   t        |      dk(  st        | d      s|S | j                  }|t        |      dk(  r|S |j                         }t	               }t        |      dkD  r@|j                         D ]  \  }}t        j                  ||||        n t        |      dkD  r@|S )Nr   get_dependency_keys)rS   rj   rt   copyr   rL   rf   _add_with_dependencies_first)r9   inputdependency_fnremaining_items	items_outr:   rE   s          r   ro   z+_FeatureStoreDataSetSorter._sort_collection   s    u:?'$0E"FL00 CJ!OL**,M	/"Q&,224 	T*GGm]lnwx /"Q&
 r   c                     | j                  d      }||=  ||       D ].  }|j                  |      }|t        j                  ||||       0 | ||<   y )Nr:   )r@   rf   rv   )rE   rx   ry   rz   r:   dep_keydep_items          r   rv   z7_FeatureStoreDataSetSorter._add_with_dependencies_first   se    hhuoC $T* 	}G&**73H#*GGR_apr{|	} 	#r   N)r$   r%   r&   r'   r,   rr   ro   rv   r   r   r   rf   rf      sC      $    r   rf   N)r'   typingr   r   collectionsr   r   ldclient.impl.rwlockr   ldclient.impl.utilr   ldclient.interfacesr	   r
   ldclient.versioned_data_kindr   r   r0   rf   r   r   r   <module>r      sE    ! 0 . " C :1 1ha<)> aH0 0r   