+
    :1j*p                       R t ^ RIHt ^ RIt^ RIt^ RIt^ RIt^ RIHt ^ RI	H
t
Ht ^ RIHt ^ RIHt ^ RIHt ^ RIHt ^ RIt^ RIt^ RIt^ R	IHt ^R
IHt ^RIHt ^RIHtHtHtH t H!t! ^RI"H#t#H$t$H%t%H&t&H't'H(t( ]PR                  ! ]*4      t+]'       d3   ^ RI,H-t-H.t.H/t/H0t0 ^ RIHt1 ^ RIH2t2H3t3 ^ RI4H5t5 ^RIH6t6 ^RI"H7t7 ^RIH8t8 ^t9^
t:^t;]! RR7       ! R R4      4       t<]! RRRR7       ! R R4      4       t=R R lt> ! R R4      t?]?P                  ]!^3R R  lltA]'       d	   ]3! R!4      tB ! R" R#4      tC]R$ R% l4       tD]R& R' l4       tE]R( R) l4       tFR# )*a  
Sharded repodata subsets.

Traverse dependencies of installed and to-be-installed packages to generate a
useful subset for the solver.

The algorithm developed here is a direct result of the following CEP:

- https://conda.org/learn/ceps/cep-0016 (Sharded Repodata)

In this algorithm we treat a (channel, package name) as a node, its dependencies
as edges. We then traverse all edges to discover all reachable (channel, package
name) tuples. The solver should be able to find a solution with only this
subset.

This subset is overgenerous since the user is unlikely to want to install very
old packages and their dependencies. If this is too slow, we could deploy
heuristics that automatically ignore older package versions. We could also allow
the user to configure minimum versions of common packages and ignore older
versions and their dependencies, falling back to a full solve if unsatisfiable.

We treat both sharded and monolithic repodata as if they were made up of
per-package shards, computing a subset of both. This is because it is possible
for the monolithic repodata to mention packages that exist in the true sharded
repodata but would not be found by only traversing the shards.

We treat all repodata as sharded, even if no actual sharded repodata has been
found.

## Example usage

The following constructs several repodata (`noarch` and `linux-64`) from a
single channel name and a list of root packages:

``` from conda.models.channel import Channel from
_conda.shards_subset import build_repodata_subset

channel = Channel("conda-forge-sharded/linux-64") channel_data =
build_repodata_subset(["python", "pandas"], [channel.url()]) repodata = {}

for url in channel_data:
    repodata[url] = channel_data.build_repodata()

# ... this is what's fed to the solver ```

)annotationsN)deque)FutureThreadPoolExecutor)	dataclass)Path)SimpleQueue)TYPE_CHECKING)context)cache)AnnotatedRawShard)_shards_connectionscombine_batches_until_noneexception_to_queuefilter_redundant_packagesspec_to_package_name)ZSTD_MAX_SHARD_SIZEShardsbatch_retrieve_from_cachebatch_retrieve_from_networkfetch_channelsshard_mentioned_packages)CallableIterableIteratorSequence)LiteralTypeVar)Channel)
ShardCache)	ShardBase)	ShardDictT)orderc                  ~    ] tR t^lt$ ]P
                  tR]R&   RtR]R&   Rt	R]R&   Rt
R]R	&   RtR]R
&   R R ltRtR# )Nodeintdistance strpackagechannelFboolvisited	shard_urlc                   V ^8  d   QhRR/# )   returnNodeId )formats   "<lib/python3.14/site-packages/conda/_private/shards/subset.py__annotate__Node.__annotate__t   s     B Bv B    c                	X    \        V P                  V P                  V P                  4      # N)r1   r)   r*   r-   selfs   &r4   to_id
Node.to_idt   s    dllDLL$..AAr7   r2   N)__name__
__module____qualname____firstlineno__sysmaxsizer&   __annotations__r)   r*   r,   r-   r<   __static_attributes__r2   r7   r4   r$   r$   l   sD    KKHcGSGSGTIsB Br7   r$   )r"   eqfrozenc                  @    ] tR t^xt$ R]R&   R]R&   RtR]R&   R tRtR# )	r1   r(   r)   r*   r'   r-   c                	Z    \        V P                  V P                  V P                  34      # r9   )hashr)   r*   r-   r:   s   &r4   __hash__NodeId.__hash__~   s     T\\4<<@AAr7   r2   N)r>   r?   r@   rA   rD   r-   rK   rE   r2   r7   r4   r1   r1   x   s    LLIsBr7   r1   c               $    V ^8  d   QhRRRRRR/# )r/   root_packagesz	list[str]
shardlikesIterable[ShardBase]r0   zIterator[tuple[NodeId, Node]]r2   )r3   s   "r4   r5   r5      s$     $ $$*=$"$r7   c           
   #     "   V  FP  pV FG  pW#9   g   K  \        ^ W#P                  VP                  V4      R7      pVP                  4       pWT3x  KI  	  KR  	  R# 5i)zA
