rtmlib
reader.h
Go to the documentation of this file.
1 /*
2  * rtmlib is a Real-Time Monitoring Library.
3  *
4  * Copyright (C) 2018-2020 AndrĂ© Pedro
5  *
6  * This file is part of rtmlib.
7  *
8  * This program is free software: you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation, either version 3 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program. If not, see <http://www.gnu.org/licenses/>.
20  */
21 
22 #ifndef _RTEML_READER_H_
23 #define _RTEML_READER_H_
24 
25 #include <array>
26 #include <time.h>
27 #include <tuple>
28 #include <utility>
29 
30 #include "circularbuffer.h"
31 #include "event.h"
32 
39 template <typename B> class RTML_reader {
40 protected:
44  const B &buffer;
45 
49  size_t top;
50 
54  size_t bottom;
55 
60 
61 public:
62  typedef B buffer_t;
63 
65 
73  RTML_reader(const B &);
74 
81  error_t pull(typename B::event_t &);
82 
89  error_t pop(typename B::event_t &);
90 
96  bool synchronize();
97 
104  bool gap() const;
105 
111  size_t length() const;
112 
116  void debug() const;
117 };
118 
119 template <typename B>
121  : buffer(_buffer), top(0), bottom(0), timestamp(0) {}
122 
123 template <typename B>
125 RTML_reader<B>::pull(typename B::event_t &event) {
126 
127  typename B::event_t event_next;
128 
129  if (length() > 0) {
130  // read in an atomic way
131  if (buffer.read(event, bottom) != buffer.OK)
132  return BUFFER_READ;
133 
134  // update local bottom
135  bottom = (size_t)(bottom + 1) % (buffer.size + 0);
136  if (buffer.read(event_next, bottom) == buffer.OK)
137  timestamp = event_next.getTime();
138  }
139 
140  DEBUGV3("pull-> %d (%d,%d)\n", length(), bottom, top);
141 
142  if (gap())
143  return OVERFLOW;
144  else
145  return (length() > 0) ? AVAILABLE : UNAVAILABLE;
146 }
147 
148 template <typename B>
150 RTML_reader<B>::pop(typename B::event_t &event) {
151 
152  if (length() > 0) {
153  if (top - 1 > 0)
154  buffer.read(event, --top);
155  else if (top - 1 <= 0) {
156  top = buffer.size;
157  buffer.read(event, top);
158  }
159  }
160 
161  DEBUGV3("pop-> %d (%d,%d)\n", length(), bottom, top);
162 
163  if (gap())
164  return OVERFLOW;
165  else
166  return (length() > 0) ? AVAILABLE : UNAVAILABLE;
167 }
168 
169 template <typename B> bool RTML_reader<B>::synchronize() {
170  /*
171  * The synchronization depends on the buffer state. Any event that is
172  * overwritten without being read is a gap for the reader.
173  */
174 
175  size_t b, t;
176  timespanw ts;
177  buffer.state(b, t, ts);
178 
179  if (timestamp > ts) {
180  // no gaps, but the reader cannot be further ahead
181  top = t; // set new top
182  return false;
183  } else {
184  // update reader state
185  top = t;
186  bottom = b;
187  timestamp = ts;
188 
189  // there is a gap
190  return true;
191  }
192 }
193 
194 template <typename B> bool RTML_reader<B>::gap() const {
195  typename B::event_t event;
196 
197  // detect a gap
198  buffer.read(event, bottom);
199  if (timestamp < event.getTime())
200  return true;
201 
202  return false;
203 }
204 
205 template <typename B> size_t RTML_reader<B>::length() const {
206  return (top >= bottom) ? top - bottom : (buffer.size + 1) - (bottom - top);
207 }
208 
209 template <typename B> void RTML_reader<B>::debug() const {
210  DEBUGV("bottom:%d top:%d timestamp:%lu\n", bottom, top, timestamp);
211 }
212 
213 #endif //_RTEML_READER_H_
size_t length() const
Definition: reader.h:205
Definition: reader.h:39
bool gap() const
Definition: reader.h:194
timeabs timespanw
Definition: time_compat.h:94
Definition: reader.h:64
error_t pop(typename B::event_t &)
Definition: reader.h:150
B buffer_t
Definition: reader.h:62
#define DEBUGV3(...)
Definition: debug_compat.h:84
void debug() const
Definition: reader.h:209
#define DEBUGV(...)
Definition: debug_compat.h:83
timespanw timestamp
Definition: reader.h:59
Definition: reader.h:64
bool synchronize()
Definition: reader.h:169
error_t
Definition: reader.h:64
error_t pull(typename B::event_t &)
Definition: reader.h:125
Definition: reader.h:64
size_t bottom
Definition: reader.h:54
size_t top
Definition: reader.h:49
RTML_reader(const B &)
Definition: reader.h:120
const B & buffer
Definition: reader.h:44
Definition: reader.h:64