Use NoteData::iterator instead of a track-row pair. With n nonempty rows in the NoteData and m nonempty rows in the range, iterating over the whole range took O(m log n). Now, it takes O(m). (Saves the map look ups which are amortized log-time.)

This commit is contained in:
Steve Checkoway
2006-08-17 17:58:45 +00:00
parent 955a8a99ae
commit f57bc1ef78
2 changed files with 22 additions and 41 deletions
+13 -31
View File
@@ -913,56 +913,39 @@ void NoteData::LoadFromNode( const XNode* pNode )
} }
template<typename ND, typename iter, typename TN> template<typename ND, typename iter, typename TN>
void NoteData::_all_tracks_iterator<ND, iter, TN>::NextRowAllTracks() void NoteData::_all_tracks_iterator<ND, iter, TN>::Find()
{ {
int iMinRow = INT_MAX; int iMinRow = m_iEndRow+1;
for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack ) for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack )
{ {
int iRow = m_iRow; iter &i = m_vIters[iTrack];
if( m_Cond )
while( i != m_NoteData.end(iTrack) && i->first < iMinRow && !m_Cond(i->second) )
++i;
if( m_NoteData.GetNextTapNoteRowForTrack(iTrack, iRow) ) if( i != m_NoteData.end(iTrack) && i->first < iMinRow )
iMinRow = min( iMinRow, iRow );
}
m_iRow = iMinRow;
}
template<typename ND, typename iter, typename TN>
void NoteData::_all_tracks_iterator<ND, iter, TN>::Find()
{ {
m_iRow = max( m_iRow, m_iStartRow ); iMinRow = i->first;
while( m_iRow <= m_iEndRow ) m_iTrack = iTrack;
{
while( m_iTrack < m_NoteData.GetNumTracks() )
{
m_Iterator = m_NoteData.FindTapNote( m_iTrack, m_iRow );
if( m_Iterator != m_NoteData.end(m_iTrack) && (!m_Cond || m_Cond(m_Iterator->second)) )
return;
++m_iTrack;
} }
m_iTrack = 0;
++m_iRow;
int oldRow = m_iRow;
NextRowAllTracks();
ASSERT( oldRow < m_iRow );
} }
} }
template<typename ND, typename iter, typename TN> template<typename ND, typename iter, typename TN>
NoteData::_all_tracks_iterator<ND, iter, TN>::_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, NoteData::IteratorCond cond ) : NoteData::_all_tracks_iterator<ND, iter, TN>::_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, NoteData::IteratorCond cond ) :
m_NoteData(nd), m_iTrack(0), m_iRow(0), m_iStartRow(iStartRow), m_iEndRow(iEndRow), m_Cond(cond) m_NoteData(nd), m_iTrack(0), m_iEndRow(iEndRow), m_Cond(cond)
{ {
ASSERT( m_NoteData.GetNumTracks() > 0 ); ASSERT( m_NoteData.GetNumTracks() > 0 );
NextRowAllTracks(); for( int iTrack = 0; iTrack < m_NoteData.GetNumTracks(); ++iTrack )
m_vIters.push_back( m_NoteData.lower_bound(iTrack, iStartRow) );
Find(); Find();
} }
template<typename ND, typename iter, typename TN> template<typename ND, typename iter, typename TN>
NoteData::_all_tracks_iterator<ND, iter, TN> &NoteData::_all_tracks_iterator<ND, iter, TN>::operator++() // preincrement NoteData::_all_tracks_iterator<ND, iter, TN> &NoteData::_all_tracks_iterator<ND, iter, TN>::operator++() // preincrement
{ {
DEBUG_ASSERT( m_iRow <= m_iEndRow ); ++m_vIters[m_iTrack];
++m_iTrack;
Find(); Find();
return *this; return *this;
} }
@@ -970,7 +953,6 @@ NoteData::_all_tracks_iterator<ND, iter, TN> &NoteData::_all_tracks_iterator<ND,
template<typename ND, typename iter, typename TN> template<typename ND, typename iter, typename TN>
NoteData::_all_tracks_iterator<ND, iter, TN> NoteData::_all_tracks_iterator<ND, iter, TN>::operator++( int dummy ) // postincrement NoteData::_all_tracks_iterator<ND, iter, TN> NoteData::_all_tracks_iterator<ND, iter, TN>::operator++( int dummy ) // postincrement
{ {
DEBUG_ASSERT( m_iRow <= m_iEndRow );
_all_tracks_iterator<ND, iter, TN> ret(*this); _all_tracks_iterator<ND, iter, TN> ret(*this);
operator++(); operator++();
return ret; return ret;
+9 -10
View File
@@ -32,26 +32,23 @@ public:
class _all_tracks_iterator class _all_tracks_iterator
{ {
ND &m_NoteData; ND &m_NoteData;
vector<iter> m_vIters;
int m_iTrack; int m_iTrack;
int m_iRow;
const int m_iStartRow;
const int m_iEndRow; const int m_iEndRow;
iter m_Iterator;
IteratorCond m_Cond; IteratorCond m_Cond;
void NextRowAllTracks();
void Find(); void Find();
public: public:
_all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, IteratorCond cond ); _all_tracks_iterator( ND &nd, int iStartRow, int iEndRow, IteratorCond cond );
_all_tracks_iterator &operator++(); // preincrement _all_tracks_iterator &operator++(); // preincrement
_all_tracks_iterator operator++( int dummy ); // postincrement _all_tracks_iterator operator++( int dummy ); // postincrement
inline int Track() const { return m_iTrack; } inline int Track() const { return m_iTrack; }
inline int Row() const { return m_iRow; } inline int Row() const { return m_vIters[m_iTrack]->first; }
inline bool IsAtEnd() const { return m_iRow > m_iEndRow; } inline bool IsAtEnd() const { return m_vIters[m_iTrack] == m_NoteData.end( m_iTrack ) || Row() > m_iEndRow; }
inline TN &operator*() { DEBUG_ASSERT( m_iRow <= m_iEndRow ); return m_Iterator->second; } inline TN &operator*() { DEBUG_ASSERT( !IsAtEnd() ); return m_vIters[m_iTrack]->second; }
inline TN *operator->() { DEBUG_ASSERT( m_iRow <= m_iEndRow ); return &m_Iterator->second; } inline TN *operator->() { DEBUG_ASSERT( !IsAtEnd() ); return &m_vIters[m_iTrack]->second; }
inline const TN &operator*() const { DEBUG_ASSERT( m_iRow <= m_iEndRow ); return m_Iterator->second; } inline const TN &operator*() const { DEBUG_ASSERT( !IsAtEnd() ); return m_vIters[m_iTrack]->second; }
inline const TN *operator->() const { DEBUG_ASSERT( m_iRow <= m_iEndRow ); return &m_Iterator->second; } inline const TN *operator->() const { DEBUG_ASSERT( !IsAtEnd() ); return &m_vIters[m_iTrack]->second; }
}; };
typedef _all_tracks_iterator<NoteData, iterator, TapNote> all_tracks_iterator; typedef _all_tracks_iterator<NoteData, iterator, TapNote> all_tracks_iterator;
typedef _all_tracks_iterator<const NoteData, const_iterator, const TapNote> all_tracks_const_iterator; typedef _all_tracks_iterator<const NoteData, const_iterator, const TapNote> all_tracks_const_iterator;
@@ -86,6 +83,8 @@ public:
const_iterator begin( int iTrack ) const { return m_TapNotes[iTrack].begin(); } const_iterator begin( int iTrack ) const { return m_TapNotes[iTrack].begin(); }
iterator end( int iTrack ) { return m_TapNotes[iTrack].end(); } iterator end( int iTrack ) { return m_TapNotes[iTrack].end(); }
const_iterator end( int iTrack ) const { return m_TapNotes[iTrack].end(); } const_iterator end( int iTrack ) const { return m_TapNotes[iTrack].end(); }
iterator lower_bound( int iTrack, int iRow ) { return m_TapNotes[iTrack].lower_bound( iRow ); }
const_iterator lower_bound( int iTrack, int iRow ) const { return m_TapNotes[iTrack].lower_bound( iRow ); }
void swap( NoteData &nd ) { m_TapNotes.swap( nd.m_TapNotes ); } void swap( NoteData &nd ) { m_TapNotes.swap( nd.m_TapNotes ); }
inline iterator FindTapNote( unsigned iTrack, int iRow ) { return m_TapNotes[iTrack].find( iRow ); } inline iterator FindTapNote( unsigned iTrack, int iRow ) { return m_TapNotes[iTrack].find( iRow ); }