






from __future__ import annotations

from collections.abc import Callable
from typing import Generic, TypeVar

SCREAMING_SNAKE_CASE__				     =			TypeVar('''T''')
SCREAMING_SNAKE_CASE__				     =			TypeVar('''U''')






class 			_UpperCamelCase(       Generic[T, U]		):

		def __init__(					self		:    Optional[Any]    ,       SCREAMING_SNAKE_CASE__		:    T | None    ,       SCREAMING_SNAKE_CASE__		:    U | None    ):



					'''simple docstring'''



					__a						:  Optional[int]									=     key
					__a						:  List[Any]									=     val
					__a						:  DoubleLinkedListNode[T, U] | None									=     None
					__a						:  DoubleLinkedListNode[T, U] | None									=     None



		def __repr__(					self		:    Any    ):



					'''simple docstring'''



					return (
					    f'''Node: key: {self.key}, val: {self.val}, '''
					    f'''has next: {bool(self.next    )}, has prev: {bool(self.prev    )}'''
					)






class 			_UpperCamelCase(       Generic[T, U]		):

		def __init__(					self		:    Tuple    ):



					'''simple docstring'''



					__a						:  DoubleLinkedListNode[T, U]									=     DoubleLinkedListNode(SCREAMING_SNAKE_CASE__    ,       SCREAMING_SNAKE_CASE__    )
					__a						:  DoubleLinkedListNode[T, U]									=     DoubleLinkedListNode(SCREAMING_SNAKE_CASE__    ,       SCREAMING_SNAKE_CASE__    )
					__a						,					__a						:  Optional[int]									=     self.rear, self.head

		def __repr__(					self		:    List[str]    ):



					'''simple docstring'''



					__a						:  Any									=     ['DoubleLinkedList']
					__a						:  Optional[Any]									=     self.head
					while node.next is not None:
								rep.append(str(SCREAMING_SNAKE_CASE__    )    )
								__a						:  List[Any]									=     node.next
					rep.append(str(self.rear    )    )
					return ",\n    ".join(SCREAMING_SNAKE_CASE__    )

		def    __lowerCAmelCase  (					self		:    int    ,       SCREAMING_SNAKE_CASE__		:    DoubleLinkedListNode[T, U]    ):



					'''simple docstring'''



					__a						:  List[Any]									=     self.rear.prev

					# All nodes other than self.head are guaranteed to have non-None previous
					assert previous is not None

					__a						:  List[str]									=     node
					__a						:  List[Any]									=     previous
					__a						:  Dict									=     node
					__a						:  int									=     self.rear



		def    __lowerCAmelCase  (					self		:    List[Any]    ,       SCREAMING_SNAKE_CASE__		:    DoubleLinkedListNode[T, U]    ):



					'''simple docstring'''



					if node.prev is None or node.next is None:
								return None

					__a						:  Optional[int]									=     node.next
					__a						:  Optional[int]									=     node.prev
					__a						:  List[Any]									=     None
					__a						:  Union[str, Any]									=     None
					return node






class 			_UpperCamelCase(       Generic[T, U]		):
		__SCREAMING_SNAKE_CASE  :       dict[Callable[[T], U], LRUCache[T, U]]							=							{}

		def __init__(					self		:    str    ,       SCREAMING_SNAKE_CASE__		:    int    ):



					'''simple docstring'''



					__a						:  DoubleLinkedList[T, U]									=     DoubleLinkedList()
					__a						:  List[Any]									=     capacity
					__a						:  Optional[Any]									=     0
					__a						:  Tuple									=     0
					__a						:  str									=     0
					__a						:  dict[T, DoubleLinkedListNode[T, U]]									=     {}

		def __repr__(					self		:    Dict    ):



					'''simple docstring'''



					return (
					    f'''CacheInfo(hits={self.hits}, misses={self.miss}, '''
					    f'''capacity={self.capacity}, current size={self.num_keys})'''
					)

		def __contains__(					self		:    Tuple    ,       SCREAMING_SNAKE_CASE__		:    T    ):



					'''simple docstring'''



					return key in self.cache

		def    __lowerCAmelCase  (					self		:    Union[str, Any]    ,       SCREAMING_SNAKE_CASE__		:    T    ):



					'''simple docstring'''



					if key in self.cache:
								self.hits += 1
								__a						:  DoubleLinkedListNode[T, U]									=     self.cache[key]
								__a						:  int									=     self.list.remove(self.cache[key]    )
								assert node == value_node

								# node is guaranteed not None because it is in self.cache
								assert node is not None
								self.list.add(SCREAMING_SNAKE_CASE__    )
								return node.val
					self.miss += 1
					return None

		def    __lowerCAmelCase  (					self		:    Any    ,       SCREAMING_SNAKE_CASE__		:    T    ,       SCREAMING_SNAKE_CASE__		:    U    ):



					'''simple docstring'''



					if key not in self.cache:
								if self.num_keys >= self.capacity:
											# delete first node (oldest) when over capacity
											__a						:  List[str]									=     self.list.head.next

											# guaranteed to have a non-None first node when num_keys > 0
											# explain to type checker via assertions
											assert first_node is not None
											assert first_node.key is not None
											assert (
											    self.list.remove(SCREAMING_SNAKE_CASE__    ) is not None
											)  # node guaranteed to be in list assert node.key is not None

											del self.cache[first_node.key]
											self.num_keys -= 1
								__a						:  int									=     DoubleLinkedListNode(SCREAMING_SNAKE_CASE__    ,       SCREAMING_SNAKE_CASE__    )
								self.list.add(self.cache[key]    )
								self.num_keys += 1

					else:
								# bump node to the end of the list, update value
								__a						:  Union[str, Any]									=     self.list.remove(self.cache[key]    )
								assert node is not None  # node guaranteed to be in list
								__a						:  Union[str, Any]									=     value
								self.list.add(SCREAMING_SNAKE_CASE__    )



		@classmethod
		def    __lowerCAmelCase  (					cls		:    Union[str, Any]    ,       SCREAMING_SNAKE_CASE__		:    int = 1_2_8    ):



					'''simple docstring'''



					def cache_decorator_inner(SCREAMING_SNAKE_CASE__		:    Callable[[T], U]    ) -> Callable[..., U]:
								def cache_decorator_wrapper(*SCREAMING_SNAKE_CASE__		:    T    ) -> U:
											if func not in cls.decorator_function_to_instance_map:
														__a						:  Any									=     LRUCache(SCREAMING_SNAKE_CASE__    )

											__a						:  Any									=     cls.decorator_function_to_instance_map[func].get(args[0]    )
											if result is None:
														__a						:  Tuple									=     func(*SCREAMING_SNAKE_CASE__    )
														cls.decorator_function_to_instance_map[func].put(args[0]    ,       SCREAMING_SNAKE_CASE__    )
											return result

								def cache_info() -> LRUCache[T, U]:
											return cls.decorator_function_to_instance_map[func]

								setattr(SCREAMING_SNAKE_CASE__    ,       'cache_info'    ,       SCREAMING_SNAKE_CASE__    )  # noqa: B010

								return cache_decorator_wrapper

					return cache_decorator_inner