Yield (NodeId, Node) for all root packages found in shardlikes.
)r-   N)r$   urlr-   r<   )rN   rO   r)   	shardlikenodenode_ids   &&    r4   _nodes_from_packagesrV      sV      !#I#w9L9LW9U **,m# $ !s   AAAc                     ] tR t^t$ RtR]R&   RtR]R&   R]R&   R]R	&   R
]R&   ]^3R R llt]	R R l4       t
]R R l4       tR R ltR R ltR]/R R lltR tR R ltR tR R ltR R  ltR! R" ltR# R$ ltR%tR&# )'RepodataSubsetz
Build a subset of repodata by traversing all packages that are dependencies
and transitive dependencies of a root set of packages.
Sequence[ShardBase]rO   	pipelinedzdict[NodeId, Node]_nodesr+   _use_only_tar_bz2_add_pip_as_python_dependencyCallable[[str], str]_spec_to_package_namec               $    V ^8  d   QhRRRRRR/# )r/   rO   rP   r   r^   repodata_versionr%   r2   )r3   s   "r4   r5   RepodataSubset.__annotate__   s(     2 2'2 32 	2r7   c                	    / V n         \        V4      V n        \        P                  V n        \        P                  V n        W n        W0n	        R # r9   )
r[   listrO   r
   use_only_tar_bz2r\   add_pip_as_python_dependencyr]   r_   _repodata_version)r;   rO   r   ra   s   &&&&r4   __init__RepodataSubset.__init__   s?     z*!(!9!9-4-Q-Q*%9"!1r7   c                   V ^8  d   QhRR/# )r/   r0   r%   r2   )r3   s   "r4   r5   rb      s        C  r7   c                ,    \        V P                  4      # )z?Number of (channel, package) nodes discovered during traversal.)lenr[   r:   s   &r4   
node_countRepodataSubset.node_count   s     4;;r7   c                    V ^8  d   QhRRRR/# )r/   strategyr(   r0   r+   r2   )r3   s   "r4   r5   rb      s     5 5C 5D 5r7   c                     \        V RV 24      # )zH
Return True if this class provides the named shard traversal strategy.

reachable_)hasattr)clsrp   s   &&r4   has_strategyRepodataSubset.has_strategy   s    
 sj
344r7   c                    V ^8  d   QhRRRR/# )r/   rT   r$   r0   zIterator[Node]r2   )r3   s   "r4   r5   rb      s     00 00t 00 00r7   c              #    "   \        4       pV P                   EF=  pVP                  V9  d   K  VP                  VP                  4      p\	        W@P
                  4      pVP                  VP                  V4       V P                  '       d   VP                  R8X  d   RMRp\        VVV P                  V P                  R7       F  p\        WcP                  4      pWpP                  9  g   K*  \        VP                  ^,           WcP                  4      V P                  V&   V P                  V,          x  Wb9  g   K{  VP!                  V4       K  	  EK@  	  R# 5i)a@  
Retrieve all unvisited neighbors of a node.

Neighbors in the context are dependencies of a package.

NOTE: This method assumes that the required shards have already been
retrieved from the network via batch_retrieve_from_network() before
neighbors() is called. It uses visit_package() to access already-loaded shards.
pythonextrar   ra   Npipr2   )setrO   r)   visit_packager   r\   visit_shardr]   r   r_   rg   r1   rR   r[   r$   r&   add)r;   rT   
discoveredrS   shardr{   r)   rU   s   &&      r4   
_neighborsRepodataSubset._neighbors   s     U
I||9,
 ++DLL9E-e5K5KLE !!$,,6
 555$,,(:R  
 4%)%?%?!%!7!7	 !--8++-+/)7MM,DKK( ++g..0"w/!) )s   C)E0AEEc                   V ^8  d   QhRR/# )r/   rT   r$   r2   )r3   s   "r4   r5   rb      s     
 
d 
r7   c              #  J   "   V P                  V4       F	  pV^3x  K  	  R# 5i)z8
All nodes that can be reached by this node, plus cost.
N)r   )r;   rT   ns   && r4   	_outgoingRepodataSubset._outgoing   s#      &AQ$J 's   !#rp   c                   V ^8  d   QhRR/# )r/   r0   Noner2   )r3   s   "r4   r5   rb      s     E E Er7   c               ,    \        V RV 24      ! V4      # )z
Run named reachability strategy or the default.

