Mercurial > hg > svcore
comparison data/model/EditableDenseThreeDimensionalModel.cpp @ 535:3ccf48fb81d6
* make compression optional in editable dense 3d model, and some tweaks
author | Chris Cannam |
---|---|
date | Fri, 23 Jan 2009 14:00:29 +0000 |
parents | 6038cb6fcd30 |
children | beb51f558e9c |
comparison
equal
deleted
inserted
replaced
534:6038cb6fcd30 | 535:3ccf48fb81d6 |
---|---|
26 #include <cassert> | 26 #include <cassert> |
27 | 27 |
28 EditableDenseThreeDimensionalModel::EditableDenseThreeDimensionalModel(size_t sampleRate, | 28 EditableDenseThreeDimensionalModel::EditableDenseThreeDimensionalModel(size_t sampleRate, |
29 size_t resolution, | 29 size_t resolution, |
30 size_t yBinCount, | 30 size_t yBinCount, |
31 CompressionType compression, | |
31 bool notifyOnAdd) : | 32 bool notifyOnAdd) : |
32 m_sampleRate(sampleRate), | 33 m_sampleRate(sampleRate), |
33 m_resolution(resolution), | 34 m_resolution(resolution), |
34 m_yBinCount(yBinCount), | 35 m_yBinCount(yBinCount), |
36 m_compression(compression), | |
35 m_minimum(0.0), | 37 m_minimum(0.0), |
36 m_maximum(0.0), | 38 m_maximum(0.0), |
37 m_haveExtents(false), | 39 m_haveExtents(false), |
38 m_notifyOnAdd(notifyOnAdd), | 40 m_notifyOnAdd(notifyOnAdd), |
39 m_sinceLastNotifyMin(-1), | 41 m_sinceLastNotifyMin(-1), |
71 { | 73 { |
72 QMutexLocker locker(&m_mutex); | 74 QMutexLocker locker(&m_mutex); |
73 | 75 |
74 EditableDenseThreeDimensionalModel *model = | 76 EditableDenseThreeDimensionalModel *model = |
75 new EditableDenseThreeDimensionalModel | 77 new EditableDenseThreeDimensionalModel |
76 (m_sampleRate, m_resolution, m_yBinCount); | 78 (m_sampleRate, m_resolution, m_yBinCount, m_compression); |
77 | 79 |
78 model->m_minimum = m_minimum; | 80 model->m_minimum = m_minimum; |
79 model->m_maximum = m_maximum; | 81 model->m_maximum = m_maximum; |
80 model->m_haveExtents = m_haveExtents; | 82 model->m_haveExtents = m_haveExtents; |
81 | 83 |
150 | 152 |
151 float | 153 float |
152 EditableDenseThreeDimensionalModel::getValueAt(size_t index, size_t n) const | 154 EditableDenseThreeDimensionalModel::getValueAt(size_t index, size_t n) const |
153 { | 155 { |
154 Column c = getColumn(index); | 156 Column c = getColumn(index); |
155 if (n < c.size()) return s.at(n); | 157 if (n < c.size()) return c.at(n); |
156 return m_minimum; | 158 return m_minimum; |
157 } | 159 } |
158 | 160 |
159 static int given = 0, stored = 0; | 161 //static int given = 0, stored = 0; |
160 | 162 |
161 void | 163 void |
162 EditableDenseThreeDimensionalModel::truncateAndStore(size_t index, | 164 EditableDenseThreeDimensionalModel::truncateAndStore(size_t index, |
163 const Column &values) | 165 const Column &values) |
164 { | 166 { |
165 assert(index < m_data.size()); | 167 assert(index < m_data.size()); |
166 | 168 |
167 //std::cout << "truncateAndStore(" << index << ", " << values.size() << ")" << std::endl; | 169 //std::cout << "truncateAndStore(" << index << ", " << values.size() << ")" << std::endl; |
168 | 170 |
171 // The default case is to store the entire column at m_data[index] | |
172 // and place 0 at m_trunc[index] to indicate that it has not been | |
173 // truncated. We only do clever stuff if one of the clever-stuff | |
174 // tests works out. | |
175 | |
169 m_trunc[index] = 0; | 176 m_trunc[index] = 0; |
170 if (index == 0 || values.size() != m_yBinCount) { | 177 if (index == 0 || |
171 given += values.size(); | 178 m_compression == NoCompression || |
172 stored += values.size(); | 179 values.size() != m_yBinCount) { |
180 // given += values.size(); | |
181 // stored += values.size(); | |
173 m_data[index] = values; | 182 m_data[index] = values; |
174 return; | 183 return; |
175 } | 184 } |
176 | 185 |
177 static int maxdist = 120; | 186 // Maximum distance between a column and the one we refer to as |
178 | 187 // the source of its truncated values. Limited by having to fit |
179 bool known = false; | 188 // in a signed char, but in any case small values are usually |
180 bool top = false; | 189 // better |
181 | 190 static int maxdist = 6; |
191 | |
192 bool known = false; // do we know whether to truncate at top or bottom? | |
193 bool top = false; // if we do know, will we truncate at top? | |
194 | |
195 // If the previous column is not truncated, then it is the only | |
196 // candidate for comparison. If it is truncated, then the column | |
197 // that it refers to is the only candidate. Either way, we only | |
198 // have one possible column to compare against here, and we are | |
199 // being careful to ensure it is not a truncated one (to avoid | |
200 // doing more work recursively when uncompressing). | |
182 int tdist = 1; | 201 int tdist = 1; |
183 int ptrunc = m_trunc[index-1]; | 202 int ptrunc = m_trunc[index-1]; |
184 if (ptrunc < 0) { | 203 if (ptrunc < 0) { |
185 top = false; | 204 top = false; |
186 known = true; | 205 known = true; |
196 | 215 |
197 if (p.size() == h && tdist <= maxdist) { | 216 if (p.size() == h && tdist <= maxdist) { |
198 | 217 |
199 int bcount = 0, tcount = 0; | 218 int bcount = 0, tcount = 0; |
200 if (!known || !top) { | 219 if (!known || !top) { |
220 // count how many identical values there are at the bottom | |
201 for (int i = 0; i < h; ++i) { | 221 for (int i = 0; i < h; ++i) { |
202 if (values.at(i) == p.at(i)) ++bcount; | 222 if (values.at(i) == p.at(i)) ++bcount; |
203 else break; | 223 else break; |
204 } | 224 } |
205 } | 225 } |
206 if (!known || top) { | 226 if (!known || top) { |
227 // count how many identical values there are at the top | |
207 for (int i = h; i > 0; --i) { | 228 for (int i = h; i > 0; --i) { |
208 if (values.at(i-1) == p.at(i-1)) ++tcount; | 229 if (values.at(i-1) == p.at(i-1)) ++tcount; |
209 else break; | 230 else break; |
210 } | 231 } |
211 } | 232 } |
212 if (!known) top = (tcount > bcount); | 233 if (!known) top = (tcount > bcount); |
213 | 234 |
214 int limit = h / 4; | 235 int limit = h / 4; // don't bother unless we have at least this many |
215 if ((top ? tcount : bcount) > limit) { | 236 if ((top ? tcount : bcount) > limit) { |
216 | 237 |
217 if (!top) { | 238 if (!top) { |
239 // create a new column with h - bcount values from bcount up | |
218 Column tcol(h - bcount); | 240 Column tcol(h - bcount); |
219 given += values.size(); | 241 // given += values.size(); |
220 stored += h - bcount; | 242 // stored += h - bcount; |
221 for (int i = bcount; i < h; ++i) { | 243 for (int i = bcount; i < h; ++i) { |
222 tcol[i - bcount] = values.at(i); | 244 tcol[i - bcount] = values.at(i); |
223 } | 245 } |
224 m_data[index] = tcol; | 246 m_data[index] = tcol; |
225 m_trunc[index] = -tdist; | 247 m_trunc[index] = -tdist; |
226 //std::cout << "bottom " << bcount << " as col at " << -tdist << std::endl; | |
227 return; | 248 return; |
228 } else { | 249 } else { |
250 // create a new column with h - tcount values from 0 up | |
229 Column tcol(h - tcount); | 251 Column tcol(h - tcount); |
230 given += values.size(); | 252 // given += values.size(); |
231 stored += h - tcount; | 253 // stored += h - tcount; |
232 for (int i = 0; i < h - tcount; ++i) { | 254 for (int i = 0; i < h - tcount; ++i) { |
233 tcol[i] = values.at(i); | 255 tcol[i] = values.at(i); |
234 } | 256 } |
235 m_data[index] = tcol; | 257 m_data[index] = tcol; |
236 m_trunc[index] = tdist; | 258 m_trunc[index] = tdist; |
237 //std::cout << "top " << tcount << " as col at " << -tdist << std::endl; | |
238 return; | 259 return; |
239 } | 260 } |
240 } | 261 } |
241 } | 262 } |
242 | 263 |
243 given += values.size(); | 264 // given += values.size(); |
244 stored += values.size(); | 265 // stored += values.size(); |
245 | |
246 // std::cout << "given: " << given << ", stored: " << stored << " (" | 266 // std::cout << "given: " << given << ", stored: " << stored << " (" |
247 // << ((float(stored) / float(given)) * 100.f) << "%)" << std::endl; | 267 // << ((float(stored) / float(given)) * 100.f) << "%)" << std::endl; |
248 | 268 |
269 // default case if nothing wacky worked out | |
249 m_data[index] = values; | 270 m_data[index] = values; |
250 return; | 271 return; |
251 } | 272 } |
252 | 273 |
253 EditableDenseThreeDimensionalModel::Column | 274 EditableDenseThreeDimensionalModel::Column |
254 EditableDenseThreeDimensionalModel::expandAndRetrieve(size_t index) const | 275 EditableDenseThreeDimensionalModel::expandAndRetrieve(size_t index) const |
255 { | 276 { |
277 // See comment above m_trunc declaration in header | |
278 | |
256 assert(index < m_data.size()); | 279 assert(index < m_data.size()); |
257 Column c = m_data.at(index); | 280 Column c = m_data.at(index); |
258 if (index == 0) { | 281 if (index == 0) { |
259 return c; | 282 return c; |
260 } | 283 } |