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 + -
显示快捷键?