Ë
    ãš¾jc  ã                   óÀ   — d dl Z d dlZd dlZd dlmZ ddlmZ ddlmZ ddl	m
Z
  ej                  e«      Z G d„ d«      Z G d	„ d
«      Z G d„ d«      Z G d„ d«      Zy)é    N)Údequeé   )Úasyn)Úsync_teardown)Ú_fast_slicec                   ól   — e Zd ZdZdd„Zdefd„Zedefd„«       Zede	fd„«       Z
edefd„«       Zd	„ Zy
)ÚRunningAverageTrackerz·Tracks a running average of values over a sliding window.

    This is used to monitor read sizes and adaptively scale the
    prefetching strategy based on recent user behavior.
    c                 ó`   — t         j                  d|«       t        |¬«      | _        d| _        y)z—Initializes the tracker with a specific window size.

        Args:
            maxlen (int): The maximum number of historical values to keep.
        z2Initializing RunningAverageTracker with maxlen: %d©Úmaxlenr   N)ÚloggerÚdebugr   Ú_historyÚ_sum)Úselfr   s     ú[/home/spazio/kingdom_calls/work5/transenv/lib/python3.12/site-packages/fsspec/prefetcher.pyÚ__init__zRunningAverageTracker.__init__   s&   € ô 	�‰ÐIÈ6ÔRÜ VÔ,ˆŒØˆ�	ó    Úvaluec                 ób  — |dk  rt        d«      ‚t        | j                  «      | j                  j                  k(  r"| xj                  | j                  d   z  c_        | j                  j                  |«       | xj                  |z  c_        t        j                  d|| j                  «       y)z�Adds a new value to the sliding window and updates the rolling sum.

        Args:
            value (int): The integer value to add to the history.
        r   zDInternal error, RunningAverageTracker tried inserting negative valuez2RunningAverageTracker added value: %d, new sum: %dN)Ú
ValueErrorÚlenr   r   r   Úappendr   r   )r   r   s     r   ÚaddzRunningAverageTracker.add   s†   € ð �AŠ:ÜØVóð ô ˆt�}‰}Ó §¡×!5Ñ!5Ò5Ø�IŠI˜Ÿ™ qÑ)Ñ)�Ià�‰×Ñ˜UÔ#Ø�	Š	�UÑ�	Ü�‰Ø@À%ÈÏÉõ	
r   Úreturnc                 óV   — t        | j                  «      }|dk(  ry| j                  |z  S )z‹Calculates and returns the current running average.

        Returns:
            int: The integer average of the current history.
        r   i   )r   r   r   ©r   Úcounts     r   ÚaveragezRunningAverageTracker.average1   s+   € ô �D—M‘MÓ"ˆØ�AŠ:ØØ�y‰y˜EÑ!Ð!r   c                 óz   — t        | j                  «      }|dk  ryt        t        | j                  «      «      dkD  S )z8Determines if the history contains distinct chunk sizes.é   Fr   )r   r   Úsetr   s     r   Úis_variablez!RunningAverageTracker.is_variable=   s5   € ô �D—M‘MÓ"ˆØ�1Š9Øä”3�t—}‘}Ó%Ó&¨Ñ*Ð*r   c                 óN   — | j                   st        d«      ‚| j                   d   S )z-Returns the most recent entry in the history.zNo entry found in historyéÿÿÿÿ)r   ÚRuntimeError©r   s    r   Ú
last_valuez RunningAverageTracker.last_valueF   s&   € ð �}Š}ÜÐ:Ó;Ð;à�}‰}˜RÑ Ð r   c                 óp   — t         j                  d«       | j                  j                  «        d| _        y)z.Clears the history and resets the sum to zero.z'Clearing RunningAverageTracker history.r   N)r   r   r   Úclearr   r'   s    r   r*   zRunningAverageTracker.clearN   s&   € ä�‰Ð>Ô?Ø�‰×ÑÔØˆ�	r   N)é
   )Ú__name__Ú
__module__Ú__qualname__Ú__doc__r   Úintr   Úpropertyr   Úboolr#   r(   r*   © r   r   r	   r	      sn   „ ñóð
˜ó 
ð& ð	"˜ò 	"ó ð	"ð ð+˜Tò +ó ð+ð ð!˜Cò !ó ð!ór   r	   c                   óÂ   — e Zd ZdZdZdZdZdZ	 ddeded	e	j                  d
e	j                  dddeddfd„Zedefd„«       Zd„ Zd„ Zdefd„Zd„ Zdeeeef   fd„Zd„ Zy)ÚPrefetchProducera
  Background worker that fetches sequential blocks of data.

    This class handles the network requests. It spawns asynchronous tasks
    to fetch data ahead of the user's current reading position and
    places those task promises into a queue for the consumer.
    i  P i   é   i   NÚsizeÚconcurrencyÚqueueÚwakeup_eventÚconsumerÚPrefetchConsumerÚtrackerÚorchestratorÚBackgroundPrefetcherc
                 ó   — t         j                  d|||	«       || _        || _        || _        || _        || _        || _        || _        t        j                  |«      | _        |	| _        d| _        d| _        t        «       | _        d| _        y)a*  Initializes the background producer.

        Args:
            fetcher (Callable): A coroutine function to fetch bytes from a remote source.
            size (int): Total size of the file being fetched.
            concurrency (int): Maximum number of concurrent fetch tasks.
            queue (asyncio.Queue): The shared queue to push download tasks into.
            wakeup_event (asyncio.Event): Event used to wake the producer from an idle state.
            consumer (PrefetchConsumer): The consumer reading the prefetched chunks.
            tracker (RunningAverageTracker): Tracker for history of read sizes.
            orchestrator (BackgroundPrefetcher): The parent object managing the operation.
            user_max_prefetch_size (int, optional): A hard limit for prefetch size overrides.
        zQInitializing PrefetchProducer: size=%d, concurrency=%d, user_max_prefetch_size=%sr   FN)r   r   Úfetcherr7   r8   r9   r:   r;   r=   ÚweakrefÚproxyr>   Ú_user_max_prefetch_sizeÚcurrent_offsetÚ
is_stoppedr"   Ú_active_tasksÚ_producer_task)
r   rA   r7   r8   r9   r:   r;   r=   r>   Úuser_max_prefetch_sizes
             r   r   zPrefetchProducer.__init__w   s‹   € ô2 	�‰Ø_ØØØ"ô		
ð ˆŒØˆŒ	Ø&ˆÔØˆŒ
Ø(ˆÔà ˆŒØˆŒÜ#ŸM™M¨,Ó7ˆÔØ'=ˆÔ$àˆÔØˆŒÜ ›UˆÔØ"ˆÕr   r   c                 óö   — | j                   �At        | j                   t        d| j                  j                  z  | j
                  «      «      S t        d| j                  j                  z  | j
                  «      S )z Calculates the maximum prefetch size based on user intent or io size.

        Returns:
            int: The maximum number of bytes to prefetch ahead.
        r!   )rD   ÚminÚmaxr=   r   ÚMIN_PREFETCH_SIZEr'   s    r   Úmax_prefetch_sizez"PrefetchProducer.max_prefetch_size¦   si   € ð ×'Ñ'Ð3ÜØ×,Ñ,Ü�A˜Ÿ™×,Ñ,Ñ,¨d×.DÑ.DÓEóð ô �1�t—|‘|×+Ñ+Ñ+¨T×-CÑ-CÓDÐDr   c                 óÀ   — t         j                  d«       d| _        | j                  j	                  «        t        j                  | j                  «       «      | _        y)z|Starts the background producer loop.

        This clears any previous wakeup events and spawns the main loop task.
        zStarting PrefetchProducer loop.FN)	r   r   rF   r:   r*   ÚasyncioÚcreate_taskÚ_looprH   r'   s    r   ÚstartzPrefetchProducer.start´   sC   € ô
 	�‰Ð6Ô7ØˆŒØ×Ñ×ÑÔ!Ü%×1Ñ1°$·*±*³,Ó?ˆÕr   c              ƒ   óB  K  — t         j                  dt        | j                  «      «       d| _        | j
                  j                  «        g }| j                  rO| j                  j                  «       s5| j                  j                  «        |j                  | j                  «       |j                  d„ t        | j                  «      D «       «       | j                  j                  «        d}| j                  j                  «       s…	 | j                  j!                  «       }t#        |t$        j&                  «      r0|j                  «       r |j)                  «       s|j+                  «        |dz  }| j                  j                  «       sŒ…|dkD  rt         j                  d|«       |r<t         j                  dt        |«      «       t%        j.                  |ddiŽƒ d	{  –—†  | j
                  j                  «        y	# t$        j,                  $ r Y Œ‰w xY w7 Œ8­w)
z¸Cancels all active fetch tasks and shuts down the producer loop.

        This method ensures the queue is flushed and waits for cancelled
        tasks to finish cleaning up.
        z1Stopping PrefetchProducer. Active fetch tasks: %dTc              3   óB   K  — | ]  }|j                  «       rŒ|–— Œ y ­w©N)Údone)Ú.0Útasks     r   ú	<genexpr>z(PrefetchProducer.stop.<locals>.<genexpr>Ï   s   è ø€ ò 
Ø¸T¿Y¹Y½[ŒDñ
ùs   ‚˜r   r   z5Cleared %d leftover items from the queue during stop.z8Waiting for %d cancelled tasks to finish their teardown.Úreturn_exceptionsN)r   r   r   rG   rF   r:   r"   rH   rW   Úcancelr   ÚextendÚlistr*   r9   ÚemptyÚ
get_nowaitÚ
isinstancerP   ÚTaskÚ	cancelledÚ	exceptionÚ
QueueEmptyÚgather)r   Útasks_to_waitÚcleared_itemsÚitems       r   ÚstopzPrefetchProducer.stop¾   sµ  è ø€ ô 	�‰Ø?ÄÀT×EWÑEWÓAXô	
ð ˆŒØ×Ñ×ÑÔàˆØ×Ò t×':Ñ':×'?Ñ'?Ô'AØ×Ñ×&Ñ&Ô(Ø× Ñ  ×!4Ñ!4Ô5à×Ññ 
Ü! $×"4Ñ"4Ó5ô
ô 	
ð 	×Ñ× Ñ Ô"ð ˆØ—*‘*×"Ñ"Ô$ð
Ø—z‘z×,Ñ,Ó.�ä˜t¤W§\¡\Ô2ØŸ	™	œØ ŸN™NÔ,à—N‘NÔ$Ø Ñ"�ð —*‘*×"Ñ"Õ$ð ˜1ÒÜ�L‰LØGÈôñ Ü�L‰LØJÜ�MÓ"ôô —.‘. -ÐHÀ4ÑH×HÐHà×Ñ×ÑÕ!øô ×%Ñ%ò Ùðúð Iús>   ‚D	HÄA)H Å5HÆAHÇ$HÇ%HÈHÈHÈHÈHÚ
new_offsetc              ƒ   óš   K  — t         j                  d|«       | j                  «       ƒ d{  –—†  || _        | j	                  «        y7 Œ­w)z±Stops current tasks and restarts the background loop at a new byte offset.

        Args:
            new_offset (int): The new byte position to start prefetching from.
        z-Restarting PrefetchProducer at new offset: %dN)r   r   rj   rE   rS   ©r   rk   s     r   ÚrestartzPrefetchProducer.restartô   s<   è ø€ ô 	�‰ÐDÀjÔQØ�i‰i‹k×ÐØ(ˆÔØ�
‰
�ð 	ús   ‚*A¬A	­Ac              ƒ   ój  K  — t         j                  d«       	 | j                  so| j                  j	                  «       ƒ d{  –—†  | j                  j                  «        | j                  ry| j                  «       ƒ d{  –—†  | j                  sŒnyy7 ŒR7 Œ# t        j                  $ r t         j                  d«       Y yt        $ re}t         j                  d«       d| _        | j                  j                  |«       | j                  j                  |«      ƒ d{  –—†7   Y d}~yd}~ww xY w­w)zFThe main background loop that delegates calculations and spawns tasks.z.PrefetchProducer internal loop is now running.Nz$PrefetchProducer loop was cancelled.z6PrefetchProducer loop encountered an unexpected error.T)r   r   rF   r:   Úwaitr*   Ú_process_prefetch_cyclerP   ÚCancelledErrorÚ	Exceptionrd   r>   Ú	set_errorr9   Úput©r   Úes     r   rR   zPrefetchProducer._loopÿ   sâ   è ø€ ä�‰ÐEÔFð	$Ø—o’oØ×'Ñ'×,Ñ,Ó.×.Ð.Ø×!Ñ!×'Ñ'Ô)à—?’?Øà×2Ñ2Ó4×4Ð4ð —o•oØ.øð 5ùä×%Ñ%ò 	AÜ�L‰LÐ?Ö@Üò 	$Ü×ÑÐUÔVØ"ˆDŒOØ×Ñ×'Ñ'¨Ô*Ø—*‘*—.‘. Ó#×#Ö#ûð		$üsw   ‚D3™)B ÁBÁ*B Á-D3Á.B ÂBÂB ÂD3ÂB ÂB Â(D0ÃD3ÃD0ÃAD+Ä D#Ä!D+Ä&D3Ä+D0Ä0D3c                 óô  — | j                   j                  }| j                  j                  }| j                   j                  }| j                   j
                  }| j                  duxr || j                  kD  }|r|| j                  kD  s|rt        j                  d«       d}n$|| j                  k  rd}n|| j                  z
  dz   }| j                  j                  «       s|dk(  r|}n|}t        ||z  | j                  «      }| j                  j                  |z   | j                  j                   k  r-| j                  j                   | j                  j                  z
  }|r|}	n||z  |z  }	|	dk(  r|}	|||	fS )z¡
        Evaluates current trackers and state to determine sizes.

        Returns:
            tuple: (prefetch_size, io_size, effective_prefetch_size)
        NzTLarge IO detected (variable > 64MB or > user max). Disabling background prefetching.r   r   )r=   r   r;   Úsequential_streakr#   r(   rD   ÚVARIABLE_IO_THRESHOLDr   r   ÚMIN_STREAKS_FOR_PREFETCHINGr9   r_   rK   rN   ÚoffsetÚtarget_offset)
r   Úavg_io_sizeÚstreakr#   Úlast_read_sizeÚexceeds_user_maxÚprefetch_multiplierÚio_sizeÚprefetch_sizeÚeffective_prefetch_sizes
             r   Ú_calculate_prefetch_paramsz+PrefetchProducer._calculate_prefetch_params  sl  € ð —l‘l×*Ñ*ˆØ—‘×0Ñ0ˆØ—l‘l×.Ñ.ˆØŸ™×0Ñ0ˆð ×(Ñ(°Ð4ò ;Ø˜d×:Ñ:Ñ:ð 	ñ ˜K¨$×*DÑ*DÒDÙÜ�L‰LØfôð #$ÑØ�d×6Ñ6Ò6Ø"#Ñà"(¨4×+KÑ+KÑ"KÈaÑ"OÐà�:‰:×ÑÔÐ!4¸Ò!9Ø$‰Gà!ˆGäÐ/°'Ñ9¸4×;QÑ;QÓRˆØ�=‰=×Ñ -Ñ/°$·-±-×2MÑ2MÒMØ ŸM™M×7Ñ7¸$¿-¹-×:NÑ:NÑNˆMáØ&3Ñ#à'4¸Ñ'?À7Ñ&JÐ#Ø&¨!Ò+Ø*7Ð'à˜gÐ'>Ð>Ð>r   c              ƒ   ó  K  — | j                  «       \  }}}t        j                  d| j                  | j                  j
                  |«       | j                  �sn| j                  | j                  j
                  z
  |k  �rG| j                  | j                  k  �r-| j                  j
                  }| j                  | j                  z
  }|| j                  |z
  z
  }|| j                  k\  r2|| j                  k\  r!t        t        | j                  |«      |«      }n�n«t        ||«      }||k  r | j                  j                  s||k(  r|}n�nz| j                  j                  }|| j                  k  r| j                  }	n0t        | j                  t        d|| j                  z  |z  «      «      }	t        j                  d| j                  ||	«       t!        j"                  | j%                  | j                  ||	¬«      «      }
| j&                  j)                  |
«       |
j+                  | j&                  j,                  «       | j.                  j1                  |
«      ƒ d{  –—†  | xj                  |z  c_        | j                  sA| j                  | j                  j
                  z
  |k  r| j                  | j                  k  r�Œ-| j                  | j                  k\  rt        j                  d«       d| _        yy7 Œ�­w)z1Executes a single cycle of enqueuing fetch tasks.zFProducer awake. Current offset: %d, User offset: %d, Prefetch size: %dr   z;Spawning fetch task. Offset: %d, Size: %d, Split Factor: %d)Úsplit_factorNz.Producer reached EOF. Exiting background loop.T)r†   r   r   rE   r;   r|   rF   r7   ÚMIN_CHUNK_SIZErK   rL   r=   r#   ry   r{   r8   rP   rQ   rA   rG   r   Úadd_done_callbackÚdiscardr9   ru   )r   r„   rƒ   r…   Úuser_offsetÚspace_remainingÚprefetch_space_availableÚactual_sizer   ÚsfactorÚdownload_tasks              r   rq   z(PrefetchProducer._process_prefetch_cycleD  s•  è ø€ ð ×+Ñ+Ó-ñ 	8ˆ�wÐ 7ô 	�‰ØTØ×ÑØ�M‰M× Ñ Øô		
ð —“Ø×$Ñ$ t§}¡}×';Ñ';Ñ;¸}ÓLØ×#Ñ# d§i¡iÓ/àŸ-™-×.Ñ.ˆKØ"Ÿi™i¨$×*=Ñ*=Ñ=ˆOØ'4Ø×#Ñ# kÑ1ñ(Ð$ð  × 3Ñ 3Ò3Ø+¨t×/BÑ/BÒBÜ"%Ü˜D×/Ñ/°Ó9¸?ó#‘Kñ ä! '¨?Ó;�à'¨+Ò5à—L‘L×,Ò,Ø/°=Ò@à":‘Káà—]‘]×4Ñ4ˆFØ˜×8Ñ8Ò8Ø×*Ñ*‘äØ×$Ñ$ÜØØ# d×&6Ñ&6Ñ6Ð:QÑQóó�ô �L‰LØMØ×#Ñ#ØØô	ô $×/Ñ/Ø—‘˜T×0Ñ0°+ÈG�ÓTóˆMð ×Ñ×"Ñ" =Ô1Ø×+Ñ+¨D×,>Ñ,>×,FÑ,FÔGà—*‘*—.‘. Ó/×/Ð/Ø×Ò ;Ñ.Õðo —’Ø×$Ñ$ t§}¡}×';Ñ';Ñ;¸}ÒLØ×#Ñ# d§i¡iÔ/ðn ×Ñ $§)¡)Ò+Ü�L‰LÐIÔJØ"ˆD�Oð ,ð 0ús   ‚ILÉ!K?É"A$LË8LrV   )r,   r-   r.   r/   r‰   rM   r{   rz   r0   rP   ÚQueueÚEventr	   r   r1   rN   rS   rj   rn   rR   Útupler†   rq   r3   r   r   r5   r5   U   sØ   „ ñð %€Nð *Ðð #$Ðð -Ðð  $ñ-#ð ð-#ð ð	-#ð
 �}‰}ð-#ð —m‘mð-#ð %ð-#ð 'ð-#ð -ó-#ð^ ðE 3ò Eó ðEò@ò4"ðl	¨ó 	ò$ð*.?¨E°#°s¸C°-Ñ,@ó .?ó`I#r   r5   c                   óœ   — e Zd ZdZdej
                  dej                  deddfd„Zde	fd	„Z