Update `self.shardlikes` with reachable package records. Later,
[shardlike.build_repodata() for shardlike in shardlikes] can be used to
generate repodata.json-format subsets of each channel.
rr   )getattr)r;   rN   rp   s   &&$r4   	reachableRepodataSubset.reachable   s     tz(45mDDr7   c                    \         P                  ! \        \        P                  P
                  P                  4       4      4      ;_uu_ 4       pV P                  W4      uuRRR4       #   + '       g   i     R# ; i)z
Fetch all packages reachable from `root_packages`' by following
dependencies using the "breadth-first search" algorithm.

Update associated `self.shardlikes` to contain enough data to build a
repodata subset.
N)r   r   r   condagatewaysrepodatacreate_cache_dir_reachable_bfs)r;   rN   shard_caches   && r4   reachable_bfsRepodataSubset.reachable_bfs  sX     ((99;<
 
&&}B
 
 
 
s   A**A;	c                   V ^8  d   QhRR/# )r/   r   cache.ShardCacher2   )r3   s   "r4   r5   rb     s     5 59I 5r7   c                   \        \        WP                  4      4      V n        \	        V P                  P                  4       4      pV'       d   V Uu0 uF"  qDP                  '       d   K  VP                  kK$  	  ppV'       d4   \        V P                  \        V4      V4      pV'       d   \        V4       \        V4      p\        V4       Fm  pVP                  4       pVP                  '       d   K'  RVn        V P                  V4       F*  w  rV	P                  '       d   K  VP                  V	4       K,  	  Ko  	  K  R# u upi )z'
Inner reachable_bfs() implementation.
TN)dictrV   rO   r[   r   valuesr,   r)   r   sortedr   rl   rangepopleftr   append)
r;   rN   r   
node_queuerT   to_retrieveneeds_network
level_size_	next_nodes
   &&&       r4   r   RepodataSubset._reachable_bfs  s     /OP4;;--/0
4>SJDll<4<<JKS 9OOVK%8+! !/> ZJ:&!))+<<<#$(NN4$8LI$,,,")))4 %9 ' Ss   E+Ec                F   \         P                  '       d   \        pM\        p\        P
                  ! \        \        P                  P                  P                  4       4      4      ;_uu_ 4       pV P                  WVR7      uuRRR4       #   + '       g   i     R# ; i)z
Fetch all packages reachable from `root_packages`' by following
dependencies.

Build repodata subset using concurrent threads to follow dependencies,
fetch from cache, and fetch from network.
)network_workerr   N)r
   offlineoffline_nofetch_threadnetwork_fetch_threadr   r   r   r   r   r   r   _reachable_pipelined)r;   rN   r   cache_instances   &&  r4   reachable_pipelined"RepodataSubset.reachable_pipelined-  sw     ???3N1N ((99;<
 
,,N - 
 
 
 
s   1BB 	c                    V ^8  d   QhRRRR/# )r/   r   zCallable[[Queue[Sequence[NodeId] | None], Queue[list[tuple[NodeId, ShardDict] | Exception]], cache.ShardCache, Sequence[ShardBase]], None]r   r   r2   )r3   s   "r4   r5   rb   G  s      85 85
85  85r7   c                B   \        4       p\        4       p\        4       p\        P                  ! \        WEWc3RR7      p\        P                  ! VVV\	        V4      V P
                  3RR7      p VP                  4        VP                  4        V P                  VVVVV4       VP                  R4       VP                  \        4       VP                  \        4       R#   TP                  R4       TP                  \        4       TP                  \        4       i ; i)zs
