Mercurial > hg > svcore
comparison data/model/Dense3DModelPeakCache.cpp @ 1778:59d9dcfd67c2
Replace the model used for the cache part of the peak-cache model with a simple vector of vectors. Avoids unnecessary locking in a class that is not thread-safe in any case. Also record whether the final column is actually truncated, rather than risk possible backward seeks to re-read it in the case where it simply might be
author | Chris Cannam |
---|---|
date | Wed, 11 Sep 2019 11:19:27 +0100 |
parents | d484490cdf69 |
children |
comparison
equal
deleted
inserted
replaced
1777:d484490cdf69 | 1778:59d9dcfd67c2 |
---|---|
20 #include "base/HitCount.h" | 20 #include "base/HitCount.h" |
21 | 21 |
22 Dense3DModelPeakCache::Dense3DModelPeakCache(ModelId sourceId, | 22 Dense3DModelPeakCache::Dense3DModelPeakCache(ModelId sourceId, |
23 int columnsPerPeak) : | 23 int columnsPerPeak) : |
24 m_source(sourceId), | 24 m_source(sourceId), |
25 m_columnsPerPeak(columnsPerPeak) | 25 m_columnsPerPeak(columnsPerPeak), |
26 m_finalColumnIncomplete(false) | |
26 { | 27 { |
27 auto source = ModelById::getAs<DenseThreeDimensionalModel>(m_source); | 28 auto source = ModelById::getAs<DenseThreeDimensionalModel>(m_source); |
28 if (!source) { | 29 if (!source) { |
29 SVCERR << "WARNING: Dense3DModelPeakCache constructed for unknown or wrong-type source model id " << m_source << endl; | 30 SVCERR << "WARNING: Dense3DModelPeakCache constructed for unknown or wrong-type source model id " << m_source << endl; |
30 m_source = {}; | 31 m_source = {}; |
31 return; | 32 return; |
32 } | 33 } |
33 | |
34 m_cache.reset(new EditableDenseThreeDimensionalModel | |
35 (source->getSampleRate(), | |
36 source->getResolution() * m_columnsPerPeak, | |
37 source->getHeight(), | |
38 false)); | |
39 | 34 |
40 connect(source.get(), SIGNAL(modelChanged(ModelId)), | 35 connect(source.get(), SIGNAL(modelChanged(ModelId)), |
41 this, SLOT(sourceModelChanged(ModelId))); | 36 this, SLOT(sourceModelChanged(ModelId))); |
42 } | 37 } |
43 | 38 |
47 | 42 |
48 Dense3DModelPeakCache::Column | 43 Dense3DModelPeakCache::Column |
49 Dense3DModelPeakCache::getColumn(int column) const | 44 Dense3DModelPeakCache::getColumn(int column) const |
50 { | 45 { |
51 if (!haveColumn(column)) fillColumn(column); | 46 if (!haveColumn(column)) fillColumn(column); |
52 return m_cache->getColumn(column); | 47 return m_cache.at(column); |
53 } | 48 } |
54 | 49 |
55 float | 50 float |
56 Dense3DModelPeakCache::getValueAt(int column, int n) const | 51 Dense3DModelPeakCache::getValueAt(int column, int n) const |
57 { | 52 { |
58 if (!haveColumn(column)) fillColumn(column); | 53 if (!haveColumn(column)) fillColumn(column); |
59 return m_cache->getValueAt(column, n); | 54 return m_cache.at(column).at(n); |
60 } | 55 } |
61 | 56 |
62 void | 57 void |
63 Dense3DModelPeakCache::sourceModelChanged(ModelId) | 58 Dense3DModelPeakCache::sourceModelChanged(ModelId) |
64 { | 59 { |
65 if (m_coverage.size() > 0) { | 60 if (m_finalColumnIncomplete && m_coverage.size() > 0) { |
66 // The last peak may have come from an incomplete read, which | 61 // The last peak came from an incomplete read, which may since |
67 // may since have been filled, so reset it | 62 // have been filled, so reset it |
68 m_coverage[m_coverage.size()-1] = false; | 63 m_coverage[m_coverage.size()-1] = false; |
64 m_finalColumnIncomplete = false; | |
69 } | 65 } |
70 m_coverage.resize(getWidth(), false); // retaining data | |
71 } | 66 } |
72 | 67 |
73 bool | 68 bool |
74 Dense3DModelPeakCache::haveColumn(int column) const | 69 Dense3DModelPeakCache::haveColumn(int column) const |
75 { | 70 { |
87 Dense3DModelPeakCache::fillColumn(int column) const | 82 Dense3DModelPeakCache::fillColumn(int column) const |
88 { | 83 { |
89 Profiler profiler("Dense3DModelPeakCache::fillColumn"); | 84 Profiler profiler("Dense3DModelPeakCache::fillColumn"); |
90 | 85 |
91 if (!in_range_for(m_coverage, column)) { | 86 if (!in_range_for(m_coverage, column)) { |
92 if (m_coverage.size() > 0) { | 87 if (m_finalColumnIncomplete && m_coverage.size() > 0) { |
93 // The last peak may have come from an incomplete read, which | 88 // The last peak may have come from an incomplete read, which |
94 // may since have been filled, so reset it | 89 // may since have been filled, so reset it |
95 m_coverage[m_coverage.size()-1] = false; | 90 m_coverage[m_coverage.size()-1] = false; |
91 m_finalColumnIncomplete = false; | |
96 } | 92 } |
97 m_coverage.resize(column + 1, false); | 93 m_coverage.resize(column + 1, false); |
94 m_cache.resize(column + 1, {}); | |
95 } | |
96 | |
97 auto source = ModelById::getAs<DenseThreeDimensionalModel>(m_source); | |
98 if (!source) { | |
99 return; | |
100 } | |
101 | |
102 int sourceWidth = source->getWidth(); | |
103 int sourceColumn = column * m_columnsPerPeak; | |
104 if (sourceColumn >= sourceWidth) { | |
105 return; | |
98 } | 106 } |
99 | 107 |
100 auto source = ModelById::getAs<DenseThreeDimensionalModel>(m_source); | 108 Column peak = source->getColumn(sourceColumn); |
101 if (!source) return; | 109 int n = int(peak.size()); |
102 | 110 |
103 int sourceWidth = source->getWidth(); | 111 for (int i = 1; i < m_columnsPerPeak; ++i) { |
104 | |
105 Column peak; | |
106 int n = 0; | |
107 for (int i = 0; i < m_columnsPerPeak; ++i) { | |
108 | 112 |
109 int sourceColumn = column * m_columnsPerPeak + i; | 113 ++sourceColumn; |
110 if (sourceColumn >= sourceWidth) break; | 114 if (sourceColumn >= sourceWidth) { |
115 m_finalColumnIncomplete = true; | |
116 break; | |
117 } | |
111 | 118 |
112 Column here = source->getColumn(sourceColumn); | 119 Column here = source->getColumn(sourceColumn); |
113 | 120 int m = std::min(n, int(here.size())); |
114 // cerr << "Dense3DModelPeakCache::fillColumn(" << column << "): source col " | 121 for (int j = 0; j < m; ++j) { |
115 // << sourceColumn << " of " << sourceWidth | 122 peak[j] = std::max(here[j], peak[j]); |
116 // << " returned " << here.size() << " elts" << endl; | |
117 | |
118 if (i == 0) { | |
119 peak = here; | |
120 n = int(peak.size()); | |
121 } else { | |
122 int m = std::min(n, int(here.size())); | |
123 for (int j = 0; j < m; ++j) { | |
124 peak[j] = std::max(here[j], peak[j]); | |
125 } | |
126 } | 123 } |
127 } | 124 } |
128 | 125 |
129 m_cache->setColumn(column, peak); | 126 m_cache[column] = peak; |
130 m_coverage[column] = true; | 127 m_coverage[column] = true; |
131 } | 128 } |
132 | 129 |
133 | 130 |