if __name__ == "__main__":
							import doctest

							doctest.testmod()







"""simple docstring"""






from ..utils import DummyObject, requires_backends



class 			lowercase					( metaclass=lowercase__		):
			lowercase        =     ['''flax''', '''transformers''']






			def __init__(self  :	List[Any]      ,*SCREAMING_SNAKE_CASE_  :	Union[str, Any]      ,**SCREAMING_SNAKE_CASE_  :	Union[str, Any]			)       ->	str:





				"""simple docstring"""


				requires_backends(self      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	List[Any]      ,*SCREAMING_SNAKE_CASE_  :	List[Any]      ,**SCREAMING_SNAKE_CASE_  :	int			)       ->	Optional[int]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	List[Any]      ,*SCREAMING_SNAKE_CASE_  :	str      ,**SCREAMING_SNAKE_CASE_  :	Union[str, Any]			)       ->	Union[str, Any]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)





class 			lowercase					( metaclass=lowercase__		):
			lowercase        =     ['''flax''', '''transformers''']






			def __init__(self  :	int      ,*SCREAMING_SNAKE_CASE_  :	List[Any]      ,**SCREAMING_SNAKE_CASE_  :	Any			)       ->	Union[str, Any]:





				"""simple docstring"""


				requires_backends(self      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	int      ,*SCREAMING_SNAKE_CASE_  :	str      ,**SCREAMING_SNAKE_CASE_  :	int			)       ->	Optional[Any]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	List[str]      ,*SCREAMING_SNAKE_CASE_  :	List[str]      ,**SCREAMING_SNAKE_CASE_  :	Optional[Any]			)       ->	Dict:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)





class 			lowercase					( metaclass=lowercase__		):
			lowercase        =     ['''flax''', '''transformers''']






			def __init__(self  :	Tuple      ,*SCREAMING_SNAKE_CASE_  :	Optional[int]      ,**SCREAMING_SNAKE_CASE_  :	Dict			)       ->	List[str]:





				"""simple docstring"""


				requires_backends(self      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	Tuple      ,*SCREAMING_SNAKE_CASE_  :	Dict      ,**SCREAMING_SNAKE_CASE_  :	Optional[Any]			)       ->	List[Any]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	Tuple      ,*SCREAMING_SNAKE_CASE_  :	Tuple      ,**SCREAMING_SNAKE_CASE_  :	Tuple			)       ->	Union[str, Any]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)





class 			lowercase					( metaclass=lowercase__		):
			lowercase        =     ['''flax''', '''transformers''']






			def __init__(self  :	Optional[Any]      ,*SCREAMING_SNAKE_CASE_  :	Any      ,**SCREAMING_SNAKE_CASE_  :	str			)       ->	Union[str, Any]:





				"""simple docstring"""


				requires_backends(self      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	List[Any]      ,*SCREAMING_SNAKE_CASE_  :	Optional[Any]      ,**SCREAMING_SNAKE_CASE_  :	Optional[int]			)       ->	Union[str, Any]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)






			@classmethod
			def 					UpperCAmelCase							(cls  :	List[Any]      ,*SCREAMING_SNAKE_CASE_  :	List[Any]      ,**SCREAMING_SNAKE_CASE_  :	List[Any]			)       ->	Optional[Any]:





				"""simple docstring"""


				requires_backends(cls      ,['''flax''', '''transformers''']			)