Set up queues and threads for shard traversal with a configurable
network_worker. Called by reachable_pipelined()
T)targetargsdaemonN)r   	threadingThreadcache_fetch_thread
QueueCacherO   start_pipelined_traversalputjoinTHREAD_WAIT_TIMEOUT)	r;   rN   r   r   cache_in_queueshard_out_queuecache_miss_queuecache_threadnetwork_threads	   &&&&     r4   r   #RepodataSubset._reachable_pipelinedG  s   & <G=M 	 >I] ''% 3CK
 #))! >*	 	
	5   "%% t$12 34 t$12 34s   /5C! !=Dc               (    V ^8  d   QhRRRRRRRR/# )r/   r   zQueue[list[NodeId] | None]r   z1Queue[list[tuple[NodeId, ShardDict]] | Exception]r   zthreading.Threadr   r2   )r3   s   "r4   r5   rb     s;     u u 3u K	u
 'u )ur7   c                  a aaaaaaaa S P                    Uu/ uF  qfP                  VbK  	  upo\        4       o\        4       o^ o/ S n        \	        ^ 4      pSP                  S P                  Wq4      4       VVVV VV3R lpVVVV VV3R lp	 V! 4        S'       g   \        P                  R4       R#  SP                  \        R7      p
\        V
\        4      '       d   V
h ^ oT
 F  w  rSP                  T4       \!        TS P"                  4      pS P                  T,          pSTP$                  ,          pTP'                  TP(                  T4       S P*                  '       d   TP(                  R8X  d   RMR	pSP                  S P                  T\-        TTS P.                  S P0                  R7      4      4       K  	  EK9  u upi   \        P                   d    T	! 4         EK^  i ; i)
zG
Run reachability algorithm given queues to submit and receive shards.
c                   < SP                  SS4      w  rV'       d#   SP                  V4       SP                  V4       V '       d*   SP                  R V  4       4       SP                  V 4       \        V 4      \        V4      ,           # )zw
Find shards we already have and those we need. Submit those need to
cache_in_queue, those we have to shard_out_queue.
c              3  *   "   T F	  w  rVx  K  	  R # 5ir9   r2   ).0rU   r   s   &  r4   	<genexpr>DRepodataSubset._pipelined_traversal.<locals>.pump.<locals>.<genexpr>  s      @4ZW4s   )_drain_pendingupdater   rl   )haveneedr   	in_flightpendingr;   r   shardlikes_by_urls     r4   pump1RepodataSubset._pipelined_traversal.<locals>.pump  ss    
 ,,W6GHJD  &""4(   @4 @@  ##D)t9s4y((r7   c                   < S^,          o\         P                  RS4       \         P                  R\        R S 4       4      R,          4       \         P                  R\        SP                  4      4       \         P                  RSP                  4       4       \         P                  RSP                  4       4       \         P                  RSP                  4       4       SP                  4       '       dB   \        \        P                  \        P                  ^,           ,          \        ,          4      p M^ p SV 8  d   \        R	4      hR
# )zJ
Log timeout information and raise TimeoutError if max timeouts
exceeded.
zShard timeout %szin_flight: %s...c              3  8   "   T F  p\        V4      x  K  	  R # 5ir9   )r(   )r   rU   s   & r4   r   KRepodataSubset._pipelined_traversal.<locals>.log_timeout.<locals>.<genexpr>  s     *QyG3w<<ys   :N
   Nz	nodes: %dzcache_thread.is_alive(): %sznetwork_thread.is_alive(): %szshard_out_queue.qsize(): %sz'Timeout while fetching repodata shards.N)logdebugr   rl   r[   is_aliveqsizer%   r
   remote_read_timeout_secsremote_max_retriesQUEUE_TIMEOUTTimeoutError)max_timeoutsr   r   r   r;   r   timeoutss    r4   log_timeout8RepodataSubset._pipelined_traversal.<locals>.log_timeout  s     MHII((3II"F*Qy*Q$QRU$V IIk3t{{#34II3\5J5J5LMII5~7N7N7PQII3_5J5J5LM''))"88"559; $	$   !<'"#LMM (r7   z$All shards have finished processing.timeoutry   rz   Nr|   r2   )rO   rR   r~   r[   r$   r   _visit_noder   r   getr   
isinstanceBaseExceptionqueueEmptyremover   r\   r*   r   r)   r]   r   r_   rg   )r;   rN   r   r   r   r   sparent_noder   r   
new_shardsrU   r   rS   r{   r   r   r   r   s   f&ffff         @@@@r4   r   #RepodataSubset._pipelined_traversal  s    04?!UUAX?"u!$	 1gt''CD	) 	)"	N 	N> F		@A	,000G
  %$ H",  ) 2%9O9OP #kk'2-goo>	%%goou=
 999#++x7  	  $$#0!"'151K1K-1-C-C	
' #-[ @P ;; s   G6.G G-,G-c               $    V ^8  d   QhRRRRRR/# )r/   r   r$   mentioned_packagesIterable[str]r0   zIterable[NodeId]r2   )r3   s   "r4   r5   rb     s$     # ##5B#	#r7   c           	   #  r  "   V F  pV P                    F  pW49   g   K  \        W4P                  VP                  V4      4      pWPP                  9  g   KB  \        VP                  ^,           VP                  VP                  VP                  R7      pW`P                  V&   Vx  K  	  K  	  RVn	        R# 5i)zEBroadcast mentioned packages across channels. yield pending NodeId's.)r&   r)   r*   r-   TN)
rO   r1   rR   r-   r[   r$   r&   r)   r*   r,   )r;   r   r   r)   rS   new_node_idnew_nodes   &&&    r4   r   RepodataSubset._visit_node  s      *G!__	'"(	0C0CG0L#K #++5#'%0%9%9A%=$/$7$7$/$7$7&1&;&;	$ 4<K0)) - *  #s   B72B7A!B7c               $    V ^8  d   QhRRRRRR/# )r/   r   zset[NodeId]r   zdict[str, ShardBase]r0   z3tuple[list[tuple[NodeId, ShardDict]], list[NodeId]]r2   )r3   s   "r4   r5   rb     s$     ( ("(7K(	<(r7   c                   . p. pV F  pW%P                   ,          pVP                  VP                  4      '       d.   VP                  WVP	                  VP                  4      34       Kc  V P
                  V,          P                  '       d   \        P                  R4       K  VP                  V4       K  	  VP                  4        WC3# )zr
