diff 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
line wrap: on
line diff
--- a/base/EventSeries.h	Mon Mar 11 13:44:35 2019 +0000
+++ b/base/EventSeries.h	Mon Mar 11 14:49:13 2019 +0000
@@ -56,12 +56,17 @@
     
     void add(const Event &p) {
 
+        bool isUnique = true;
+
+        auto pitr = m_events.find(p);
+        if (pitr != m_events.end()) {
+            isUnique = false;
+        }
+
         ++m_events[p];
         ++m_count;
 
-        sv_id_t id = Event::getId(p);
-        
-        if (p.hasDuration()) {
+        if (p.hasDuration() && isUnique) {
 
             const sv_frame_t frame = p.getFrame();
             const sv_frame_t endFrame = p.getFrame() + p.getDuration();
@@ -80,16 +85,7 @@
                            << endl;
                     break;
                 }
-/*                bool found = false;
-                for (auto eid: i->second) {
-                    if (eid == id) {
-                        found = true;
-                        break;
-                    }
-                }
-                if (!found) {*/
-                    i->second.push_back(id);
-//                }
+                i->second.push_back(p);
             }
         }
 
@@ -118,8 +114,6 @@
             --m_count;
         }
 
-        sv_id_t id = Event::getId(p);
-        
         if (p.hasDuration() && isUnique) {
             
             const sv_frame_t frame = p.getFrame();
@@ -138,6 +132,10 @@
             }
 #endif
 
+            // Remove any and all instances of p from the seam map; we
+            // are only supposed to get here if we are removing the
+            // last instance of p from the series anyway
+            
             for (auto i = i0; i != i1; ++i) {
                 if (i == m_seams.end()) {
                     // This can happen only if we have a negative
@@ -145,7 +143,7 @@
                     throw std::logic_error("unexpectedly reached end of map");
                 }
                 for (size_t j = 0; j < i->second.size(); ) {
-                    if (i->second[j] == id) {
+                    if (i->second[j] == p) {
                         i->second.erase(i->second.begin() + j);
                     } else {
                         ++j;
@@ -155,8 +153,6 @@
 
             // Tidy up by removing any entries that are now identical
             // to their predecessors
-
-//!!! won't work as vector is not consistently ordered
             
             std::vector<sv_frame_t> redundant;
 
@@ -167,7 +163,8 @@
             }
 
             for (auto i = i0; i != m_seams.end(); ++i) {
-                if (pitr != m_seams.end() && i->second == pitr->second) {
+                if (pitr != m_seams.end() &&
+                    seamsEqual(i->second, pitr->second)) {
                     redundant.push_back(i->first);
                 }
                 pitr = i;
@@ -179,6 +176,13 @@
             for (sv_frame_t f: redundant) {
                 m_seams.erase(f);
             }
+
+            // And remove any empty seams from the start of the map
+            
+            while (m_seams.begin() != m_seams.end() &&
+                   m_seams.begin()->second.empty()) {
+                m_seams.erase(m_seams.begin());
+            }
         }
 
 #ifdef DEBUG_EVENT_SERIES
@@ -252,8 +256,8 @@
             }                
         }
         while (sitr != m_seams.end() && sitr->first < end) {
-            for (const auto &id: sitr->second) {
-                found.insert(Event::getEventForId(id));
+            for (const auto &p: sitr->second) {
+                found.insert(p);
             }
             ++sitr;
         }
@@ -302,8 +306,8 @@
             }                
         }
         if (sitr != m_seams.end() && sitr->first <= frame) {
-            for (const auto &id: sitr->second) {
-                found.insert(Event::getEventForId(id));
+            for (const auto &p: sitr->second) {
+                found.insert(p);
             }
             ++sitr;
         }
@@ -354,9 +358,12 @@
      * onward and disappearing again at its end frame.
      *
      * Only events with duration appear in this map; point events
-     * appear only in m_events.
+     * appear only in m_events. Note that unlike m_events, we only
+     * store one instance of each event here, even if we hold many -
+     * we refer back to m_events when we need to know how many
+     * identical copies of a given event we have.
      */
-    typedef std::map<sv_frame_t, std::vector<sv_id_t>> FrameEventMap;
+    typedef std::map<sv_frame_t, std::vector<Event>> FrameEventMap;
     FrameEventMap m_seams;
 
     /** Create a seam at the given frame, copying from the prior seam
@@ -379,6 +386,39 @@
         }
     }
 
+    bool seamsEqual(const std::vector<Event> &s1,
+                    const std::vector<Event> &s2) const {
+        
+        if (s1.size() != s2.size()) {
+            return false;
+        }
+
+        // precondition: no event appears more than once in s1 or more
+        // than once in s2
+
+#ifdef DEBUG_EVENT_SERIES
+        for (int i = 0; in_range_for(s1, i); ++i) {
+            for (int j = i + 1; in_range_for(s1, j); ++j) {
+                if (s1[i] == s1[j] || s2[i] == s2[j]) {
+                    throw std::runtime_error
+                        ("debug error: duplicate event in s1 or s2");
+                }
+            }
+        }
+#endif
+
+        std::set<Event> ee;
+        for (const auto &e: s1) {
+            ee.insert(e);
+        }
+        for (const auto &e: s2) {
+            if (ee.find(e) == ee.end()) {
+                return false;
+            }
+        }
+        return true;
+    }
+
 #ifdef DEBUG_EVENT_SERIES
     void dumpEvents() const {
         std::cerr << "EVENTS (" << m_events.size() << ") [" << std::endl;