d
„ Zde	dedee   fd„Zde	defd„Zde	ddfd„Zy)r<   zæConsumes prefetched chunks from the queue and manages byte slicing.

    This class pulls data out of the shared queue and slices it into the
    exact byte sizes requested by the user. It also manages the local block buffer.
    r9   r:   r=   r>   r?   c                 óÒ   — t         j                  d«       || _        || _        || _        t        j                  |«      | _        d| _        d| _	        d| _
        d| _        d| _        y)aŒ  Initializes the consumer.

        Args:
            queue (asyncio.Queue): The shared queue containing fetch tasks.
            wakeup_event (asyncio.Event): Event used to wake the producer when more data is needed.
            tracker (RunningAverageTracker): Tracker for history of read sizes.
            orchestrator (BackgroundPrefetcher): The parent object managing the operation.
        zInitializing PrefetchConsumer.r   r   N)r   r   r9   r:   r=   rB   rC   r>   ry   r|   r}   Ú_current_blockÚ_current_block_idx)r   r9   r:   r=   r>   s        r   r   zPrefetchConsumer.__init__—  s_   € ô 	�‰Ð5Ô6ØˆŒ
Ø(ˆÔØˆŒÜ#ŸM™M¨,Ó7ˆÔØ!"ˆÔØˆŒØˆÔØ!ˆÔØ"#ˆÕr   rk   c                 óv   — t         j                  d|«       || _        || _        d| _        d| _        d| _        y)z¥Clears the buffer and resets the internal offset for a hard seek.

        Args:
            new_offset (int): The byte position the consumer is jumping to.
        zDConsumer executing hard seek to offset %d. Clearing internal buffer.r   r   N)r   r   r|   r}   ry   r—   r˜   rm   s     r   ÚseekzPrefetchConsumer.seek±  s?   € ô 	�‰ØRØô	
