seq_vector_ci.cpp
来自「ncbi源码」· C++ 代码 · 共 923 行 · 第 1/2 页
CPP
923 行
void CSeqVector_CI::x_UpdateCacheDown(TSeqPos pos){ _ASSERT(pos < x_GetSize()); TSeqPos segStart = m_Seg.GetPosition(); _ASSERT(pos >= segStart && pos < m_Seg.GetEndPosition()); TSeqPos cache_offset = min(kCacheSize - 1, pos - segStart); x_FillCache(pos - cache_offset, cache_offset + 1); m_Cache = m_CacheData + cache_offset; _ASSERT(GetPos() == pos);}void CSeqVector_CI::x_FillCache(TSeqPos start, TSeqPos count){ _ASSERT(m_Seg.GetType() != CSeqMap::eSeqEnd); _ASSERT(start >= m_Seg.GetPosition()); _ASSERT(start < m_Seg.GetEndPosition()); x_ResizeCache(count); switch ( m_Seg.GetType() ) { case CSeqMap::eSeqData: { const CSeq_data& data = m_Seg.GetRefData(); CSeqVector::TCoding dataCoding = data.Which(); CSeqVector::TCoding cacheCoding = x_GetCoding(m_Coding, dataCoding); bool reverse = m_Seg.GetRefMinusStrand(); bool randomize = false; if (cacheCoding == CSeq_data::e_Ncbi2na && bool(m_Randomizer)) { cacheCoding = CSeq_data::e_Ncbi4na; randomize = true; } const char* table = 0; if ( cacheCoding != dataCoding || reverse ) { table = CSeqVector::sx_GetConvertTable(dataCoding, cacheCoding, reverse); if ( !table && cacheCoding != dataCoding ) { NCBI_THROW(CSeqVectorException, eCodingError, "Incompatible sequence codings"); } } TSeqPos dataPos; if ( reverse ) { // Revert segment offset dataPos = m_Seg.GetRefEndPosition() - (start - m_Seg.GetPosition()) - count; } else { dataPos = m_Seg.GetRefPosition() + (start - m_Seg.GetPosition()); } switch ( dataCoding ) { case CSeq_data::e_Iupacna: copy_8bit_any(m_Cache, count, data.GetIupacna().Get(), dataPos, table, reverse); break; case CSeq_data::e_Iupacaa: copy_8bit_any(m_Cache, count, data.GetIupacaa().Get(), dataPos, table, reverse); break; case CSeq_data::e_Ncbi2na: copy_2bit_any(m_Cache, count, data.GetNcbi2na().Get(), dataPos, table, reverse); break; case CSeq_data::e_Ncbi4na: copy_4bit_any(m_Cache, count, data.GetNcbi4na().Get(), dataPos, table, reverse); break; case CSeq_data::e_Ncbi8na: copy_8bit_any(m_Cache, count, data.GetNcbi8na().Get(), dataPos, table, reverse); break; case CSeq_data::e_Ncbipna: NCBI_THROW(CSeqVectorException, eCodingError, "Ncbipna conversion not implemented"); case CSeq_data::e_Ncbi8aa: copy_8bit_any(m_Cache, count, data.GetNcbi8aa().Get(), dataPos, table, reverse); break; case CSeq_data::e_Ncbieaa: copy_8bit_any(m_Cache, count, data.GetNcbieaa().Get(), dataPos, table, reverse); break; case CSeq_data::e_Ncbipaa: NCBI_THROW(CSeqVectorException, eCodingError, "Ncbipaa conversion not implemented"); case CSeq_data::e_Ncbistdaa: copy_8bit_any(m_Cache, count, data.GetNcbistdaa().Get(), dataPos, table, reverse); break; default: NCBI_THROW(CSeqVectorException, eCodingError, "Invalid data coding"); } if ( randomize ) { m_Randomizer->RandomizeData(m_Cache, count, start); } break; } case CSeqMap::eSeqGap: // x_GetCoding(m_Coding, CSeq_data::e_not_set); fill(m_Cache, m_Cache + count, CSeqVector::x_GetGapChar(m_Coding)); if (m_Coding == CSeq_data::e_Ncbi2na && bool(m_Randomizer)) { m_Randomizer->RandomizeData(m_Cache, count, start); } break; default: NCBI_THROW(CSeqVectorException, eDataError, "Invalid segment type"); } m_CachePos = start;}void CSeqVector_CI::x_SetPos(TSeqPos pos){ TSeqPos size = x_GetSize(); if ( pos >= size ) { if ( x_CacheSize() ) { // save current cache as backup x_SwapCache(); x_ResetCache(); } _ASSERT(x_CacheSize() == 0 && x_CacheOffset() == 0); m_CachePos = size; _ASSERT(GetPos() == size); return; } _ASSERT(pos - x_CachePos() >= x_CacheSize()); // update current segment x_UpdateSeg(pos); // save current cache as backup and restore old backup x_SwapCache(); // check if old backup is suitable TSeqPos cache_offset = pos - x_CachePos(); TSeqPos cache_size = x_CacheSize(); if ( cache_offset < cache_size ) { // can use backup _ASSERT(x_CacheSize() && x_CachePos() >= m_Seg.GetPosition() && x_CacheEndPos() <= m_Seg.GetEndPosition()); m_Cache = m_CacheData + cache_offset; } else { // cannot use backup x_InitializeCache(); TSeqPos old_pos = x_BackupPos(); if ( pos < old_pos && pos >= old_pos - kCacheSize && m_Seg.GetEndPosition() >= old_pos ) { x_UpdateCacheDown(old_pos - 1); cache_offset = pos - x_CachePos(); m_Cache = m_CacheData + cache_offset; } else { x_UpdateCacheUp(pos); } } _ASSERT(x_CacheOffset() < x_CacheSize()); _ASSERT(GetPos() == pos);}void CSeqVector_CI::x_UpdateSeg(TSeqPos pos){ if ( m_Seg.IsInvalid() ) { x_InitSeg(pos); } else if ( m_Seg.GetPosition() > pos ) { // segment is ahead do { _ASSERT(m_Seg || m_Seg.GetPosition() == x_GetSize()); --m_Seg; } while ( m_Seg.GetLength() == 0 ); // skip zero length segments _ASSERT(m_Seg); if ( m_Seg.GetPosition() > pos ) { // too far x_InitSeg(pos); } } else if ( m_Seg.GetEndPosition() <= pos ) { // segment is behind do { _ASSERT(m_Seg); ++m_Seg; } while ( m_Seg.GetLength() == 0 ); // skip zero length segments _ASSERT(m_Seg); if ( m_Seg.GetEndPosition() <= pos ) { // too far x_InitSeg(pos); } } _ASSERT(pos >= m_Seg.GetPosition() && pos < m_Seg.GetEndPosition());}void CSeqVector_CI::GetSeqData(string& buffer, TSeqPos count){ buffer.erase(); count = min(count, x_GetSize() - GetPos()); if ( count ) { buffer.reserve(count); do { TCache_I cache = m_Cache; TCache_I cache_end = m_CacheEnd; TSeqPos chunk_count = min(count, TSeqPos(cache_end - cache)); _ASSERT(chunk_count > 0); TCache_I chunk_end = cache + chunk_count; buffer.append(cache, chunk_end); if ( chunk_end == cache_end ) { x_NextCacheSeg(); } else { m_Cache = chunk_end; } count -= chunk_count; } while ( count ); }}void CSeqVector_CI::x_NextCacheSeg(){ _ASSERT(m_SeqMap); TSeqPos pos = x_CacheEndPos(); // save current cache in backup _ASSERT(x_CacheSize()); x_SwapCache(); // update segment if needed while ( m_Seg.GetEndPosition() <= pos ) { if ( !m_Seg ) { // end of sequence _ASSERT(pos == x_GetSize()); x_ResetCache(); m_CachePos = pos; return; } ++m_Seg; } _ASSERT(m_Seg); // Try to re-use backup cache if ( pos < x_CacheEndPos() && pos >= x_CachePos() ) { m_Cache = m_CacheData + pos - x_CachePos(); } else { // can not use backup cache x_ResetCache(); x_UpdateCacheUp(pos); _ASSERT(GetPos() == pos); _ASSERT(x_CacheSize()); _ASSERT(x_CachePos() == pos); }}void CSeqVector_CI::x_PrevCacheSeg(){ _ASSERT(m_SeqMap); TSeqPos pos = x_CachePos(); if ( pos-- == 0 ) { // Can not go further NCBI_THROW(CSeqVectorException, eOutOfRange, "Can not update cache: iterator out of range"); } // save current cache in backup x_SwapCache(); // update segment if needed if ( m_Seg.IsInvalid() ) { x_InitSeg(pos); } else { while ( m_Seg.GetPosition() > pos ) { _ASSERT(m_Seg || m_Seg.GetPosition() == x_GetSize()); --m_Seg; } } _ASSERT(m_Seg); // Try to re-use backup cache if ( pos >= x_CachePos() && pos < x_CacheEndPos() ) { m_Cache = m_CacheData + pos - x_CachePos(); } else { // can not use backup cache x_ResetCache(); x_UpdateCacheDown(pos); _ASSERT(GetPos() == pos); _ASSERT(x_CacheSize()); _ASSERT(x_CacheEndPos() == pos+1); }}void CSeqVector_CI::x_InitRandomizer(CRandom& random_gen){ TSeqPos pos = GetPos(); x_ResetCache(); x_ResetBackup(); m_Randomizer.Reset(new CNcbi2naRandomizer(random_gen)); x_SetPos(pos);}void CSeqVector_CI::SetRandomizeAmbiguities(void){ CRandom random_gen; x_InitRandomizer(random_gen);}void CSeqVector_CI::SetRandomizeAmbiguities(Uint4 seed){ CRandom random_gen(seed); x_InitRandomizer(random_gen);}void CSeqVector_CI::SetRandomizeAmbiguities(CRandom& random_gen){ x_InitRandomizer(random_gen);}void CSeqVector_CI::SetNoAmbiguities(void){ TSeqPos pos = GetPos(); x_ResetCache(); x_ResetBackup(); m_Randomizer.Reset(); x_SetPos(pos);}END_SCOPE(objects)END_NCBI_SCOPE/** ---------------------------------------------------------------------------* $Log: seq_vector_ci.cpp,v $* Revision 1000.3 2004/06/01 19:24:26 gouriano* PRODUCTION: UPGRADED [GCC34_MSVC7] Dev-tree R1.34** Revision 1.34 2004/05/21 21:42:13 gorelenk* Added PCH ncbi_pch.hpp** Revision 1.33 2004/05/10 18:27:37 grichenk* Check cache in x_ResizeCache()** Revision 1.32 2004/04/27 14:45:01 grichenk* Fixed warnings.** Revision 1.31 2004/04/22 18:34:18 grichenk* Added optional ambiguity randomizer for ncbi2na coding** Revision 1.30 2004/04/12 16:49:16 vasilche* Allow null scope in CSeqMap_CI and CSeqVector.** Revision 1.29 2004/04/09 20:34:50 vasilche* Fixed wrong assertion.** Revision 1.28 2003/11/07 17:00:13 vasilche* Added check for out of bounds withing CSeq_inst to avoid coredump.** Revision 1.27 2003/10/08 14:16:55 vasilche* Removed circular reference CSeqVector <-> CSeqVector_CI.** Revision 1.26 2003/09/05 17:29:40 grichenk* Structurized Object Manager exceptions** Revision 1.25 2003/08/29 13:34:47 vasilche* Rewrote CSeqVector/CSeqVector_CI code to allow better inlining.* CSeqVector::operator[] made significantly faster.* Added possibility to have platform dependent byte unpacking functions.** Revision 1.24 2003/08/21 18:51:34 vasilche* Fixed compilation errors on translation with reverse.** Revision 1.23 2003/08/21 17:04:10 vasilche* Fixed bug in making conversion tables.** Revision 1.22 2003/08/21 13:32:04 vasilche* Optimized CSeqVector iteration.* Set some CSeqVector values (mol type, coding) in constructor instead of detecting them while iteration.* Remove unsafe bit manipulations with coding.** Revision 1.21 2003/08/19 18:34:11 vasilche* Buffer length constant moved to *.cpp file for easier modification.** Revision 1.20 2003/07/21 14:30:48 vasilche* Fixed buffer destruction and exception processing.** Revision 1.19 2003/07/18 20:41:48 grichenk* Fixed memory leaks in CSeqVector_CI** Revision 1.18 2003/07/18 19:42:42 vasilche* Added x_DestroyCache() method.** Revision 1.17 2003/07/01 18:00:41 vasilche* Fixed unsigned/signed comparison.** Revision 1.16 2003/06/24 19:46:43 grichenk* Changed cache from vector<char> to char*. Made* CSeqVector::operator[] inline.** Revision 1.15 2003/06/18 15:01:19 vasilche* Fixed positioning of CSeqVector_CI in GetSeqData().** Revision 1.14 2003/06/17 20:37:06 grichenk* Removed _TRACE-s, fixed bug in x_GetNextSeg()** Revision 1.13 2003/06/13 17:22:28 grichenk* Check if seq-map is not null before using it** Revision 1.12 2003/06/10 15:27:14 vasilche* Fixed warning** Revision 1.11 2003/06/06 15:09:43 grichenk* One more fix for coordinates** Revision 1.10 2003/06/05 20:20:22 grichenk* Fixed bugs in assignment functions,* fixed minor problems with coordinates.** Revision 1.9 2003/06/04 13:48:56 grichenk* Improved double-caching, fixed problem with strands.** Revision 1.8 2003/06/02 21:03:59 vasilche* Grichenko's fix of wrong data in CSeqVector.** Revision 1.7 2003/06/02 16:53:35 dicuccio* Restore file damaged by last check-in** Revision 1.5 2003/05/31 01:42:51 ucko* Avoid min(size_t, TSeqPos), as they may be different types.** Revision 1.4 2003/05/30 19:30:08 vasilche* Fixed compilation on GCC 3.** Revision 1.3 2003/05/30 18:00:29 grichenk* Fixed caching bugs in CSeqVector_CI** Revision 1.2 2003/05/29 13:35:36 grichenk* Fixed bugs in buffer fill/copy procedures.** Revision 1.1 2003/05/27 19:42:24 grichenk* Initial revision*** ===========================================================================*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?