Check pending for in-memory shards.
Clear pending.

Return a list of shards we have and shards we need to fetch.
z#Skip visited, should not be reached)
r*   shard_loadedr)   r   r   r[   r,   r   r   clear)r;   r   r   shards_needshards_haverU   rS   s   &&&    r4   r   RepodataSubset._drain_pending  s     G)//:I%%goo66""G-D-DW__-U#VW;;w'///IICD""7+  	''r7   )r]   r[   rg   r_   r\   rO   N)r>   r?   r@   rA   __doc__rD   DEFAULT_STRATEGYr   rh   propertyrm   classmethodru   r   r   r   r   r   r   r   r   r   r   rE   r2   r7   r4   rX   rX      s    
 $#"#''//
 6J !	2     5 500d
E3C EC5>485tun#2( (r7   rX   c               0    V ^8  d   QhRRRRRRRRR	R
RR/# )r/   rN   r   channelszdict[str, Channel]	algorithmzLiteral['bfs', 'pipelined']spec_to_package_name_funcr^   ra   r%   r0   zdict[str, ShardBase] | Noner2   )r3   s   "r4   r5   r5   *  sD     " " " " +"  4	"
 " !"r7   c                    \        V4      pVeR   \        . VP                  4       O5VVR7      pVP                  WR7       \        P                  RVP                  4       V# )a"  
Retrieve all necessary information to build a repodata subset.

This function implements the conda.gateways.shards.BuildRepodataSubset protocol,
allowing it to be passed to solvers that support sharded repodata optimization.

Params:
    root_packages: iterable of installed and requested package names
    channels: Channel objects; dict form preferred.
    algorithm: desired traversal algorithm ("bfs" or "pipelined")
    spec_to_package_name_func: callable to convert package specs to names.
                               Defaults to the standard spec_to_package_name.
    repodata_version: repodata format version (1 = classic, 3 = v3).
Return:
    None if there are no shards available, or a mapping of channel URL's to
    ShardBase objects where build_repodata() returns the computed subset.
)r   ra   )rp   z&%d (channel, package) nodes discovered)r   rX   r   r   r   r   rm   )rN   r  r  r	  ra   channel_datasubsets   &&&&&  r4   build_repodata_subsetr  *  sc    0 "(+L%l!!#%!:-

 	;		:F<M<MNr7   _Tc                  >    ] tR tRtRtR tR R ltR tR tR t	R	t
