<commit_before>from .monitor import Monitor
from ...exceptions import AlreadyAllocated


class IDAllocator(Monitor):
    """
    Reusable ID allocator

    You can use it to requisition ints from a pool, and then free their ints, permitting
    them to be reused.

    Thread-safe.
    """
    def __init__(self):
        super().__init__()
        self.ints_allocated = set()
        self.free_ints = set()
        self.bound = 0

    def _extend_the_bound_to(self, x: int):
        for i in range(self.bound, x):
            self.free_ints.add(i)
        self.bound = x

    @Monitor.synchronized
    def mark_as_free(self, x: int):
        """
        Mark x as free

        :param x: int to free
        :raises ValueError: x was not allocated
        """
        if x not in self.ints_allocated:
            raise ValueError('%s was not allocated' % (x, ))
        self.ints_allocated.remove(x)
        self.free_ints.add(x)

    @Monitor.synchronized
    def allocate_int(self) -> int:
        """
        Return an allocated int

        :return: an allocated int
        """
        if not self.free_ints:
            self._extend_the_bound_to(self.bound+10)
        x = self.free_ints.pop()
        self.ints_allocated.add(x)
        return x

    @Monitor.synchronized
    def mark_as_allocated(self, x: int):
        """
        Mark given x as allocated

        :param x: x to mark as allocated
        :raises AlreadyAllocated: x was already allocated
        """<commit_msg>added `IDAllocator`<commit_after>from .monitor import Monitor
from ...exceptions import AlreadyAllocated


class IDAllocator(Monitor):
    """
    Reusable ID allocator

    You can use it to requisition ints from a pool, and then free their ints, permitting
    them to be reused.

    Thread-safe.
    """
    def __init__(self):
        super().__init__()
        self.ints_allocated = set()
        self.free_ints = set()
        self.bound = 0

    def _extend_the_bound_to(self, x: int):
        for i in range(self.bound, x):
            self.free_ints.add(i)
        self.bound = x

    @Monitor.synchronized
    def mark_as_free(self, x: int):
        """
        Mark x as free

        :param x: int to free
        :raises ValueError: x was not allocated
        """
        if x not in self.ints_allocated:
            raise ValueError('%s was not allocated' % (x, ))
        self.ints_allocated.remove(x)
        self.free_ints.add(x)

    @Monitor.synchronized
    def allocate_int(self) -> int:
        """
        Return a previously unallocated int, and mark it as allocated

        :return: an allocated int
        """
        if not self.free_ints:
            self._extend_the_bound_to(self.bound+10)
        x = self.free_ints.pop()
        self.ints_allocated.add(x)
        return x

    @Monitor.synchronized
    def mark_as_allocated(self, x: int):
        """
        Mark given x as allocated

        :param x: x to mark as allocated
        :raises AlreadyAllocated: x was already allocated
        """
{'fraction_non_alphanumeric': 0.09292328042328042, 'fraction_numerical': 0.001984126984126984, 'mean_word_length': 2.0189620758483033, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2481427', 'n_tokens_mistral': 951, 'n_tokens_neox': 902, 'n_words': 271}