ð !ˆŒØ'ˆÔØ!"ˆÔØ!ˆÔØ"#ˆÕr   c                 óJ   — t         j                  d«       d| _        d| _        y)zADiscards the local byte buffer. Useful during shutdown or resets.z$Consumer local block buffer cleared.r   r   N)r   r   r—   r˜   r'   s    r   Úclear_bufferzPrefetchConsumer.clear_bufferÁ  s   € ä�‰Ð;Ô<Ø!ˆÔØ"#ˆÕr   r7   Ú	save_datar   c              ƒ   ó€  K  — |dk  rg S g }d}| j                   |z   | _        ||k  �r6t        | j                  «      | j                  z
  }d}|�s| j
                  j                  du xs  | j
                  j                  j                  }|r2| j                  j                  «       rt        j                  d«       	 |S | j                  j                  «       r/t        j                  d«       | j                  j                  «        | j                  j                  «       ƒ d{  –—† }t        |t         «      r3t        j#                  d|«       | j
                  j%                  |«       |‚	 |ƒ d{  –—† }	| xj&                  dz  c_        | j&                  t(        j*                  k\  r¢| j
                  j,                  duxr- | j.                  j0                  | j
                  j,                  kD  }
| j.                  j2                  xr' | j.                  j0                  t(        j4                  kD  }|s|
sd}nt        j                  d	«       |	| _        d| _        t        | j                  «      }| j                  s	 |S ||z
  }t=        ||«      }|r}|t        | j                  «      k(  r| j                  dk(  r| j                  }n8t7        j>                  t@        | j                  | j                  |«      ƒ d{  –—† }|jC                  |«       | xj                  |z  c_        ||z  }| xj                   |z  c_         |r| j                  j                  «        ||k  r�Œ6|S 7 �Œ=7 �Œò# t6        j8                  $ r ‚ t         $ r7}t        j;                  d
