comparison base/EventSeries.h @ 1625:7dbb2a7b592e single-point

That last change didn't seem worthwhile
author Chris Cannam
date Mon, 11 Mar 2019 11:25:17 +0000
parents dcd510bd89db
children 895186c43fce
comparison
equal deleted inserted replaced
1624:dcd510bd89db 1625:7dbb2a7b592e
16 #define SV_EVENT_SERIES_H 16 #define SV_EVENT_SERIES_H
17 17
18 #include "Event.h" 18 #include "Event.h"
19 19
20 #include <set> 20 #include <set>
21
22 #include <QHash>
23 #include <QMap>
24 21
25 //#define DEBUG_EVENT_SERIES 1 22 //#define DEBUG_EVENT_SERIES 1
26 23
27 /** 24 /**
28 * Container storing a series of events, with or without durations, 25 * Container storing a series of events, with or without durations,
79 SVCERR << "ERROR: EventSeries::add: " 76 SVCERR << "ERROR: EventSeries::add: "
80 << "reached end of seam map" 77 << "reached end of seam map"
81 << endl; 78 << endl;
82 break; 79 break;
83 } 80 }
84 i.value().insert(p); 81 i->second.insert(p);
85 } 82 }
86 } 83 }
87 84
88 #ifdef DEBUG_EVENT_SERIES 85 #ifdef DEBUG_EVENT_SERIES
89 std::cerr << "after add:" << std::endl; 86 std::cerr << "after add:" << std::endl;
101 98
102 auto pitr = m_events.find(p); 99 auto pitr = m_events.find(p);
103 if (pitr == m_events.end()) { 100 if (pitr == m_events.end()) {
104 return; // we don't know this event 101 return; // we don't know this event
105 } else { 102 } else {
106 if (--(pitr.value()) == 0) { 103 if (--(pitr->second) == 0) {
107 isUnique = true; 104 isUnique = true;
108 m_events.erase(pitr); 105 m_events.erase(pitr);
109 } 106 }
110 --m_count; 107 --m_count;
111 } 108 }
133 // This can happen only if we have a negative 130 // This can happen only if we have a negative
134 // duration, which Event forbids 131 // duration, which Event forbids
135 throw std::logic_error("unexpectedly reached end of map"); 132 throw std::logic_error("unexpectedly reached end of map");
136 } 133 }
137 134
138 i.value().remove(p); 135 i->second.erase(p);
139 } 136 }
140 137
141 // Tidy up by removing any entries that are now identical 138 // Tidy up by removing any entries that are now identical
142 // to their predecessors 139 // to their predecessors
143 140
148 pitr = i0; 145 pitr = i0;
149 --pitr; 146 --pitr;
150 } 147 }
151 148
152 for (auto i = i0; i != m_seams.end(); ++i) { 149 for (auto i = i0; i != m_seams.end(); ++i) {
153 if (pitr != m_seams.end() && i.value() == pitr.value()) { 150 if (pitr != m_seams.end() && i->second == pitr->second) {
154 redundant.push_back(i.key()); 151 redundant.push_back(i->first);
155 } 152 }
156 pitr = i; 153 pitr = i;
157 if (i == i1) { 154 if (i == i1) {
158 break; 155 break;
159 } 156 }
160 } 157 }
161 158
162 for (sv_frame_t f: redundant) { 159 for (sv_frame_t f: redundant) {
163 m_seams.remove(f); 160 m_seams.erase(f);
164 } 161 }
165 } 162 }
166 163
167 #ifdef DEBUG_EVENT_SERIES 164 #ifdef DEBUG_EVENT_SERIES
168 std::cerr << "after remove:" << std::endl; 165 std::cerr << "after remove:" << std::endl;
213 const sv_frame_t start = frame; 210 const sv_frame_t start = frame;
214 const sv_frame_t end = frame + duration; 211 const sv_frame_t end = frame + duration;
215 212
216 // first find any zero-duration events 213 // first find any zero-duration events
217 214
218 auto pitr = m_events.lowerBound(Event(start, QString())); 215 auto pitr = m_events.lower_bound(Event(start, QString()));
219 while (pitr != m_events.end() && pitr.key().getFrame() < end) { 216 while (pitr != m_events.end() && pitr->first.getFrame() < end) {
220 if (!pitr.key().hasDuration()) { 217 if (!pitr->first.hasDuration()) {
221 for (int i = 0; i < pitr.value(); ++i) { 218 for (int i = 0; i < pitr->second; ++i) {
222 span.push_back(pitr.key()); 219 span.push_back(pitr->first);
223 } 220 }
224 } 221 }
225 ++pitr; 222 ++pitr;
226 } 223 }
227 224
228 // now any non-zero-duration ones from the seam map 225 // now any non-zero-duration ones from the seam map
229 226
230 std::set<Event> found; 227 std::set<Event> found;
231 auto sitr = m_seams.lowerBound(start); 228 auto sitr = m_seams.lower_bound(start);
232 if (sitr == m_seams.end() || sitr.key() > start) { 229 if (sitr == m_seams.end() || sitr->first > start) {
233 if (sitr != m_seams.begin()) { 230 if (sitr != m_seams.begin()) {
234 --sitr; 231 --sitr;
235 } 232 }
236 } 233 }
237 while (sitr != m_seams.end() && sitr.key() < end) { 234 while (sitr != m_seams.end() && sitr->first < end) {
238 for (const auto &p: sitr.value()) { 235 for (const auto &p: sitr->second) {
239 found.insert(p); 236 found.insert(p);
240 } 237 }
241 ++sitr; 238 ++sitr;
242 } 239 }
243 for (const auto &p: found) { 240 for (const auto &p: found) {
244 int n = m_events.value(p); 241 int n = m_events.at(p);
245 if (n < 1) { 242 if (n < 1) {
246 throw std::logic_error("event is in seams but not events"); 243 throw std::logic_error("event is in seams but not events");
247 } 244 }
248 for (int i = 0; i < n; ++i) { 245 for (int i = 0; i < n; ++i) {
249 span.push_back(p); 246 span.push_back(p);
263 EventVector getEventsCovering(sv_frame_t frame) const { 260 EventVector getEventsCovering(sv_frame_t frame) const {
264 EventVector cover; 261 EventVector cover;
265 262
266 // first find any zero-duration events 263 // first find any zero-duration events
267 264
268 auto pitr = m_events.lowerBound(Event(frame, QString())); 265 auto pitr = m_events.lower_bound(Event(frame, QString()));
269 while (pitr != m_events.end() && pitr.key().getFrame() == frame) { 266 while (pitr != m_events.end() && pitr->first.getFrame() == frame) {
270 if (!pitr.key().hasDuration()) { 267 if (!pitr->first.hasDuration()) {
271 for (int i = 0; i < pitr.value(); ++i) { 268 for (int i = 0; i < pitr->second; ++i) {
272 cover.push_back(pitr.key()); 269 cover.push_back(pitr->first);
273 } 270 }
274 } 271 }
275 ++pitr; 272 ++pitr;
276 } 273 }
277 274
278 // now any non-zero-duration ones from the seam map. We insert 275 // now any non-zero-duration ones from the seam map
279 // these into a std::set to recover the ordering, lost by QSet 276
280 277 auto sitr = m_seams.lower_bound(frame);
281 std::set<Event> found; 278 if (sitr == m_seams.end() || sitr->first > frame) {
282 auto sitr = m_seams.lowerBound(frame);
283 if (sitr == m_seams.end() || sitr.key() > frame) {
284 if (sitr != m_seams.begin()) { 279 if (sitr != m_seams.begin()) {
285 --sitr; 280 --sitr;
286 } 281 }
287 } 282 }
288 if (sitr != m_seams.end() && sitr.key() <= frame) { 283 if (sitr != m_seams.end() && sitr->first <= frame) {
289 for (const auto &p: sitr.value()) { 284 for (const auto &p: sitr->second) {
290 found.insert(p); 285 int n = m_events.at(p);
291 } 286 if (n < 1) {
292 ++sitr; 287 throw std::logic_error("event is in seams but not events");
293 } 288 }
294 for (const auto &p: found) { 289 for (int i = 0; i < n; ++i) {
295 int n = m_events.value(p); 290 cover.push_back(p);
296 if (n < 1) { 291 }
297 throw std::logic_error("event is in seams but not events");
298 }
299 for (int i = 0; i < n; ++i) {
300 cover.push_back(p);
301 } 292 }
302 } 293 }
303 294
304 return cover; 295 return cover;
305 } 296 }
308 /** 299 /**
309 * Total number of events in the series. Will exceed 300 * Total number of events in the series. Will exceed
310 * m_events.size() if the series contains duplicate events. 301 * m_events.size() if the series contains duplicate events.
311 */ 302 */
312 int m_count; 303 int m_count;
313 304
314 /** 305 /**
315 * The (ordered) Events map acts as a list of all the events in 306 * The (ordered) Events map acts as a list of all the events in
316 * the series. For reasons of backward compatibility, we have to 307 * the series. For reasons of backward compatibility, we have to
317 * handle series containing multiple instances of identical 308 * handle series containing multiple instances of identical
318 * events; the int indexed against each event records the number 309 * events; the int indexed against each event records the number
323 * 314 *
324 * Because events are immutable, we never have to move one to a 315 * Because events are immutable, we never have to move one to a
325 * different "key" in this map - we only add or delete them or 316 * different "key" in this map - we only add or delete them or
326 * change their counts. 317 * change their counts.
327 */ 318 */
328 typedef QMap<Event, int> Events; 319 typedef std::map<Event, int> Events;
329 Events m_events; 320 Events m_events;
330 321
331 /** 322 /**
332 * The FrameEventMap maps from frame number to a set of events. In 323 * The FrameEventMap maps from frame number to a set of events. In
333 * the seam map this is used to represent the events that are 324 * the seam map this is used to represent the events that are
338 * onward and disappearing again at its end frame. 329 * onward and disappearing again at its end frame.
339 * 330 *
340 * Only events with duration appear in this map; point events 331 * Only events with duration appear in this map; point events
341 * appear only in m_events. 332 * appear only in m_events.
342 */ 333 */
343 typedef QMap<sv_frame_t, QSet<Event>> FrameEventMap; 334 typedef std::map<sv_frame_t, std::set<Event>> FrameEventMap;
344 FrameEventMap m_seams; 335 FrameEventMap m_seams;
345 336
346 /** Create a seam at the given frame, copying from the prior seam 337 /** Create a seam at the given frame, copying from the prior seam
347 * if there is one. If a seam already exists at the given frame, 338 * if there is one. If a seam already exists at the given frame,
348 * leave it untouched. 339 * leave it untouched.
349 */ 340 */
350 void createSeam(sv_frame_t frame) { 341 void createSeam(sv_frame_t frame) {
351 auto itr = m_seams.lowerBound(frame); 342 auto itr = m_seams.lower_bound(frame);
352 if (itr == m_seams.end() || itr.key() > frame) { 343 if (itr == m_seams.end() || itr->first > frame) {
353 if (itr != m_seams.begin()) { 344 if (itr != m_seams.begin()) {
354 --itr; 345 --itr;
355 } 346 }
356 } 347 }
357 if (itr == m_seams.end()) { 348 if (itr == m_seams.end()) {
358 m_seams[frame] = {}; 349 m_seams[frame] = {};
359 } else if (itr.key() < frame) { 350 } else if (itr->first < frame) {
360 m_seams[frame] = itr.value(); 351 m_seams[frame] = itr->second;
361 } else if (itr.key() > frame) { // itr must be begin() 352 } else if (itr->first > frame) { // itr must be begin()
362 m_seams[frame] = {}; 353 m_seams[frame] = {};
363 } 354 }
364 } 355 }
365 356
366 #ifdef DEBUG_EVENT_SERIES 357 #ifdef DEBUG_EVENT_SERIES