Исходный код EJIO.utils.struct.deque

## /utils/struct/deque.py

from threading import Lock
from typing import Any, Generator

__all__ = [
    'Deque',
]


class Node[T]:
    """
    Узел двусвязного списка для хранения значения и указателей на следующий и предыдущий элементы.
    """
    __slots__ = ('value', 'next', 'prev')

    def __init__(
            self,
            value: T,
            next: 'Node[T] | None' = None,
            prev: 'Node[T] | None' = None
    ) -> None:
        """
        Создает узел двусвязного списка.

        :param value: Значение записываемое в узел.
        :param next: Ссылка на следующий узел.
        :param prev: Ссылка на предыдущий узел.
        """
        self.value: T = value
        self.next: 'Node[T] | None' = next
        self.prev: 'Node[T] | None' = prev


[документация] class Deque[T]: """ Потокобезопасная двусторонняя очередь на двусвязном списке. Класс поддерживает основные операции с обоих концов структуры. """ __slots__ = ('_head', '_tail', '_size', '_lock') def __init__(self) -> None: """Создает объект двусторонней очереди.""" self._head: Node[T] | None = None self._tail: Node[T] | None = None self._lock: Lock = Lock() self._size: int = 0
[документация] def push_back(self, item: T) -> None: """ Добавляет элемент в конец (хвост) очереди. :param item: Объект для добавления. """ with self._lock: new_node = Node(item, prev=self._tail) if self._tail is None: self._head = new_node self._tail = new_node else: self._tail.next = new_node self._tail = new_node self._size += 1
[документация] def push_front(self, item: T) -> None: """ Добавляет элемент в начало (голову) очереди. :param item: Объект для добавления. """ with self._lock: new_node = Node(item, next=self._head) if self._head is None: self._head = new_node self._tail = new_node else: self._head.prev = new_node self._head = new_node self._size += 1
[документация] def pop_front(self) -> T: """ Удаляет и возвращает элемент из начала (головы) очереди. :return: Объект из начала очереди. :raises IndexError: Если очередь пуста. """ with self._lock: if self._head is None: raise IndexError("Pop from empty deque") node = self._head self._head = node.next if self._head is None: self._tail = None else: self._head.prev = None self._size -= 1 return node.value
[документация] def pop_back(self) -> T: """ Удаляет и возвращает элемент из конца (хвоста) очереди. :return: Объект из конца очереди. :raises IndexError: Если очередь пуста. """ with self._lock: if self._tail is None: raise IndexError("Pop from empty deque") node = self._tail self._tail = node.prev if self._tail is None: self._head = None else: self._tail.next = None self._size -= 1 return node.value
[документация] def peek_front(self) -> T: """ Возвращает первый элемент (в голове) без удаления. :return: Объект из начала очереди. :raises IndexError: Если очередь пуста. """ with self._lock: if self._head is None: raise IndexError("Peek from empty deque") return self._head.value
[документация] def peek_back(self) -> T: """ Возвращает последний элемент (в хвосте) без удаления. :return: Объект из конца очереди. :raises IndexError: Если очередь пуста. """ with self._lock: if self._tail is None: raise IndexError("Peek from empty deque") return self._tail.value
@property def empty(self) -> bool: """ Проверяет пуста ли очередь. :return: True если очередь пуста, иначе False. """ with self._lock: return self._head is None @property def size(self) -> int: """ Возвращает текущий размер очереди. :return: Размер очереди. """ with self._lock: return self._size def __reversed__(self) -> Generator[T, Any, None]: """ Возвращает итератор, извлекающий элементы из конца очереди до тех пор, пока она не опустеет. Потокобезопасно на уровне отдельных операций. :yields: Элементы очереди в порядке с конца до начала. """ while True: try: yield self.pop_back() except IndexError: return def __iter__(self) -> Generator[T, Any, None]: """ Возвращает итератор, извлекающий элементы из начала очереди до тех пор, пока она не опустеет. Потокобезопасно на уровне отдельных операций. :yields: Элементы очереди в порядке с начала до конца. """ while True: try: yield self.pop_front() except IndexError: return def __str__(self) -> str: """ Возвращает строковое представление всей очереди в виде списка элементов от начала к концу. :return: Представление очереди в виде строки. """ with self._lock: elements = [] current = self._head while current: elements.append(repr(current.value)) current = current.next return f"[{', '.join(elements)}]" def __repr__(self) -> str: """ Возвращает строковое представление всего дека в виде списка элементов от начала к концу. :return: Представление очереди в виде строки. """ return f"Deque({str(self)})" def __del__(self) -> None: """Очищает память при удалении объекта, изолируя узлы двусвязного списка.""" with self._lock: current = self._head while current: next_node = current.next current.next = None current.prev = None current = next_node self._head = None self._tail = None self._size = 0