Mercurial > hg > svcore
comparison base/EventSeries.h @ 1627:1c21ddac220e single-point
Seems we can do just as well with a vector of events themselves
author | Chris Cannam |
---|---|
date | Mon, 11 Mar 2019 14:49:13 +0000 |
parents | 895186c43fce |
children | b2048f350906 |
comparison
equal
deleted
inserted
replaced
1626:895186c43fce | 1627:1c21ddac220e |
---|---|
54 return m_events == other.m_events; | 54 return m_events == other.m_events; |
55 } | 55 } |
56 | 56 |
57 void add(const Event &p) { | 57 void add(const Event &p) { |
58 | 58 |
59 bool isUnique = true; | |
60 | |
61 auto pitr = m_events.find(p); | |
62 if (pitr != m_events.end()) { | |
63 isUnique = false; | |
64 } | |
65 | |
59 ++m_events[p]; | 66 ++m_events[p]; |
60 ++m_count; | 67 ++m_count; |
61 | 68 |
62 sv_id_t id = Event::getId(p); | 69 if (p.hasDuration() && isUnique) { |
63 | |
64 if (p.hasDuration()) { | |
65 | 70 |
66 const sv_frame_t frame = p.getFrame(); | 71 const sv_frame_t frame = p.getFrame(); |
67 const sv_frame_t endFrame = p.getFrame() + p.getDuration(); | 72 const sv_frame_t endFrame = p.getFrame() + p.getDuration(); |
68 | 73 |
69 createSeam(frame); | 74 createSeam(frame); |
78 SVCERR << "ERROR: EventSeries::add: " | 83 SVCERR << "ERROR: EventSeries::add: " |
79 << "reached end of seam map" | 84 << "reached end of seam map" |
80 << endl; | 85 << endl; |
81 break; | 86 break; |
82 } | 87 } |
83 /* bool found = false; | 88 i->second.push_back(p); |
84 for (auto eid: i->second) { | |
85 if (eid == id) { | |
86 found = true; | |
87 break; | |
88 } | |
89 } | |
90 if (!found) {*/ | |
91 i->second.push_back(id); | |
92 // } | |
93 } | 89 } |
94 } | 90 } |
95 | 91 |
96 #ifdef DEBUG_EVENT_SERIES | 92 #ifdef DEBUG_EVENT_SERIES |
97 std::cerr << "after add:" << std::endl; | 93 std::cerr << "after add:" << std::endl; |
116 m_events.erase(pitr); | 112 m_events.erase(pitr); |
117 } | 113 } |
118 --m_count; | 114 --m_count; |
119 } | 115 } |
120 | 116 |
121 sv_id_t id = Event::getId(p); | |
122 | |
123 if (p.hasDuration() && isUnique) { | 117 if (p.hasDuration() && isUnique) { |
124 | 118 |
125 const sv_frame_t frame = p.getFrame(); | 119 const sv_frame_t frame = p.getFrame(); |
126 const sv_frame_t endFrame = p.getFrame() + p.getDuration(); | 120 const sv_frame_t endFrame = p.getFrame() + p.getDuration(); |
127 | 121 |
136 << " for event not found in seam map: event is " | 130 << " for event not found in seam map: event is " |
137 << p.toXmlString() << endl; | 131 << p.toXmlString() << endl; |
138 } | 132 } |
139 #endif | 133 #endif |
140 | 134 |
135 // Remove any and all instances of p from the seam map; we | |
136 // are only supposed to get here if we are removing the | |
137 // last instance of p from the series anyway | |
138 | |
141 for (auto i = i0; i != i1; ++i) { | 139 for (auto i = i0; i != i1; ++i) { |
142 if (i == m_seams.end()) { | 140 if (i == m_seams.end()) { |
143 // This can happen only if we have a negative | 141 // This can happen only if we have a negative |
144 // duration, which Event forbids | 142 // duration, which Event forbids |
145 throw std::logic_error("unexpectedly reached end of map"); | 143 throw std::logic_error("unexpectedly reached end of map"); |
146 } | 144 } |
147 for (size_t j = 0; j < i->second.size(); ) { | 145 for (size_t j = 0; j < i->second.size(); ) { |
148 if (i->second[j] == id) { | 146 if (i->second[j] == p) { |
149 i->second.erase(i->second.begin() + j); | 147 i->second.erase(i->second.begin() + j); |
150 } else { | 148 } else { |
151 ++j; | 149 ++j; |
152 } | 150 } |
153 } | 151 } |
154 } | 152 } |
155 | 153 |
156 // Tidy up by removing any entries that are now identical | 154 // Tidy up by removing any entries that are now identical |
157 // to their predecessors | 155 // to their predecessors |
158 | |
159 //!!! won't work as vector is not consistently ordered | |
160 | 156 |
161 std::vector<sv_frame_t> redundant; | 157 std::vector<sv_frame_t> redundant; |
162 | 158 |
163 auto pitr = m_seams.end(); | 159 auto pitr = m_seams.end(); |
164 if (i0 != m_seams.begin()) { | 160 if (i0 != m_seams.begin()) { |
165 pitr = i0; | 161 pitr = i0; |
166 --pitr; | 162 --pitr; |
167 } | 163 } |
168 | 164 |
169 for (auto i = i0; i != m_seams.end(); ++i) { | 165 for (auto i = i0; i != m_seams.end(); ++i) { |
170 if (pitr != m_seams.end() && i->second == pitr->second) { | 166 if (pitr != m_seams.end() && |
167 seamsEqual(i->second, pitr->second)) { | |
171 redundant.push_back(i->first); | 168 redundant.push_back(i->first); |
172 } | 169 } |
173 pitr = i; | 170 pitr = i; |
174 if (i == i1) { | 171 if (i == i1) { |
175 break; | 172 break; |
176 } | 173 } |
177 } | 174 } |
178 | 175 |
179 for (sv_frame_t f: redundant) { | 176 for (sv_frame_t f: redundant) { |
180 m_seams.erase(f); | 177 m_seams.erase(f); |
178 } | |
179 | |
180 // And remove any empty seams from the start of the map | |
181 | |
182 while (m_seams.begin() != m_seams.end() && | |
183 m_seams.begin()->second.empty()) { | |
184 m_seams.erase(m_seams.begin()); | |
181 } | 185 } |
182 } | 186 } |
183 | 187 |
184 #ifdef DEBUG_EVENT_SERIES | 188 #ifdef DEBUG_EVENT_SERIES |
185 std::cerr << "after remove:" << std::endl; | 189 std::cerr << "after remove:" << std::endl; |
250 if (sitr != m_seams.begin()) { | 254 if (sitr != m_seams.begin()) { |
251 --sitr; | 255 --sitr; |
252 } | 256 } |
253 } | 257 } |
254 while (sitr != m_seams.end() && sitr->first < end) { | 258 while (sitr != m_seams.end() && sitr->first < end) { |
255 for (const auto &id: sitr->second) { | 259 for (const auto &p: sitr->second) { |
256 found.insert(Event::getEventForId(id)); | 260 found.insert(p); |
257 } | 261 } |
258 ++sitr; | 262 ++sitr; |
259 } | 263 } |
260 for (const auto &p: found) { | 264 for (const auto &p: found) { |
261 int n = m_events.at(p); | 265 int n = m_events.at(p); |
300 if (sitr != m_seams.begin()) { | 304 if (sitr != m_seams.begin()) { |
301 --sitr; | 305 --sitr; |
302 } | 306 } |
303 } | 307 } |
304 if (sitr != m_seams.end() && sitr->first <= frame) { | 308 if (sitr != m_seams.end() && sitr->first <= frame) { |
305 for (const auto &id: sitr->second) { | 309 for (const auto &p: sitr->second) { |
306 found.insert(Event::getEventForId(id)); | 310 found.insert(p); |
307 } | 311 } |
308 ++sitr; | 312 ++sitr; |
309 } | 313 } |
310 for (const auto &p: found) { | 314 for (const auto &p: found) { |
311 int n = m_events.at(p); | 315 int n = m_events.at(p); |
352 * an entry here for each frame at which an event starts or ends, | 356 * an entry here for each frame at which an event starts or ends, |
353 * with the event appearing in all entries from its start time | 357 * with the event appearing in all entries from its start time |
354 * onward and disappearing again at its end frame. | 358 * onward and disappearing again at its end frame. |
355 * | 359 * |
356 * Only events with duration appear in this map; point events | 360 * Only events with duration appear in this map; point events |
357 * appear only in m_events. | 361 * appear only in m_events. Note that unlike m_events, we only |
358 */ | 362 * store one instance of each event here, even if we hold many - |
359 typedef std::map<sv_frame_t, std::vector<sv_id_t>> FrameEventMap; | 363 * we refer back to m_events when we need to know how many |
364 * identical copies of a given event we have. | |
365 */ | |
366 typedef std::map<sv_frame_t, std::vector<Event>> FrameEventMap; | |
360 FrameEventMap m_seams; | 367 FrameEventMap m_seams; |
361 | 368 |
362 /** Create a seam at the given frame, copying from the prior seam | 369 /** Create a seam at the given frame, copying from the prior seam |
363 * if there is one. If a seam already exists at the given frame, | 370 * if there is one. If a seam already exists at the given frame, |
364 * leave it untouched. | 371 * leave it untouched. |
375 } else if (itr->first < frame) { | 382 } else if (itr->first < frame) { |
376 m_seams[frame] = itr->second; | 383 m_seams[frame] = itr->second; |
377 } else if (itr->first > frame) { // itr must be begin() | 384 } else if (itr->first > frame) { // itr must be begin() |
378 m_seams[frame] = {}; | 385 m_seams[frame] = {}; |
379 } | 386 } |
387 } | |
388 | |
389 bool seamsEqual(const std::vector<Event> &s1, | |
390 const std::vector<Event> &s2) const { | |
391 | |
392 if (s1.size() != s2.size()) { | |
393 return false; | |
394 } | |
395 | |
396 // precondition: no event appears more than once in s1 or more | |
397 // than once in s2 | |
398 | |
399 #ifdef DEBUG_EVENT_SERIES | |
400 for (int i = 0; in_range_for(s1, i); ++i) { | |
401 for (int j = i + 1; in_range_for(s1, j); ++j) { | |
402 if (s1[i] == s1[j] || s2[i] == s2[j]) { | |
403 throw std::runtime_error | |
404 ("debug error: duplicate event in s1 or s2"); | |
405 } | |
406 } | |
407 } | |
408 #endif | |
409 | |
410 std::set<Event> ee; | |
411 for (const auto &e: s1) { | |
412 ee.insert(e); | |
413 } | |
414 for (const auto &e: s2) { | |
415 if (ee.find(e) == ee.end()) { | |
416 return false; | |
417 } | |
418 } | |
419 return true; | |
380 } | 420 } |
381 | 421 |
382 #ifdef DEBUG_EVENT_SERIES | 422 #ifdef DEBUG_EVENT_SERIES |
383 void dumpEvents() const { | 423 void dumpEvents() const { |
384 std::cerr << "EVENTS (" << m_events.size() << ") [" << std::endl; | 424 std::cerr << "EVENTS (" << m_events.size() << ") [" << std::endl; |