comparison base/EventSeries.h @ 1624:dcd510bd89db single-point

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