controls/DebugVariablePanel/RingBuffer.py
branchsvghmi
changeset 3257 095c73591b7e
child 2742 5f7445b582d4
equal deleted inserted replaced
3256:8d1cc99a8f54 3257:095c73591b7e
       
     1 #!/usr/bin/env python
       
     2 # -*- coding: utf-8 -*-
       
     3 
       
     4 # This file is part of Beremiz
       
     5 # Copyright (C) 2021: Edouard TISSERANT
       
     6 #
       
     7 # See COPYING file for copyrights details.
       
     8 
       
     9 # Based on Eelco Hoogendoorn stackoverflow answer about RingBuffer with numpy
       
    10 
       
    11 import numpy as np
       
    12 
       
    13 
       
    14 class RingBuffer(object):
       
    15     def __init__(self, width=None, size=65536, padding=None):
       
    16         self.size = size
       
    17         self.padding = size if padding is None else padding
       
    18         shape = (self.size+self.padding,)
       
    19         if width :
       
    20             shape += (width,)
       
    21         self.buffer = np.zeros(shape)
       
    22         self.counter = 0
       
    23         self.full = False
       
    24 
       
    25     def append(self, data):
       
    26         """this is an O(n) operation"""
       
    27         data = data[-self.padding:]
       
    28         n = len(data)
       
    29         if self.remaining < n: self.compact()
       
    30         self.buffer[self.counter+self.size:][:n] = data
       
    31         self.counter += n
       
    32 
       
    33     @property
       
    34     def count(self):
       
    35         return self.counter if not self.full else self.size
       
    36 
       
    37     @property
       
    38     def remaining(self):
       
    39         return self.padding-self.counter
       
    40 
       
    41     @property
       
    42     def view(self):
       
    43         """this is always an O(1) operation"""
       
    44         return self.buffer[self.counter:][:self.size]
       
    45 
       
    46     def compact(self):
       
    47         """
       
    48         note: only when this function is called, is an O(size) performance hit incurred,
       
    49         and this cost is amortized over the whole padding space
       
    50         """
       
    51         print 'compacting'
       
    52         self.buffer[:self.size] = self.view
       
    53         self.counter = 0
       
    54         self.full = True
       
    55