R
# )r   iU  z
Implement insert() interface of .cache.ShardCache() as a queue, instead of
giving network thread direct access to the database.
c                	    Wn         R # r9   r   )r;   r   s   &&r4   rh   QueueCache.__init__[  s    !
r7   c                   V ^8  d   QhRR/# )r/   r   r   r2   )r3   s   "r4   r5   QueueCache.__annotate__^  s        -  r7   c                	>    V P                   P                  V.4       R # r9   )r   r   )r;   r   s   &&r4   insertQueueCache.insert^  s    

wr7   c                	    V # r9   r2   r:   s   &r4   copyQueueCache.copya      r7   c                	    V # r9   r2   r:   s   &r4   	__enter__QueueCache.__enter__d  r  r7   c                	    R # r9   r2   )r;   r   s   &*r4   __exit__QueueCache.__exit__g  s    r7   r  N)r>   r?   r@   rA   r  rh   r  r  r  r   rE   r2   r7   r4   r   r   U  s     
" r7   r   c               (    V ^8  d   QhRRRRRRRR/# )r/   in_queueQueue[Sequence[NodeId] | None]r   z5Queue[Sequence[tuple[NodeId, ShardDict] | Exception]]network_out_queuer   r   r2   )r3   s   "r4   r5   r5   l  s0     /  / ,/ J/  6/  	/ r7   c           	        VP                   ! 4       ;_uu_ 4       p\        V 4       F  p. pV F>  p\        V\        4      '       d   VP                  ! V4       K-  VP                  V4       K@  	  VP                  ! V Uu. uF  qwP                  NK  	  up4      p. p	. p
V FK  pVP                  VP                  4      ;p'       d   V	P                  W{34       K:  V
P                  V4       KM  	  V
'       d   VP                  V
4       V	'       g   K  VP                  V	4       K  	  RRR4       VP                  R4       R# u upi   + '       g   i     L(; i)a  
Fetch batches of shards from cache until in_queue sees None. Enqueue found
shards to shard_out_queue, and not found shards to network_out_queue.

When we see None on in_queue, send None to both out queues and exit.

Args:
    in_queue: NodeId (URLs) to fetch.
    shard_out_queue: fetched shards sent to queue.
    network_out_queue: cache misses forwarded to queue. Same queue is
        network_fetch_thread's in_queue.
    cache: used to retrieve shards.
