Source code for plastid.util.unique_fifo

#!/usr/bin/env python


[docs]class UniqueFIFO(object): """FIFO of unique objects. In other words, if an element already present in the FIFO is appended to the FIFO, it is moved to the right end and no element is removed from the FIFO. Elements are only removed when a element not present in the FIFO is appended to the right end, and when the number of elements in the FIFO exceeds `self.max_size`. Parameters ---------- idx : int Index of item to fetch Returns ------- object Nth item in the |UniqueFIFO| Attributes ---------- max_size : int Maximum size of |UniqueFIFO| """ def __init__(self, size): assert size > 0 self.max_size = size self._elements = [] def __getitem__(self, idx): """Fetch Nth item in the |UniqueFIFO| Parameters ---------- idx : int Index of item to fetch Returns ------- object Nth item in the |UniqueFIFO| """ return self._elements[idx] def __contains__(self, el): """Determine whether an element is in the |UniqueFIFO| Parameters ---------- el : hashable object Query object Returns ------- bool `True` if `el` is in the |UniqueFIFO|, `False` otherwise """ return el in self._elements def __iter__(self): """Iterate over elements in the |UniqueFIFO|""" return iter(self._elements) def __len__(self): """Return number of objects presently in the |UniqueFIFO| Returns ------- int Number of elements presently in the |UniqueFIFO|, must be less than or equal to `self.max_size` """ return len(self._elements)
[docs] def append(self, el): """Append an item to the |UniqueFIFO|. If the item is already present in the |UniqueFIFO|, it is moved to the right end of the FIFO, and the length of the |UniqueFIFO| is unchanged. Otherwise, the element is appended to the right end. If the length of the |UniqueFIFO| then exceeds `self.max_size`, the fist element is popped. Parameters ---------- el : hashable Any hashable object """ if el in self: # move to front if present n = self._elements.index(el) self._elements = self._elements[:n] + self._elements[n + 1:] + [el] else: # otherwise append, removing first element # if we are too long if len(self._elements) >= self.max_size: self._elements = self._elements[1:] self._elements.append(el) else: self._elements.append(el)
def __str__(self): return str(self._elements) def __repr__(self): return "<UniqueFifo %s>" % repr(self._elements)