a
    %i                     @   sT   d Z ddlmZ ddlmZmZ ddlZddlZddlZe	e
ZG dd dZdS )zz
LRU cache for player records with auto-save on eviction.

Prevents unbounded memory growth by evicting inactive players.
    )OrderedDict)OptionalCallableNc                   @   s   e Zd ZdZdeedddZeddd	Zed
dddZ	eedddZ
d
dddZd
dddZedddZedddZedddZedddZd
S )PlayerCacheaW  
    LRU cache for player records.

    Features:
    - Automatic eviction of least-recently-used players
    - Never evicts connected players
    - Auto-save on eviction (optional)
    - Memory usage tracking

    Usage:
        cache = PlayerCache(max_size=100)
        cache.set("user123", player)
        player = cache.get("user123")
    d   T)max_size	auto_savec                 C   s4   t  | _|| _|| _d| _td| d|  dS )z
        Initialize player cache.

        Args:
            max_size: Maximum number of players to keep in memory
            auto_save: Whether to auto-save evicted players
        Nz"PlayerCache initialized: max_size=z, auto_save=)r   _cache	_max_size
_auto_saveon_evictloggerinfo)selfr   r    r   -/var/www/lichun.app/lichun/ws/player_cache.py__init__    s
    zPlayerCache.__init__)user_idc                 C   s$   || j v r | j | | j | S dS )z
        Get player from cache (marks as recently used).

        Args:
            user_id: User ID

        Returns:
            playerClass instance or None
        N)r	   move_to_endr   r   r   r   r   get3   s    


zPlayerCache.getN)r   returnc                 C   sJ   || j v r$| j | || j |< dS t| j | jkr<|   || j |< dS )z{
        Add player to cache.

        Args:
            user_id: User ID
            player: playerClass instance
        N)r	   r   lenr
   
_evict_lrur   r   playerr   r   r   setC   s    	

zPlayerCache.setc                 C   s   || j v r| j |= dS dS )z
        Remove player from cache.

        Args:
            user_id: User ID

        Returns:
            True if removed, False if not found
        TF)r	   r   r   r   r   removeX   s    

zPlayerCache.remove)r   c                 C   s   t | j D ]b\}}|jdkrtd| d|jj d | jrL| 	| | j
rbt| 
| | j|=  dS qtd| j d dS )z3Evict least recently used player (unless connected)disconnectedzEvicting player from cache: z ()NzPlayerCache full (z) with all connected players)listr	   items
connectionr   r   c	firstnamer   _save_playerr   asynciocreate_taskwarningr
   r   r   r   r   r   g   s    

zPlayerCache._evict_lruc              
   C   s`   ddl m} zt|| W n< tyZ } z$td|j d|  W Y d}~n
d}~0 0 dS )zSave player to database (async)r   )saveGameAsynczFailed to save evicted player z: N)	functionsr)   r&   r'   	Exceptionr   errorid)r   r   r)   er   r   r   r%   }   s
    zPlayerCache._save_playerc                 C   s
   t | jS )zGet current cache size)r   r	   r   r   r   r   size   s    zPlayerCache.sizec                 C   s   t | j| jkS )zCheck if cache is full)r   r	   r
   r/   r   r   r   is_full   s    zPlayerCache.is_fullc                 C   s@   | j s
dS tt| j  }t|}|t| j  d }|d S )zo
        Estimate memory usage of cached players.

        Returns:
            Estimated memory in MB
        g        
   i   )r	   nextitervaluessys	getsizeofr   )r   Zsample_playerZsample_sizeZestimated_totalr   r   r   estimate_memory_mb   s    
zPlayerCache.estimate_memory_mbc                 C   sT   t dd | j D }t| j| }t| j| j|||  t| j| j d dS )zGet cache statisticsc                 s   s   | ]}|j d krdV  qdS )	connected   N)r"   ).0pr   r   r   	<genexpr>       z(PlayerCache.get_stats.<locals>.<genexpr>r   )r0   r   r9   r   	memory_mbZutilization)sumr	   r5   r   r
   r8   )r   r9   r   r   r   r   	get_stats   s    zPlayerCache.get_stats)r   T)__name__
__module____qualname____doc__intboolr   strr   r   r   r   r%   r0   r1   floatr8   dictrA   r   r   r   r   r      s      	r   )rE   collectionsr   typingr   r   r6   loggingr&   	getLoggerrB   r   r   r   r   r   r   <module>   s   