N)
r  r   r   r   r  r   retrieve_multipler-   r   r   )r#  r   r%  r   batchnode_idsitemrU   cachedfound	not_foundr   s   &&&&        r4   r   r   k  s   ( 
/9EHd$566LL&OOD)  ,,2:;(w""(;F
 57E&(I#"JJw'8'89959LL'!12$$W-	 $ !%%i0u##E*3 : 
8 $% < 
s+   A%E?EA#E7EEEE	c               (    V ^8  d   QhRRRRRRRR/# )	r/   r#  r$  r   1Queue[list[tuple[NodeId, ShardDict] | Exception]]r   zShardCache | QueueCacherO   rY   r2   )r3   s   "r4   r5   r5     s<     IA IA,IAFIA #IA $	IAr7   c           
     Z  a aaaaaa \         P                  ! \        R7      oV Uu/ uF  qDP                  VbK  	  upoR R loR VVV3R llpR VVV3R llpR V 3R	 llp\	        \        4       R
7      ;_uu_ 4       oSP                  ! 4       ;_uu_ 4       o\        S 4       FE  pV F<  p	\        V	\        4      '       d   V! V	4       K#  V! V	4      p
V
P                  V4       K>  	  KG  	  RRR4       RRR4       R# u upi   + '       g   i     L; i  + '       g   i     R# ; i)ar  
Fetch shards from the network that are received on in_queue, until we see
None.

Unhandled exceptions also go to shard_out_queue, and exit this thread.

Args:
    in_queue: NodeId (URLs) to fetch.
    shard_out_queue: fetched shards sent to queue.
    cache: once shards are decoded they are stored in cache.
    shardlikes: list of (network-only) shard index objects.
)max_window_sizec                    V ^8  d   QhRRRR/# )r/   rR   r(   rU   r1   r2   )r3   s   "r4   r5   *network_fetch_thread.<locals>.__annotate__  s     " "c "F "r7   c                    \         P                  \         P                  3pV P                  WR 7      ;_uu_ 4       pVP	                  4        VP
                  pRRR4       WX3#   + '       g   i     L; i)r   N)r
   remote_connect_timeout_secsr   r   raise_for_statuscontent)r   rR   rU   r   responsedatas   &&&   r4   fetch#network_fetch_thread.<locals>.fetch  sb    //,,
 UU3U((H%%'##D ) T!! )(s   A$$A4	c                   V ^8  d   QhRR/# )r/   rU   r1   r2   )r3   s   "r4   r5   r3    s     = = =r7   c                  < SV P                   ,          p\        V\        4      '       g   \        R 4      hVP                  pSV P                   ,          P                  V P                  4      pSP                  SW#V 4      # )z.network_fetch_thread got non-network shardlike)r*   r   r   	TypeErrorsessionr-   r)   submit)rU   rS   r?  rR   executorr:  r   s   &   r4   r@  $network_fetch_thread.<locals>.submit  se    %goo6	)V,,LMM##0::7??KugG<<r7   c                   V ^8  d   QhRR/# r/   futurer   r2   )r3   s   "r4   r5   r3    s     0 0f 0r7   c                6  < V P                  4       w  rp\        P                  R V\        V4      4       \        P
                  ! SP                  V\        R7      4      pSP                  ! \        WP                  V4      4       SP                  W$3.4       R# )zFetch thread got %s (%s bytes))max_output_sizeN)resultr   r   rl   msgpackloads
decompressr   r  r   r)   r   )rE  rR   rU   r9  r   r   dctxr   s   &    r4   handle_result+network_fetch_thread.<locals>.handle_result  sw    #]]_d		2CTC #==OOD2EOF

 	&sOOTBCg-./r7   c                   V ^8  d   QhRR/# rD  r2   )r3   s   "r4   r5   r3    s      6 r7   c                ,   < SP                  V .4       R # r9   )r   )rE  r#  s   &r4   result_to_in_queue0network_fetch_thread.<locals>.result_to_in_queue  s     	fXr7   )max_workersN)	zstandardZstdDecompressorr   rR   r   r   r  r   r   r   add_done_callback)r#  r   r   rO   r   r@  rM  rQ  node_ids_and_resultsnode_id_or_resultrE  rL  rA  r:  r   s   fff&       @@@@r4   r   r     s    & %%6IJD+56:a:6"= =0 0  	':'<==

$>x$H %9!/88!"34#$56F,,-?@ &: %I 	 	>=[ 7\ 	 	>==s*   D DAD	/DDDD*	c               (    V ^8  d   QhRRRRRRRR/# )	r/   r#  r$  r   r/  r   r   rO   rY   r2   )r3   s   "r4   r5   r5     s0     4 4,4F4 4 $	4r7   c                n    \        V 4       F%  pV F  pR/ R/ /pVP                  WV3.4       K  	  K'  	  R# )a  
For offline mode, where network requests are not allowed.
Pretend that every network request is an empty shard.
Don't save those to the cache.

Depending on how many shards are in sqlite3 and which packages were requested, the user may or may not get enough repodata for a solution.

Args:
    in_queue: NodeId (URLs) to fetch.
    shard_out_queue: fetched shards sent to queue.
    cache: once shards are decoded they are stored in cache.
    shardlikes: list of (network-only) shard index objects.
packageszpackages.condaN)r   r   )r#  r   r   rO   r)  rU   r   s   &&&&   r4   r   r     s@    * /x8G *B0@"EE'!1 23   9r7   )Gr  
__future__r   loggingr   rB   r   collectionsr   concurrent.futuresr   r   dataclassesr   pathlibr   r   typingr	   rI  rT  conda.gateways.repodatar   conda.base.contextr
   r'   r   r   miscr   r   r   r   r   shardsr   r   r   r   r   r   	getLoggerr>   r   collections.abcr   r   r   r   Queuer   r   conda.models.channelr   r   r    r!   r    REACHABLE_PIPELINED_MAX_TIMEOUTSr   r$   r1   rV   rX   r  r  r  r   r   r   r   r2   r7   r4   <module>rl     sa  -^ #   
   9 !        &  $   !FF*',!!!   !  B B B $t,B B -B$ U( U(v .<-L-L6J"N 	B , /  / f IA IA` 4 4r7   