«       | j
                  j%                  |«       |‚d}~ww xY w7 ŒÅ­w)z•Internal method to advance the offset and optionally extract data.

        Handles queue exhaustion, producer wakeups, and streak tracking.
        r   FNzConsumer reached EOF.z#Queue is empty. Waking up producer.z#Consumer retrieved an exception: %sr   TzfSuppressing proactive producer wakeup due to massive variable workload or exceeding user max prefetch.zConsumer caught an error.)"r|   r}   r   r—   r˜   r>   ÚproducerrF   r9   r_   r   r   r:   r"   Úgetra   rs   Úerrorrt   ry   r5   r{   rN   r=   r   r#   rz   rP   rr   rd   rK   Ú	to_threadr   r   )r   r7   r�   ÚchunksÚ	processedÚ	availableÚtrigger_wakeupÚis_producer_stoppedrY   Úblockr�   Úis_massive_variablerw   ÚneededÚtakeÚchunks                   r   Ú_advancezPrefetchConsumer._advanceÇ  sc  è ø€ ð
 �1Š9ØˆIàˆØˆ	Ø!Ÿ[™[¨4Ñ/ˆÔà˜$ÓÜ˜D×/Ñ/Ó0°4×3JÑ3JÑJˆIØ"ˆNâà×%Ñ%×.Ñ.°$Ð6ò =Ø×(Ñ(×1Ñ1×<Ñ<ð $ñ '¨4¯:©:×+;Ñ+;Ô+=Ü—L‘LÐ!8Ô9ØðT ˆðQ —:‘:×#Ñ#Ô%Ü—L‘LÐ!FÔGØ×%Ñ%×)Ñ)Ô+à!ŸZ™ZŸ^™^Ó-×-�ä˜d¤IÔ.Ü—L‘LÐ!FÈÔMØ×%Ñ%×/Ñ/°Ô5Ø�Jð%Ø"&ŸJ�Eà×*Ò*¨aÑ/Õ*à×.Ñ.Ü+×GÑGòHð !×-Ñ-×?Ñ?ÀtÐKò BØ $§¡× 4Ñ 4Ø"×/Ñ/×AÑAñ!Bð )ð !ŸL™L×4Ñ4ò EØ $§¡× 4Ñ 4Ü.×DÑDñ!Eð ,ñ !4Ñ7GØ-1™Nä"ŸL™Lð!Lôð
 +0�DÔ'Ø./�DÔ+Ü # D×$7Ñ$7Ó 8�Ið ×&Ò&Øð* ˆð' ˜IÑ%ˆFÜ�v˜yÓ)ˆDáØœ3˜t×2Ñ2Ó3Ò3¸×8OÑ8OÐSTÒ8TØ ×/Ñ/‘Eô #*×"3Ñ"3Ü# T×%8Ñ%8¸$×:QÑ:QÐSWó#÷ �Eð —‘˜eÔ$à×#Ò# tÑ+Õ#Ø˜ÑˆIØ�KŠK˜4Ñ�KÙØ×!Ñ!×%Ñ%Ô'ðg ˜$Ôðj ˆðI .ùð 'úô> ×-Ñ-ò ØÜ ò Ü×$Ñ$Ð%@ÔAØ×%Ñ%×/Ñ/°Ô2Ø�Gûðúð ús^   ‚D!N>Ä#M Ä$AN>Å,M& Å1M#Å2C;M& É-B	N>Ë6N<Ë7A%N>ÍN>Í#M& Í&N9Î2N4Î4N9Î9N>c              ƒ   óÐ   K  — |dk  ry| j                  |d¬«      ƒ d{  –—† }|syt        |«      dk(  r|d   S t        j                  dj                  |«      ƒ d{  –—† S 7 ŒB7 Œ­w)aä  Pulls exactly 'size' bytes from the local block or the task queue.

        If the local block is exhausted, this will wait on the queue for the next
        available chunk of data.

        Args:
            size (int): The exact number of bytes to retrieve.

        Returns:
            bytes: The requested bytes. This may be shorter than 'size' if EOF is reached.

        Raises:
            Exception: Re-raises any exceptions encountered by the producer fetch tasks.
        r   r   T©r�   Nr   )r­   r   rP   r¢   Újoin)r   r7   r£   s      r   ÚconsumezPrefetchConsumer.consume*  sh   è ø€ ð �1Š9Øà—}‘} T°T�}Ó:×:ˆáØäˆv‹;˜!ÒØ˜!‘9Ðä×&Ñ& s§x¡x°Ó8×8Ð8ð ;øð 9ús!   ‚A&ŸA" =A&ÁA$ÁA&Á$A&Nc              ƒ   óF   K  — | j                  |d¬«      ƒ d{  –—†  y7 Œ­w)z7Advances the consumer offset without allocating memory.Fr¯   N)r­   )r   r7   s     r   ÚskipzPrefetchConsumer.skipF  s   è ø€ à�m‰m˜D¨EˆmÓ2×2Ò2ús   ‚!™š!)r,   r-   r.   r/   rP   r’   r“   r	   r   r0   rš   rœ   r2   r^   Úbytesr­   r±   r³   r3   r   r   r<   r<   �  s”   „ ñð$à�}‰}ð$ð —m‘mð$ð 'ð	$ð
 -ó$ð4$˜só $ò $ða 3ð a°4ð a¸DÀ¹Kó aðF9 #ð 9¨%ó 9ð83˜sð 3 tô 3r   r<   c                   ó¾   — e Zd ZdZdZ	 ddedefd„Zd„ Zd„ Zd„ Z	d	„ Z
