controls/DebugVariablePanel/RingBuffer.py
changeset 2742 5f7445b582d4
parent 2741 3cc5663af196
child 3750 f62625418bff
equal deleted inserted replaced
2741:3cc5663af196 2742:5f7445b582d4
    10 
    10 
    11 import numpy as np
    11 import numpy as np
    12 
    12 
    13 
    13 
    14 class RingBuffer(object):
    14 class RingBuffer(object):
    15     def __init__(self, width=None, size=65536, padding=None):
    15     def __init__(self, width=None, size=131072, padding=None):
    16         self.size = size
    16         self.size = size
    17         self.padding = size if padding is None else padding
    17         self.padding = size if padding is None else padding
    18         shape = (self.size+self.padding,)
    18         shape = (self.size+self.padding,)
    19         if width :
    19         if width :
    20             shape += (width,)
    20             shape += (width,)
    21         self.buffer = np.zeros(shape)
    21         self.buffer = np.zeros(shape)
    22         self.counter = 0
    22         self.cursor = 0
    23         self.full = False
       
    24 
    23 
    25     def append(self, data):
    24     def append(self, data):
    26         """this is an O(n) operation"""
    25         """this is an O(n) operation"""
    27         data = data[-self.padding:]
    26         data = data[-self.size:]
    28         n = len(data)
    27         n = len(data)
    29         if self.remaining < n: self.compact()
    28         if self.size + self.padding - self.cursor < n:
    30         self.buffer[self.counter+self.size:][:n] = data
    29             self.compact()
    31         self.counter += n
    30         self.buffer[self.cursor:][:n] = data
       
    31         self.cursor += n
    32 
    32 
    33     @property
    33     @property
    34     def count(self):
    34     def count(self):
    35         return self.counter if not self.full else self.size
    35         return min(self.size, self.cursor)
    36 
       
    37     @property
       
    38     def remaining(self):
       
    39         return self.padding-self.counter
       
    40 
    36 
    41     @property
    37     @property
    42     def view(self):
    38     def view(self):
    43         """this is always an O(1) operation"""
    39         """this is always an O(1) operation"""
    44         return self.buffer[self.counter:][:self.size]
    40         return self.buffer[max(0, self.cursor - self.size):][:self.count]
    45 
    41 
    46     def compact(self):
    42     def compact(self):
    47         """
    43         """
    48         note: only when this function is called, is an O(size) performance hit incurred,
    44         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
    45         and this cost is amortized over the whole padding space
    50         """
    46         """
    51         print 'compacting'
    47         print 'compacting'
    52         self.buffer[:self.size] = self.view
    48         self.buffer[:self.count] = self.view
    53         self.counter = 0
    49         self.cursor -= self.size
    54         self.full = True
       
    55 
    50