Exemple #1
0
    def test_dllist_for(self):
        ll = DLList("4")
        ll.push("2")

        ll_iter = iter(ll)

        for i in ll_iter:
            assert i == "4" or i == "2"

        with pytest.raises(StopIteration):
            next(ll_iter)
Exemple #2
0
    def test_dllist_insert_after(self):
        ll = DLList(14)
        ll.push(15)
        ll.push(17)

        ll.insert(16, after_node=ll.tail.prev)

        assert len(ll) == 4

        _assert_order_and_values(ll, [14, 15, 16, 17])
Exemple #3
0
    def test_dllist_insert_before(self):
        ll = DLList(14)
        ll.push(16)
        ll.push(17)

        ll.insert(15, before_node=ll.head.next)

        assert len(ll) == 4

        _assert_order_and_values(ll, [14, 15, 16, 17])
Exemple #4
0
    def test_dllist_insert_exception(self):
        ll = DLList(13)
        ll.push(15)

        with pytest.raises(ValueError):
            ll.insert(14)
Exemple #5
0
    def test_dllist_complicated_case(self):
        ll3 = DLList(13)
        ll3.push(14)
        ll3.shift(12)
        ll3.push(15)
        assert ll3.unshift() == 12
        assert ll3.pop() == 15
        assert ll3.unshift() == 13
        assert ll3.pop() == 14

        with pytest.raises(Exception):
            ll3.pop()
Exemple #6
0
    def test_dllist_len(self):
        ll = DLList((1, 2))
        assert len(ll) == 1
        ll.shift((2, 3))
        assert len(ll) == 2
        ll.push((3, 4))
        assert len(ll) == 3

        ll.pop()
        assert len(ll) == 2
        ll.unshift()
        assert len(ll) == 1
        ll.pop()
        assert len(ll) == 0
Exemple #7
0
 def test_dllist_unshift(self):
     ll = DLList("k")
     assert ll.unshift() == "k"
     with pytest.raises(Exception):
         ll.unshift()
Exemple #8
0
 def test_dllist_pop(self):
     ll = DLList(12)
     assert ll.pop() == 12
     with pytest.raises(Exception):
         ll.pop()
Exemple #9
0
 def test_dllist_init(self):
     with pytest.raises(TypeError):
         DLList()
Exemple #10
0
    def test_dllist_iter(self):
        ll = DLList(4)
        dlli = iter(ll)

        assert dlli.__next__() is ll.unshift()
Exemple #11
0
    def __init__(self, buffer_size: int = 40, check_time: int = 50) -> None:
        self.buffer_size = buffer_size
        self.check_time = check_time
        self.stream_sequence = 0

        self.buffers = DLList(PercentileBuffer(buffer_size, buffer_size * 2))
Exemple #12
0
class StreamMetrics:
    """
    Stream metrics has 100 buckets for storing values (percentiles).
    Inner stream_sequence for delete oldest values and buckets.
    """
    max_number_of_buffer = 100

    def __init__(self, buffer_size: int = 40, check_time: int = 50) -> None:
        self.buffer_size = buffer_size
        self.check_time = check_time
        self.stream_sequence = 0

        self.buffers = DLList(PercentileBuffer(buffer_size, buffer_size * 2))

    def append(self, val: StreamValue) -> None:
        if self.stream_sequence > 0:
            if self.buffers.head.val.metrics.min > val.value:
                self.buffers.head.val.insert(val, self.stream_sequence)
            elif self.buffers.tail.val.metrics.max < val.value:
                self.buffers.tail.val.insert(val, self.stream_sequence)

            prev_buffer = None
            for buffer in self.buffers:
                if val.value in buffer.metrics:
                    if len(self.buffers) != self.max_number_of_buffer:
                        if not buffer.is_full():
                            buffer.append(val, self.stream_sequence)
                        else:
                            self.split_buffer(buffer)
                elif (prev_buffer and prev_buffer.metrics.max < val.value <
                      buffer.metrics.min):
                    if len(prev_buffer) <= len(buffer):
                        prev_buffer.insert(val, self.stream_sequence)
                    else:
                        buffer.insert(val, self.stream_sequence)
                prev_buffer = buffer

        else:
            self.buffers.head.val.append(val, self.stream_sequence)

        self.stream_sequence += 1

    def split_buffer(self, buffer_for_split: PercentileBuffer) -> None:
        node = [
            b for b in self.buffers.iter_over_nodes()
            if b.val == buffer_for_split
        ][0]

        new_buffer = buffer_for_split.split_buffer()
        self.buffers.insert(new_buffer, before_node=node)

    def rebuild(self) -> None:
        buffer_to_number = {buffer: i for i, buffer in enumerate(self.buffers)}
        seq_to_buffer = {
            buffer.max_sequence(): buffer
            for buffer in self.buffers
        }

        split_candidate_buffer = seq_to_buffer[max(seq_to_buffer.keys())]
        merge_candidate_buffer = seq_to_buffer[min(seq_to_buffer.keys())]

        if buffer_to_number[split_candidate_buffer] - buffer_to_number[
                merge_candidate_buffer] < 2:
            pass

    def current_metrics(self) -> Dict[int, Union[int, float]]:
        if self.stream_sequence < self.max_number_of_buffer * self.buffer_size:
            raise Exception("Not enough data")

        percentiles = {}
        for i, buffer in enumerate(self.buffers):
            if i == 24:
                percentiles[25] = buffer.metrics.max
            elif i == 49:
                percentiles[50] = buffer.metrics.max
            elif i == 74:
                percentiles[75] = buffer.metrics.max

        return percentiles