d
efd„Zdefd„Zd„ Zd„ Zdedz  dedz  defd„Zdedz  dedz  defd„Zd„ Zddedz  fd„Zy)r?   a&  Orchestrator that manages reading behavior and coordinates background work.

    This acts as the main public interface for the file reader. It tracks the
    user's reading history, routes seek operations, and links the producer's
    network tasks with the consumer's data slicing logic.
    Nr7   r8   c                 óº  ‡ ‡‡‡— t         j                  d||‰«       |‰ _        |‰ _        ‰‰ _        ‰�&‰dk  r!t         j                  d‰«       t        d«      ‚|‰ _        d‰ _        d‰ _	        d‰ _
        t        d¬«      ‰ _        d‰ _        d‰ _        d‰ _        d‰ _        d‰ _        ˆˆˆ fd	„Š	 t%        j&                  «       }|‰ j                  u r‰ j                  � ‰«        nN‰ j                  �&ˆfd
„}t+        j,                  ‰ j                  |«       n|�|‰ _         ‰«        nt)        d«      ‚t         j                  d«       y# t(        $ r d}Y Œ“w xY w)aƒ  Initializes the background prefetcher.

        Args:
            fetcher (Callable): A coroutine of the form `f(start, end)` which gets bytes from the remote.
            size (int): Total byte size of the file being read.
            concurrency (int): Number of concurrent network requests to use for large chunks.
            max_prefetch_size (int, optional): Maximum bytes to prefetch ahead of the current user offset.
            loop (asyncio.AbstractEventLoop, optional): The event loop to attach the prefetcher to.
                If executing synchronously, this should be the fsspec background loop. If executing
                asynchronously (asynchronous=True), this should be None so it can automatically
                inherit the user's currently running event loop.

        Raises:
            ValueError: If max_prefetch_size is provided but is not a positive integer.
        zJStarting BackgroundPrefetcher. Size: %d, Concurrency: %d, Max Prefetch: %sNr   z&Invalid max_prefetch_size provided: %szKmax_prefetch_size should be a positive integer to use adaptive prefetching!Fr+   r   c                  óÞ  •— t        j                  «       ‰_        t        j                  «       ‰_        t        j
                  «       ‰_        t        ‰j                  ‰j                  ‰j                  ‰¬«      ‰_	        t        ‰ ‰j                  ‰j                  ‰j                  ‰j                  ‰j                  ‰j                  ‰‰¬«	      ‰_        ‰j                  j                  «        y )N)r9   r:   r=   r>   )	rA   r7   r8   r9   r:   r;   r=   r>   rI   )rP   r’   r9   r“   r:   ÚLockÚ_async_lockr<   Úread_trackerr;   r5   r7   r8   rŸ   rS   )rA   rN   r   s   €€€r   Ú_startz-BackgroundPrefetcher.__init__.<locals>._startƒ  s­   ø€ ä Ÿ™›ˆDŒJÜ '§¡£ˆDÔÜ&Ÿ|™|›~ˆDÔä,Ø—j‘jØ!×.Ñ.Ø×)Ñ)Ø!ô	ˆDŒMô -ØØ—Y‘YØ ×,Ñ,Ø—j‘jØ!×.Ñ.ØŸ™Ø×)Ñ)Ø!Ø'8ô
