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;