equal
deleted
inserted
replaced
|
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 |