Mercurial > hg > svcore
changeset 1626:895186c43fce single-point
Experiment with storing vectors of event ids in seam map for compactness
author | Chris Cannam |
---|---|
date | Mon, 11 Mar 2019 13:44:35 +0000 |
parents | 7dbb2a7b592e |
children | 1c21ddac220e |
files | base/BaseTypes.h base/Event.cpp base/Event.h base/EventSeries.h files.pri |
diffstat | 5 files changed, 92 insertions(+), 14 deletions(-) [+] |
line wrap: on
line diff
--- a/base/BaseTypes.h Mon Mar 11 11:25:17 2019 +0000 +++ b/base/BaseTypes.h Mon Mar 11 13:44:35 2019 +0000 @@ -55,5 +55,11 @@ typedef std::vector<std::complex<float>, breakfastquay::StlAllocator<std::complex<float>>> complexvec_t; +typedef uint64_t sv_id_t; + +enum { + ID_NOTHING = 0 +}; + #endif
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/base/Event.cpp Mon Mar 11 13:44:35 2019 +0000 @@ -0,0 +1,21 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + Sonic Visualiser + An audio file viewer and annotation editor. + Centre for Digital Music, Queen Mary, University of London. + This file copyright 2006 Chris Cannam. + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2 of the + License, or (at your option) any later version. See the file + COPYING included with this distribution for more information. +*/ + +#include "Event.h" + +sv_id_t Event::m_nextId = 1; +QHash<Event, sv_id_t> Event::m_ids; +QHash<sv_id_t, Event> Event::m_rids; +
--- a/base/Event.h Mon Mar 11 11:25:17 2019 +0000 +++ b/base/Event.h Mon Mar 11 13:44:35 2019 +0000 @@ -279,6 +279,27 @@ if (m_haveReferenceFrame) h ^= qHash(m_referenceFrame); return h; } + + static sv_id_t getId(const Event &ev) { + sv_id_t id; + if (!m_ids.contains(ev)) { + id = m_nextId; + ++m_nextId; + m_ids[ev] = id; + m_rids[id] = ev; + return id; + } else { + return m_ids.value(ev); + } + } + + static Event getEventForId(sv_id_t id) { + if (!m_rids.contains(id)) { + throw std::runtime_error("unknown event id"); + } else { + return m_rids.value(id); + } + } private: // The order of fields here is chosen to minimise overall size of struct. @@ -293,6 +314,10 @@ sv_frame_t m_duration; sv_frame_t m_referenceFrame; QString m_label; + + static sv_id_t m_nextId; + static QHash<Event, sv_id_t> m_ids; + static QHash<sv_id_t, Event> m_rids; }; inline uint qHash(const Event &e, uint seed = 0) {
--- a/base/EventSeries.h Mon Mar 11 11:25:17 2019 +0000 +++ b/base/EventSeries.h Mon Mar 11 13:44:35 2019 +0000 @@ -59,6 +59,8 @@ ++m_events[p]; ++m_count; + sv_id_t id = Event::getId(p); + if (p.hasDuration()) { const sv_frame_t frame = p.getFrame(); @@ -78,7 +80,16 @@ << endl; break; } - i->second.insert(p); +/* bool found = false; + for (auto eid: i->second) { + if (eid == id) { + found = true; + break; + } + } + if (!found) {*/ + i->second.push_back(id); +// } } } @@ -107,6 +118,8 @@ --m_count; } + sv_id_t id = Event::getId(p); + if (p.hasDuration() && isUnique) { const sv_frame_t frame = p.getFrame(); @@ -131,13 +144,20 @@ // duration, which Event forbids throw std::logic_error("unexpectedly reached end of map"); } - - i->second.erase(p); + for (size_t j = 0; j < i->second.size(); ) { + if (i->second[j] == id) { + i->second.erase(i->second.begin() + j); + } else { + ++j; + } + } } // 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; auto pitr = m_seams.end(); @@ -232,8 +252,8 @@ } } while (sitr != m_seams.end() && sitr->first < end) { - for (const auto &p: sitr->second) { - found.insert(p); + for (const auto &id: sitr->second) { + found.insert(Event::getEventForId(id)); } ++sitr; } @@ -274,6 +294,7 @@ // now any non-zero-duration ones from the seam map + std::set<Event> found; auto sitr = m_seams.lower_bound(frame); if (sitr == m_seams.end() || sitr->first > frame) { if (sitr != m_seams.begin()) { @@ -281,14 +302,18 @@ } } if (sitr != m_seams.end() && sitr->first <= frame) { - for (const auto &p: sitr->second) { - int n = m_events.at(p); - if (n < 1) { - throw std::logic_error("event is in seams but not events"); - } - for (int i = 0; i < n; ++i) { - cover.push_back(p); - } + for (const auto &id: sitr->second) { + found.insert(Event::getEventForId(id)); + } + ++sitr; + } + for (const auto &p: found) { + int n = m_events.at(p); + if (n < 1) { + throw std::logic_error("event is in seams but not events"); + } + for (int i = 0; i < n; ++i) { + cover.push_back(p); } } @@ -331,7 +356,7 @@ * Only events with duration appear in this map; point events * appear only in m_events. */ - typedef std::map<sv_frame_t, std::set<Event>> FrameEventMap; + typedef std::map<sv_frame_t, std::vector<sv_id_t>> FrameEventMap; FrameEventMap m_seams; /** Create a seam at the given frame, copying from the prior seam