
    c                         d Z ddlmZmZ ddlmZ ddlZ	 ddlmZ  ed      Z		 dd	lmZ g d
Z G d de      Z G d de      Z G d de      ZeZy# e
$ r
  e       Z	Y =w xY w# e
$ r eZY Cw xY w)a  Python comes with a many great data structures, from :class:`dict`
to :class:`collections.deque`, and no shortage of serviceable
algorithm implementations, from :func:`sorted` to :mod:`bisect`. But
priority queues are curiously relegated to an example documented in
:mod:`heapq`. Even there, the approach presented is not full-featured
and object-oriented. There is a built-in priority queue,
:class:`Queue.PriorityQueue`, but in addition to its austere API, it
carries the double-edged sword of threadsafety, making it fine for
multi-threaded, multi-consumer applications, but high-overhead for
cooperative/single-threaded use cases.

The ``queueutils`` module currently provides two Queue
implementations: :class:`HeapPriorityQueue`, based on a heap, and
:class:`SortedPriorityQueue`, based on a sorted list. Both use a
unified API based on :class:`BasePriorityQueue` to facilitate testing
the slightly different performance characteristics on various
application use cases.

>>> pq = PriorityQueue()
>>> pq.add('low priority task', 0)
>>> pq.add('high priority task', 2)
>>> pq.add('medium priority task 1', 1)
>>> pq.add('medium priority task 2', 1)
>>> len(pq)
4
>>> pq.pop()
'high priority task'
>>> pq.peek()
'medium priority task 1'
>>> len(pq)
3

    )heappushheappopinsortN   )make_sentinel_REMOVED)var_name)BList)PriorityQueueBasePriorityQueueHeapPriorityQueueSortedPriorityQueuec                   |    e Zd ZdZ ed       ZeZd Zed        Z	ed        Z
ddZd Zdd	Zefd
ZefdZd Zy)r   a  The abstract base class for the other PriorityQueues in this
    module. Override the ``_backend_type`` class attribute, as well as
    the :meth:`_push_entry` and :meth:`_pop_entry` staticmethods for
    custom subclass behavior. (Don't forget to use
    :func:`staticmethod`).

    Args:
        priority_key (callable): A function that takes *priority* as
            passed in by :meth:`add` and returns a real number
            representing the effective priority.

    c                 "    t        | xs d       S Nr   )float)ps    2lib/python3.12/site-packages/boltons/queueutils.py<lambda>zBasePriorityQueue.<lambda>k   s    E!&qM>     c                     | j                         | _        i | _        t        j                         | _        |j                  d| j                        | _        |rt        d|j                         z        y )Npriority_keyz unexpected keyword arguments: %r)_backend_type_pq
_entry_map	itertoolscount_counterpop_default_priority_key_get_priority	TypeErrorkeys)selfkws     r   __init__zBasePriorityQueue.__init__n   s_    %%'!)VVND4N4NO>JKK r   c                      y N backendentrys     r   _push_entryzBasePriorityQueue._push_entryv       r   c                      y r)   r*   r,   s    r   
_pop_entryzBasePriorityQueue._pop_entryz   r/   r   Nc                     | j                  |      }|| j                  v r| j                  |       t        | j                        }|||g}|| j                  |<   | j                  | j                  |       y)aP  
        Add a task to the queue, or change the *task*'s priority if *task*
        is already in the queue. *task* can be any hashable object,
        and *priority* defaults to ``0``. Higher values representing
        higher priority, but this behavior can be controlled by
        setting *priority_key* in the constructor.
        N)r"   r   removenextr   r.   r   )r%   taskpriorityr   r-   s        r   addzBasePriorityQueue.add~   sh     %%h/4??"KKT]]#5$' %5)r   c                 L    | j                   j                  |      }t        |d<   y)zgRemove a task from the priority queue. Raises :exc:`KeyError` if
        the *task* is absent.
        N)r   r    r	   )r%   r6   r-   s      r   r4   zBasePriorityQueue.remove   s!     ##D)b	r   c                     | j                   r8| j                   d   \  }}}|t        u r| j                  | j                          Cy|rt        d      y)zBRemove entries marked as removed by previous :meth:`remove` calls.r   Nzempty priority queue)r   r	   r2   
IndexError)r%   	raise_excr7   r   r6   s        r   _cullzBasePriorityQueue._cull   sO    hh$(HHQK!HeTx)344 r   c                     	 | j                          | j                  d   \  }}}|S # t        $ r |t        ur|cY S t        d      w xY w)zRead the next value in the queue without removing it. Returns
        *default* on an empty queue, or raises :exc:`KeyError` if
        *default* is not set.
        r   zpeek on empty queue)r>   r   r<   r	   r%   default_r6   s       r   peekzBasePriorityQueue.peek   sT    
	4JJL!JAq$
 	  	4h&233	4s   #' AAc                     	 | j                          | j                  | j                        \  }}}| j                  |= |S # t        $ r |t
        ur|cY S t	        d      w xY w)zRemove and return the next value in the queue. Returns *default* on
        an empty queue, or raises :exc:`KeyError` if *default* is not
        set.
        zpop on empty queue)r>   r2   r   r   r<   r	   r@   s       r   r    zBasePriorityQueue.pop   se    
	3JJL2JAq$%
 	  	3h&122	3s   <A   A!A!c                 ,    t        | j                        S )z(Return the number of tasks in the queue.)lenr   )r%   s    r   __len__zBasePriorityQueue.__len__   s    4??##r   r)   )T)__name__
__module____qualname____doc__staticmethodr!   listr   r'   r.   r2   r8   r4   r>   r	   rC   r    rG   r*   r   r   r   r   ]   sp     ))ABML    * 	5 $  # $r   r   c                   0    e Zd ZdZed        Zed        Zy)r   zA priority queue inherited from :class:`BasePriorityQueue`,
    backed by a list and based on the :func:`heapq.heappop` and
    :func:`heapq.heappush` functions in the built-in :mod:`heapq`
    module.
    c                     t        |       S r)   )r   r1   s    r   r2   zHeapPriorityQueue._pop_entry   s    wr   c                     t        | |       y r)   )r   r+   s     r   r.   zHeapPriorityQueue._push_entry   s    % r   N)rH   rI   rJ   rK   rL   r2   r.   r*   r   r   r   r      s/    
     ! !r   r   c                   4    e Zd ZdZeZed        Zed        Zy)r   zA priority queue inherited from :class:`BasePriorityQueue`, based
    on the :func:`bisect.insort` approach for in-order insertion into
    a sorted list.
    c                 $    | j                  d      S r   )r    r1   s    r   r2   zSortedPriorityQueue._pop_entry   s    {{1~r   c                     t        | |       y r)   r   r+   s     r   r.   zSortedPriorityQueue._push_entry   s    wr   N)	rH   rI   rJ   rK   r   r   rL   r2   r.   r*   r   r   r   r      s4     M   r   r   )rK   heapqr   r   bisectr   r   	typeutilsr   r	   ImportErrorobject	listutilsr   rM   __all__r   r   r   r   r*   r   r   <module>r[      s   B F $  (j1H 7b$ b$J!) !+   $m  xH  Es"   A A& A#"A#&A0/A0