ˆDŒMð �M‰M×ÑÕ!r   c               “   ó   •K  —  ‰ «        y ­wrV   r3   )r»   s   €r   Ú_start_wrapperz5BackgroundPrefetcher.__init__.<locals>._start_wrapper§  s   øè ø€ Ù•ùs   ƒ	zNo event loop foundz-BackgroundPrefetcher initialization complete.)r   r   r7   r8   rN   r¡   r   ÚloopÚ_errorrF   rŒ   r	   rº   r9   r:   r¹   r;   rŸ   rP   Úget_running_loopr&   Úfsspec_asynÚsync)	r   rA   r7   r8   rN   r¾   Úcurrent_loopr½   r»   s	   ``  `   @r   r   zBackgroundPrefetcher.__init__U  sQ  û€ ô$ 	�‰ØXØØØô		
ð ˆŒ	Ø&ˆÔØ!2ˆÔàÐ(Ð->À!Ò-CÜ�L‰LÐAÐCTÔUÜØ]óð ð ˆŒ	ØˆŒØˆŒØˆÔÜ1¸Ô<ˆÔàˆŒ
Ø ˆÔØˆÔØˆŒØˆŒö	"ð4	 Ü"×3Ñ3Ó5ˆLð ˜4Ÿ9™9Ñ$¨¯©Ð)>á�HØ�Y‰YÐ"ôô ×Ñ˜TŸY™Y¨Õ7ØÐ%à$ˆDŒIÙ�Hô Ð4Ó5Ð5ä�‰ÐDÕEøô) ò 	 ØŠLð	 ús   Â2E ÅEÅEc                 ó   — | S )zContext manager entry point.r3   r'   s    r   Ú	__enter__zBackgroundPrefetcher.__enter__µ  s   € àˆr   c                 ó$   — | j                  «        y)zEContext manager exit point. Ensures the prefetcher is cleanly closed.N)Úclose©r   Úexc_typeÚexc_valÚexc_tbs       r   Ú__exit__zBackgroundPrefetcher.__exit__¹  s   € à�
‰
�r   c              ƒ   ó   K  — | S ­w)z"Async context manager entry point.r3   r'   s    r   Ú
__aenter__zBackgroundPrefetcher.__aenter__½  s   è ø€ àˆùs   ‚c              ƒ   ó@   K  — | j                  «       ƒ d{  –—†  y7 Œ­w)zKAsync context manager exit point. Ensures the prefetcher is cleanly closed.N)ÚacloserÈ   s       r   Ú	__aexit__zBackgroundPrefetcher.__aexit__Á  s   è ø€ à�k‰k‹m×Òús   ‚–—rw   c                 ó>   — t         j                  d|«       || _        y )Nz2Global error state set in BackgroundPrefetcher: %s)r   r¡   r¿   rv   s     r   rt   zBackgroundPrefetcher.set_errorÅ  s   € Ü�‰ÐIÈ1ÔMØˆ�r   rk   c              ƒ   óú   K  — t         j                  d|«       d | _        | j                  j	                  |«      ƒ d {  –—†  | j
                  j                  |«       | j                  j                  «        y 7 Œ:­w)Nz8Handling seek request. Restarting producer at offset: %d)	r   r   r¿   rŸ   rn   r;   rš   rº   r*   rm   s     r   Ú_restart_producerz&BackgroundPrefetcher._restart_producerÉ  sa   è ø€ Ü�‰ØFÈ
ô	
ð ˆŒØ�m‰m×#Ñ# JÓ/×/Ð/Ø�‰×Ñ˜:Ô&Ø×Ñ×ÑÕ!ð 	0ús   ‚<A;¾A9¿;A;c           	   ƒ   óè  K  — | j                   4 ƒd{  –—†  	 | j                  rt        d«      ‚t        j	                  d||«       | j
                  r8t        j                  d|«       || _        | j                  |«      ƒ d{  –—†  �nŸ|| j                  k7  �r�| j                  j                  | j                  j                  z
  }| j                  |cxk  r| j                  j                  k  r^n n[t        j	                  d| j                  |«       || j                  z
  }| j                  j                  |«      ƒ d{  –—†  || _        nÛ||cxk  r| j                  j                  k  r{n nxt        j	                  d| j                  || j                  j                  ||z
  «       ||z
  | j                  _        || j                  _
        || j                  _        || _        nAt        j	                  d| j                  |«       || _        | j                  |«      ƒ d{  –—†  ||z
  }| j                   j#                  |«       | j                  j%                  |«      ƒ d{  –—† }| xj                  t'        |«      z  c_        t        j	                  dt'        |«      «       |cddd«      ƒd{  –—†  S 7 �Œª7 �Œ<7 �Œ�7 Œ 7 Œ_7 Œ# t(        j*                  $ r}|| _        ‚ d}~wt,        $ rg}t        j/                  d	«       || _        | j                  r9| j                  j                  s#| j                  j1                  «       ƒ d{  –—†7   ‚ d}~ww xY w# 1 ƒd{  –—†7  sw Y   yxY w­w)
zGCore internal async fetching logic, protected safely by the async lock.Nz"The file instance has been closed.z)Executing _async_fetch for range %d - %d.z>Recovering from error state. Restarting producer at offset: %dz1Soft seek detected. Skipping ahead from %d to %d.z\Local seek performed. User offset moved from %d to %d. Adjusting buffer index from %d to %d.z5Hard seek detected. Moving user offset from %d to %d.z*Completed _async_fetch. Returned %d bytes.z+Exception raised during asynchronous fetch.)r¹   rF   r&   r   r   r¿   ÚinforŒ   rÔ   r;   r|   r˜   rŸ   rE   r³   r}   rº   r   r±   r   rP   rr   rs   rd   rj   )r   rS   ÚendÚblock_offsetÚskip_amountÚrequested_sizer¬   rw   s           r   Ú_async_fetchz!BackgroundPrefetcher._async_fetchÒ  så  è ø€ à×#Ñ#÷ B	ñ B	ðAØ—?’?Ü&Ð'KÓLÐLä—‘ÐHÈ%ÐQTÔUð —;’;Ü—K‘KØXØôð (-�DÔ$Ø×0Ñ0°Ó7×7Ò7Ø˜d×.Ñ.Ó.àŸ™×,Ñ,¨t¯}©}×/OÑ/OÑOð !ð ×'Ñ'¨%ÔO°4·=±=×3OÑ3OÕOÜŸ™ØOØ ×,Ñ,Ø!ôð
 ',¨d×.>Ñ.>Ñ&>˜Ø"Ÿm™m×0Ñ0°Ó=×=Ð=Ø+0˜Õ(Ø%¨ÔE°·±×1EÑ1EÕEÜŸ™ðDà ×,Ñ,Ø!Ø ŸM™M×<Ñ<Ø! LÑ0ôð <AÀ<Ñ;O˜Ÿ™Ô8Ø/4˜Ÿ™Ô,Ø6;˜Ÿ™Ô3Ø+0˜Õ(äŸ™ØSØ ×,Ñ,Ø!ôð
 ,1˜Ô(Ø"×4Ñ4°UÓ;×;Ð;à!$ u¡�Ø×!Ñ!×%Ñ% nÔ5à"Ÿm™m×3Ñ3°NÓC×C�Ø× Ò ¤C¨£JÑ.Õ ä—‘ÐIÌ3ÈuË:ÔVØ÷sB	÷ B	ò B	ùð 8ùð >ùð, <øð
 DøðkB	ùôt ×)Ñ)ò Ø�”ØûÜò Ü× Ñ Ð!NÔOØ�”Ø—=’=¨¯©×)AÒ)AØŸ-™-×,Ñ,Ó.×.Ñ.Øûðú÷{B	÷ B	ñ B	üsÇ   ‚M2“J=”M2—M™A+KÂK ÂB=KÅKÅC"KÈ%KÈ&AKÉ(KÉ)AKÊ+M2Ê7K
Ê8M2Ë KËKËKËKË
M2ËMËK'Ë'MË3AMÍMÍMÍMÍMÍM/Í#M&Í$M/Í+M2c              ƒ   óœ  K  — | j                   4 ƒd{  –—†  t        j                  d«       | j                  r8| j                  j                  s"| j                  j                  «       ƒ d{  –—†  | j                  j                  «        t        j                  d«       ddd«      ƒd{  –—†  y7 Œ�7 ŒF7 Œ	# 1 ƒd{  –—†7  sw Y   yxY w­w)a  Asynchronous teardown logic protected by the async lock.

        Held for the duration of teardown so a concurrent in-flight
        ``_async_fetch`` cannot observe a stopped producer/empty queue as
        EOF and silently return a truncated read.
        Nz4Signaling prefetcher stop and tearing down producer.z)BackgroundPrefetcher closed successfully.)r¹   r   r   rŸ   rF   rj   r;   rœ   r'   s    r   Ú_async_closez!BackgroundPrefetcher._async_close  s¢   è ø€ ð ×#Ñ#÷ 	Fñ 	FÜ�L‰LÐOÔPà�}Š} T§]¡]×%=Ò%=Ø—m‘m×(Ñ(Ó*×*Ð*à�M‰M×&Ñ&Ô(Ü�L‰LÐDÔE÷	F÷ 	Fñ 	Føð +øð		Fø÷ 	F÷ 	Fñ 	FüsW   ‚C“B1”C—AB7Á,B3Á-3B7Â CÂ+B5Â,CÂ3B7Â5CÂ7C	Â=C Â>C	ÃCrS   r×   r   c              ƒ   óB  K  — |€d}|€| j                   }t        || j                   «      }t        j                  d||«       || j                   k\  s||k\  ry| j                  r t        j                  d«       t        d«      ‚| j                  ||«      ƒ d{  –—† S 7 Œ­w)z)Asynchronous API counterpart to `_fetch`.Nr   z7Asynchronous afetch called for bounds start=%s, end=%s.r   z=Cannot fetch data: BackgroundPrefetcher is stopped or closed.zŒThe file instance has been closed. This can occur if a close operation is executed concurrently while a read operation is still in progress.)r7   rK   r   r   rF   r¡   r&   rÛ   ©r   rS   r×   s      r   ÚafetchzBackgroundPrefetcher.afetch(  sž   è ø€ àˆ=ØˆEØˆ;Ø—)‘)ˆCä�#�t—y‘yÓ!ˆÜ�‰ØEÀuÈcô	
ð �D—I‘IÒ ¨#¢Øà�?Š?Ü�L‰LØOôô ðXóð ð
 ×&Ñ& u¨cÓ2×2Ð2Ð2ús   ‚BBÂBÂBc                 óZ   — t        j                  | j                  | j                  ||«      S )z/Synchronous API wrapper delegating to `afetch`.)rÁ   rÂ   r¾   rà   rß   s      r   ÚfetchzBackgroundPrefetcher.fetchB  s#   € ô ×Ñ §	¡	¨4¯;©;¸¸sÓCÐCr   c              ƒ   óN   K  — d| _         | j                  «       ƒ d{  –—†  y7 Œ­w)z>Safely shuts down the prefetcher from an asynchronous context.TN)rF   rÝ   r'   s    r   rÐ   zBackgroundPrefetcher.acloseG  s   è ø€ àˆŒØ×ÑÓ!×!Ò!ús   ‚%�#ž%Útimeoutc                 óú   — d| _         	 t        | j                  | j                  |d¬«       y# t        j
                  $ r t        j                  d|«       Y yt        $ r t        j                  dd¬«       Y yw xY w)a¸  Safely shuts down the prefetcher from a synchronous context.

        Schedules teardown on the IO loop. If the wait times out, teardown
        continues in the background to let in-flight reads finish cleanly.

        Args:
            timeout: Maximum seconds to wait for teardown to finish. Defaults
                to 10.0 seconds. If 0 or negative, teardown runs fire-and-forget.
                If None, waits indefinitely.
        TzBackgroundPrefetcher teardown)rä   ÚdescriptionzbBackgroundPrefetcher teardown did not complete within %ss; it will keep running in the background.z,Exception while closing BackgroundPrefetcher)Úexc_infoN)	rF   r   r¾   rÝ   rÁ   ÚFSTimeoutErrorr   Úwarningrs   )r   rä   s     r   rÇ   zBackgroundPrefetcher.closeL  sy   € ð ˆŒð	ÜØ—	‘	Ø×!Ñ!ØØ;ö	øô ×)Ñ)ò 	Ü�N‰Nð:àöô
 ò 	Ü�N‰NØ>Èð ö ð	ús   ‰#- ­)A:ÁA:Á9A:)NN)g      $@)r,   r-   r.   r/   rŸ   r0   r   rÅ   rÌ   rÎ   rÑ   rs   rt   rÔ   rÛ   rÝ   r´   rà   râ   rÐ   ÚfloatrÇ   r3   r   r   r?   r?   K  sÇ   „ ñð €Hð RVñ^FØ ð^FØ/2ó^Fò@òòòð˜9ó ð"°#ó "òDòLFð 3 #¨¡*ð 3°3¸±:ð 3À%ó 3ð4D˜3 ™:ð D¨C°$©Jð D¸5ó Dò
"ñ
˜U T™\ô r   r?   )rP   ÚloggingrB   Úcollectionsr   Ú r   rÁ   r   Úutilsr   Ú	getLoggerr,   r   r	   r5   r<   r?   r3   r   r   ú<module>rð      s_   ðÛ Û Û Ý å !Ý Ý à	ˆ×	Ñ	˜8Ó	$€÷Eñ E÷Px#ñ x#÷v	x3ñ x3÷v^ò ^r   