1 /* $Id: tse_info.cpp 611141 2020-06-29 20:55:12Z vasilche $
2 * ===========================================================================
3 *
4 * PUBLIC DOMAIN NOTICE
5 * National Center for Biotechnology Information
6 *
7 * This software/database is a "United States Government Work" under the
8 * terms of the United States Copyright Act. It was written as part of
9 * the author's official duties as a United States Government employee and
10 * thus cannot be copyrighted. This software/database is freely available
11 * to the public for use. The National Library of Medicine and the U.S.
12 * Government have not placed any restriction on its use or reproduction.
13 *
14 * Although all reasonable efforts have been taken to ensure the accuracy
15 * and reliability of the software and data, the NLM and the U.S.
16 * Government do not and cannot warrant the performance or results that
17 * may be obtained by using this software or data. The NLM and the U.S.
18 * Government disclaim all warranties, express or implied, including
19 * warranties of performance, merchantability or fitness for any particular
20 * purpose.
21 *
22 * Please cite the author in any work or product based on this material.
23 *
24 * ===========================================================================
25 *
26 * Author: Aleksey Grichenko, Eugene Vasilchenko
27 *
28 * File Description:
29 * TSE info -- entry for data source seq-id to TSE map
30 *
31 */
32
33
34 #include <ncbi_pch.hpp>
35 #include <objmgr/impl/data_source.hpp>
36 #include <objmgr/impl/tse_info.hpp>
37 #include <objmgr/impl/tse_split_info.hpp>
38 #include <objmgr/impl/tse_chunk_info.hpp>
39 #include <objmgr/impl/tse_assigner.hpp>
40 #include <objmgr/impl/bioseq_info.hpp>
41 #include <objmgr/impl/bioseq_set_info.hpp>
42 #include <objmgr/impl/annot_object.hpp>
43 #include <objmgr/impl/seq_annot_info.hpp>
44 #include <objmgr/impl/snp_annot_info.hpp>
45 #include <objmgr/impl/annot_type_index.hpp>
46 #include <objmgr/impl/handle_range.hpp>
47 #include <objmgr/impl/handle_range_map.hpp>
48
49 #include <objects/seqset/Seq_entry.hpp>
50 #include <objects/submit/Seq_submit.hpp>
51
52 #include <objmgr/objmgr_exception.hpp>
53 #include <objmgr/error_codes.hpp>
54
55 #include <algorithm>
56
57
58 #define NCBI_USE_ERRCODE_X ObjMgr_TSEinfo
59
60 BEGIN_NCBI_SCOPE
61
62 NCBI_DEFINE_ERR_SUBCODE_X(3);
63
BEGIN_SCOPE(objects)64 BEGIN_SCOPE(objects)
65
66
67 SIdAnnotObjs::SIdAnnotObjs(void)
68 {
69 }
70
71
~SIdAnnotObjs(void)72 SIdAnnotObjs::~SIdAnnotObjs(void)
73 {
74 NON_CONST_ITERATE ( TAnnotSet, it, m_AnnotSet ) {
75 delete *it;
76 *it = 0;
77 }
78 }
79
80
x_GetRangeMap(size_t index)81 SIdAnnotObjs::TRangeMap& SIdAnnotObjs::x_GetRangeMap(size_t index)
82 {
83 if ( index >= m_AnnotSet.size() ) {
84 m_AnnotSet.resize(index+1);
85 }
86 TRangeMap*& slot = m_AnnotSet[index];
87 if ( !slot ) {
88 slot = new TRangeMap;
89 }
90 return *slot;
91 }
92
93
x_CleanRangeMaps(void)94 bool SIdAnnotObjs::x_CleanRangeMaps(void)
95 {
96 while ( !m_AnnotSet.empty() ) {
97 TRangeMap*& slot = m_AnnotSet.back();
98 if ( slot ) {
99 if ( !slot->empty() ) {
100 return false;
101 }
102 delete slot;
103 slot = 0;
104 }
105 m_AnnotSet.pop_back();
106 }
107 return true;
108 }
109
110
SIdAnnotObjs(const SIdAnnotObjs & _DEBUG_ARG (objs))111 SIdAnnotObjs::SIdAnnotObjs(const SIdAnnotObjs& _DEBUG_ARG(objs))
112 {
113 _ASSERT(objs.m_AnnotSet.empty());
114 _ASSERT(objs.m_SNPSet.empty());
115 }
116
117
118 ////////////////////////////////////////////////////////////////////
119 //
120 // CTSE_Info::
121 //
122 // General information and indexes for top level seq-entries
123 //
124
125
CTSE_Info(void)126 CTSE_Info::CTSE_Info(void)
127 : m_InternalBioObjNumber(0),
128 m_MasterSeqSegmentsLoaded(false)
129 {
130 x_Initialize();
131
132 x_TSEAttach(*this);
133 }
134
135
CTSE_Info(const TBlobId & blob_id,TBlobVersion blob_version)136 CTSE_Info::CTSE_Info(const TBlobId& blob_id,
137 TBlobVersion blob_version)
138 : m_InternalBioObjNumber(0),
139 m_MasterSeqSegmentsLoaded(false)
140 {
141 x_Initialize();
142
143 m_BlobId = blob_id;
144 m_BlobVersion = blob_version;
145
146 x_TSEAttach(*this);
147 }
148
149
CTSE_Info(CSeq_entry & entry,TBlobState blob_state,const TBlobId & blob_id,TBlobVersion blob_version)150 CTSE_Info::CTSE_Info(CSeq_entry& entry,
151 TBlobState blob_state,
152 const TBlobId& blob_id,
153 TBlobVersion blob_version)
154 : m_InternalBioObjNumber(0),
155 m_MasterSeqSegmentsLoaded(false)
156 {
157 x_Initialize();
158
159 m_BlobId = blob_id;
160 m_BlobVersion = blob_version;
161 m_BlobState = blob_state;
162
163 SetSeq_entry(entry);
164 m_LoadState = eLoaded;
165
166 x_TSEAttach(*this);
167 }
168
169
CTSE_Info(CSeq_entry & entry,TBlobState blob_state)170 CTSE_Info::CTSE_Info(CSeq_entry& entry,
171 TBlobState blob_state)
172 : m_InternalBioObjNumber(0),
173 m_MasterSeqSegmentsLoaded(false)
174 {
175 x_Initialize();
176
177 m_BlobState = blob_state;
178
179 SetSeq_entry(entry);
180 m_LoadState = eLoaded;
181
182 x_TSEAttach(*this);
183 }
184
185
CTSE_Info(const CTSE_Lock & tse)186 CTSE_Info::CTSE_Info(const CTSE_Lock& tse)
187 : m_BaseTSE(new SBaseTSE(tse)),
188 m_InternalBioObjNumber(0),
189 m_MasterSeqSegmentsLoaded(false)
190 {
191 x_Initialize();
192
193 m_BlobState = tse->m_BlobState;
194 m_TopLevelObjectType = tse->m_TopLevelObjectType;
195 m_Name = tse->m_Name;
196 m_UsedMemory = tse->m_UsedMemory;
197 m_LoadState = eLoaded;
198
199 // update Seq-inst object with split data
200 tse->x_Update(fNeedUpdate_children_seq_data|fNeedUpdate_children_bioseq);
201 x_SetObject(*tse, &m_BaseTSE->m_ObjectCopyMap);
202 x_TSEAttach(*this);
203
204 m_Split = tse->m_Split;
205 if (m_Split) {
206 CRef<ITSE_Assigner> lsnr = m_Split->GetAssigner(*tse);
207 if( !lsnr )
208 lsnr.Reset(new CTSE_Default_Assigner);
209 m_Split->x_TSEAttach(*this, lsnr);
210 m_BioseqUpdater = tse->m_BioseqUpdater;
211 }
212 if (tse->HasDataSource()) {
213 CDataLoader* ld = tse->GetDataSource().GetDataLoader();
214 if ( ld ) {
215 m_EditSaver = ld->GetEditSaver();
216 m_BlobId = tse->m_BlobId;
217 //CBlobIdKey(new CBlobIdString(tse->m_BlobId.ToString()));
218 }
219 }
220 }
221
222
~CTSE_Info(void)223 CTSE_Info::~CTSE_Info(void)
224 {
225 _ASSERT(m_LockCounter.Get() == 0);
226 _ASSERT(m_DataSource == 0);
227 if( m_Split )
228 m_Split->x_TSEDetach(*this);
229 }
230
231
Assign(const CTSE_Lock & tse)232 CTSE_Info& CTSE_Info::Assign(const CTSE_Lock& tse)
233 {
234 // m_BaseTSE.reset(new SBaseTSE(tse));
235 m_BlobState = tse->m_BlobState;
236 m_TopLevelObjectType = tse->m_TopLevelObjectType;
237 m_Name = tse->m_Name;
238 m_UsedMemory = tse->m_UsedMemory;
239
240 if (tse->m_Contents)
241 x_SetObject(*tse,NULL);//tse->m_BaseTSE->m_ObjectCopyMap);
242 //x_TSEAttach(*this);
243
244 m_Split = tse->m_Split;
245 if (m_Split) {
246 CRef<ITSE_Assigner> listener = m_Split->GetAssigner(*tse);
247 if( !listener )
248 listener.Reset(new CTSE_Default_Assigner);
249 m_Split->x_TSEAttach(*this, listener);
250 }
251 return *this;
252 }
253
254
Assign(const CTSE_Lock & tse,CRef<CSeq_entry> entry)255 CTSE_Info& CTSE_Info::Assign(const CTSE_Lock& tse,
256 CRef<CSeq_entry> entry)
257 // CRef<ITSE_Assigner> listener)
258 {
259 m_BlobState = tse->m_BlobState;
260 m_TopLevelObjectType = tse->m_TopLevelObjectType;
261 m_Name = tse->m_Name;
262 m_UsedMemory = tse->m_UsedMemory;
263
264 if (entry)
265 SetSeq_entry(*entry);
266
267 m_Split = tse->m_Split;
268 if (m_Split) {
269 CRef<ITSE_Assigner> listener = m_Split->GetAssigner(*tse);
270 if( !listener )
271 listener.Reset(new CTSE_Default_Assigner);
272 m_Split->x_TSEAttach(*this, listener);
273 /*
274 if( !listener ) {
275 listener = m_Split->GetAssigner(*tse);
276 if( !listener ) {
277 listener.Reset(new CTSE_Default_Assigner);
278 }
279 }
280 m_Split->x_TSEAttach(*this, listener);
281 */
282 }
283
284 //x_TSEAttach(*this);
285 return *this;
286 }
287
288
x_Initialize(void)289 void CTSE_Info::x_Initialize(void)
290 {
291 m_DataSource = 0;
292 m_BlobVersion = -1;
293 m_BlobState = CBioseq_Handle::fState_none;
294 m_TopLevelObjectType = CTSE_Handle::eTopLevel_Seq_entry;
295 m_UsedMemory = 0;
296 m_LoadState = eNotLoaded;
297 m_CacheState = eNotInCache;
298 m_AnnotIdsFlags = 0;
299 }
300
301
x_Reset(void)302 void CTSE_Info::x_Reset(void)
303 {
304 m_Bioseq_sets.clear();
305 m_Bioseqs.clear();
306 m_Removed_Bioseq_sets.clear();
307 m_Removed_Bioseqs.clear();
308 m_Split.Reset();
309 m_SetObjectInfo.Reset();
310 m_NamedAnnotObjs.clear();
311 m_IdAnnotInfoMap.clear();
312 m_FeatIdIndex.clear();
313 m_BaseTSE.reset();
314 m_EditSaver.Reset();
315 m_InternalBioObjNumber = 0;
316 m_BioObjects.clear();
317
318 m_Object.Reset();
319 m_Which = CSeq_entry::e_not_set;
320 m_Contents.Reset();
321 }
322
323
SetBlobVersion(TBlobVersion version)324 void CTSE_Info::SetBlobVersion(TBlobVersion version)
325 {
326 _ASSERT(version >= 0);
327 _ASSERT(m_LoadState == eNotLoaded || !m_Object ||
328 m_BlobVersion < 0 || m_BlobVersion == version);
329 m_BlobVersion = version;
330 }
331
332
SetName(const CAnnotName & name)333 void CTSE_Info::SetName(const CAnnotName& name)
334 {
335 m_Name = name;
336 }
337
338
SetUsedMemory(size_t size)339 void CTSE_Info::SetUsedMemory(size_t size)
340 {
341 m_UsedMemory = size;
342 }
343
344
AddUsedMemory(size_t size)345 void CTSE_Info::AddUsedMemory(size_t size)
346 {
347 m_UsedMemory += size;
348 }
349
350
SetSeq_entry(CSeq_entry & entry,CTSE_SetObjectInfo * set_info)351 void CTSE_Info::SetSeq_entry(CSeq_entry& entry, CTSE_SetObjectInfo* set_info)
352 {
353 if ( m_Which != CSeq_entry::e_not_set ) {
354 if ( m_LoadState == eNotLoaded ) {
355 Reset();
356 m_Object.Reset();
357 m_Split.Reset();
358 m_RequestedId.Reset();
359 m_Removed_Bioseq_sets.clear();
360 m_Removed_Bioseqs.clear();
361 m_AnnotIdsFlags = 0;
362 }
363 }
364
365 entry.Parentize();
366
367 m_SetObjectInfo = set_info;
368 if ( HasDataSource() ) {
369 {{
370 CDataSource::TMainLock::TWriteLockGuard guard
371 (GetDataSource().m_DSMainLock);
372 x_SetObject(entry);
373 }}
374 UpdateAnnotIndex();
375 }
376 else {
377 x_SetObject(entry);
378 }
379 if ( set_info ) {
380 if ( !set_info->m_Seq_annot_InfoMap.empty() ) {
381 NCBI_THROW(CObjMgrException, eAddDataError,
382 "Unknown SNP annots");
383 }
384 m_SetObjectInfo = null;
385 }
386 }
387
388
x_IndexBioseq(CBioseq_Info * info)389 CBioObjectId CTSE_Info::x_IndexBioseq(CBioseq_Info* info)
390 {
391 // x_RegisterRemovedIds(bioseq,info);
392 CBioObjectId uniq_id;
393 _ASSERT(info->GetBioObjectId().GetType() == CBioObjectId::eUnSet);
394 ITERATE ( CBioseq_Info::TId, it, info->GetId() ) {
395 if ( it->IsGi() ) {
396 uniq_id = CBioObjectId(*it);
397 break;
398 }
399 }
400 if ( !info->GetId().empty() ) {
401 x_SetBioseqIds(info);
402 }
403 if (uniq_id.GetType() == CBioObjectId::eUnSet) {
404 if (!info->GetId().empty())
405 uniq_id = CBioObjectId(*info->GetId().begin());
406 else
407 uniq_id = x_RegisterBioObject(*info);
408 }
409 return uniq_id;
410 }
x_IndexBioseq_set(CBioseq_set_Info * info)411 CBioObjectId CTSE_Info::x_IndexBioseq_set(CBioseq_set_Info* info)
412 {
413 CBioObjectId uniq_id;
414 _ASSERT(info->GetBioObjectId().GetType() == CBioObjectId::eUnSet);
415 if (info->m_Bioseq_set_Id > 0)
416 uniq_id = CBioObjectId(CBioObjectId::eSetId, info->m_Bioseq_set_Id);
417 else
418 uniq_id = x_RegisterBioObject(*info);
419 return uniq_id;
420 }
421
x_RegisterBioObject(CTSE_Info_Object & info)422 CBioObjectId CTSE_Info::x_RegisterBioObject(CTSE_Info_Object& info)
423 {
424 CBioObjectId uniq_id = info.GetBioObjectId();
425 if (uniq_id.GetType() == CBioObjectId::eUniqNumber) {
426 if (m_BioObjects.find(uniq_id) != m_BioObjects.end())
427 return uniq_id;
428 }
429
430 uniq_id = CBioObjectId(CBioObjectId::eUniqNumber,
431 ++m_InternalBioObjNumber);
432 m_BioObjects[uniq_id] = &info;
433 return uniq_id;
434 }
435
x_UnregisterBioObject(CTSE_Info_Object & info)436 void CTSE_Info::x_UnregisterBioObject(CTSE_Info_Object& info)
437 {
438 const CBioObjectId& uid = info.GetBioObjectId();
439 if (uid.GetType() == CBioObjectId::eUniqNumber) {
440 TBioObjects::iterator i = m_BioObjects.find(uid);
441 if (i != m_BioObjects.end()) {
442 // i->second->x_SetBioObjectId(CBioObjectId());
443 m_BioObjects.erase(i);
444 }
445 }
446 }
447
x_FindBioObject(const CBioObjectId & uniq_id) const448 CTSE_Info_Object* CTSE_Info::x_FindBioObject(const CBioObjectId& uniq_id) const
449 {
450 switch (uniq_id.GetType()) {
451 case CBioObjectId::eUniqNumber:
452 {
453 TBioObjects::const_iterator i = m_BioObjects.find(uniq_id);
454 if (i != m_BioObjects.end())
455 return i->second;
456 }
457 return NULL;
458 case CBioObjectId::eSeqId:
459 {
460 x_GetRecords(uniq_id.GetSeqId(), true);
461 CFastMutexGuard guard(m_BioseqsMutex);
462 TBioseqs::const_iterator it = m_Bioseqs.find(uniq_id.GetSeqId());
463 if ( it != m_Bioseqs.end() ) {
464 return it->second;
465 }
466 }
467 return NULL;
468 case CBioObjectId::eSetId:
469 {
470 TBioseq_sets::const_iterator it =
471 m_Bioseq_sets.find(uniq_id.GetSetId());
472 if ( it != m_Bioseq_sets.end() ) {
473 return it->second;
474 }
475 }
476 return NULL;
477 default:
478 _ASSERT(0);
479 }
480 return NULL;
481 }
482
483 /*
484 void CTSE_Info::x_RegisterRemovedIds(const CConstRef<CBioseq>& bioseq,
485 CBioseq_Info* info)
486 {
487 if (m_SetObjectInfo) {
488 CTSE_SetObjectInfo::TBioseq_InfoMap::iterator iter =
489 m_SetObjectInfo->m_Bioseq_InfoMap.find(bioseq);
490 if ( iter != m_SetObjectInfo->m_Bioseq_InfoMap.end() ) {
491 vector<CSeq_id_Handle>& ids = iter->second.m_Removed_ids;
492 for( vector<CSeq_id_Handle>::const_iterator idit = ids.begin();
493 idit != ids.end(); ++idit) {
494 _ASSERT( m_Removed_Bioseqs.find(*idit) == m_Removed_Bioseqs.end());
495 m_Removed_Bioseqs.insert(TBioseqs::value_type(*idit, info));
496 }
497 }
498 }
499 }
500 */
501 CRef<CSeq_annot_SNP_Info>
x_GetSNP_Info(const CConstRef<CSeq_annot> & annot)502 CTSE_Info::x_GetSNP_Info(const CConstRef<CSeq_annot>& annot)
503 {
504 CRef<CSeq_annot_SNP_Info> ret;
505 if ( m_SetObjectInfo ) {
506 CTSE_SetObjectInfo::TSeq_annot_InfoMap::iterator iter =
507 m_SetObjectInfo->m_Seq_annot_InfoMap.find(annot);
508 if ( iter != m_SetObjectInfo->m_Seq_annot_InfoMap.end() ) {
509 ret = iter->second.m_SNP_annot_Info;
510 m_SetObjectInfo->m_Seq_annot_InfoMap.erase(iter);
511 }
512 }
513 return ret;
514 }
515
516
HasAnnot(const CAnnotName & name) const517 bool CTSE_Info::HasAnnot(const CAnnotName& name) const
518 {
519 TAnnotLockReadGuard guard(GetAnnotLock());
520 return m_NamedAnnotObjs.find(name) != m_NamedAnnotObjs.end();
521 }
522
523
HasNamedAnnot(const string & name) const524 bool CTSE_Info::HasNamedAnnot(const string& name) const
525 {
526 return HasAnnot(CAnnotName(name));
527 }
528
529
HasUnnamedAnnot(void) const530 bool CTSE_Info::HasUnnamedAnnot(void) const
531 {
532 return HasAnnot(CAnnotName());
533 }
534
535
GetCompleteTSE(void) const536 CConstRef<CSeq_entry> CTSE_Info::GetCompleteTSE(void) const
537 {
538 return GetCompleteSeq_entry();
539 }
540
541
GetTSECore(void) const542 CConstRef<CSeq_entry> CTSE_Info::GetTSECore(void) const
543 {
544 return GetSeq_entryCore();
545 }
546
547
x_DSAttachContents(CDataSource & ds)548 void CTSE_Info::x_DSAttachContents(CDataSource& ds)
549 {
550 _ASSERT(!m_DataSource);
551
552 m_DataSource = &ds;
553 TParent::x_DSAttachContents(ds);
554 if ( m_Split ) {
555 m_Split->x_DSAttach(ds);
556 }
557 ITERATE ( TBioseqs, it, m_Bioseqs ) {
558 ds.x_IndexSeqTSE(it->first, this);
559 }
560 ds.x_IndexAnnotTSEs(this);
561 }
562
563
x_DSDetachContents(CDataSource & ds)564 void CTSE_Info::x_DSDetachContents(CDataSource& ds)
565 {
566 _ASSERT(m_DataSource == &ds);
567
568 ITERATE ( TBioseqs, it, m_Bioseqs ) {
569 ds.x_UnindexSeqTSE(it->first, this);
570 }
571 ds.x_UnindexAnnotTSEs(this);
572 if ( m_Split ) {
573 m_Split->x_DSDetach(ds);
574 }
575 TParent::x_DSDetachContents(ds);
576 m_DataSource = 0;
577 }
578
579
x_DSMapObject(CConstRef<TObject> obj,CDataSource & ds)580 void CTSE_Info::x_DSMapObject(CConstRef<TObject> obj, CDataSource& ds)
581 {
582 ds.x_Map(obj, this);
583 TParent::x_DSMapObject(obj, ds);
584 }
585
586
x_DSUnmapObject(CConstRef<TObject> obj,CDataSource & ds)587 void CTSE_Info::x_DSUnmapObject(CConstRef<TObject> obj, CDataSource& ds)
588 {
589 ds.x_Unmap(obj, this);
590 TParent::x_DSUnmapObject(obj, ds);
591 }
592
593
594 inline
x_IndexSeqTSE(const CSeq_id_Handle & id)595 void CTSE_Info::x_IndexSeqTSE(const CSeq_id_Handle& id)
596 {
597 if ( HasDataSource() ) {
598 GetDataSource().x_IndexSeqTSE(id, this);
599 }
600 }
601
602
603 inline
x_UnindexSeqTSE(const CSeq_id_Handle & id)604 void CTSE_Info::x_UnindexSeqTSE(const CSeq_id_Handle& id)
605 {
606 if ( HasDataSource() ) {
607 GetDataSource().x_UnindexSeqTSE(id, this);
608 }
609 }
610
611
x_IndexAnnotTSE(const CAnnotName & name,const CSeq_id_Handle & id)612 bool CTSE_Info::x_IndexAnnotTSE(const CAnnotName& name,
613 const CSeq_id_Handle& id)
614 {
615 if ( !id.IsGi() ) {
616 m_AnnotIdsFlags |= fAnnotIds_NonGi;
617 if ( id.HaveMatchingHandles() ) {
618 m_AnnotIdsFlags |= fAnnotIds_Matching;
619 }
620 }
621 bool new_id = false;
622 TIdAnnotInfoMap::iterator iter = m_IdAnnotInfoMap.lower_bound(id);
623 if ( iter == m_IdAnnotInfoMap.end() || iter->first != id ) {
624 iter = m_IdAnnotInfoMap
625 .insert(iter, TIdAnnotInfoMap::value_type(id, SIdAnnotInfo()));
626 new_id = true;
627 bool orphan = !ContainsMatchingBioseq(id);
628 iter->second.m_Orphan = orphan;
629 if ( HasDataSource() ) {
630 GetDataSource().x_IndexAnnotTSE(id, this, orphan);
631 }
632 }
633 _VERIFY(iter->second.m_Names.insert(name).second);
634 return new_id;
635 }
636
637
x_UnindexAnnotTSE(const CAnnotName & name,const CSeq_id_Handle & id)638 void CTSE_Info::x_UnindexAnnotTSE(const CAnnotName& name,
639 const CSeq_id_Handle& id)
640 {
641 TIdAnnotInfoMap::iterator iter = m_IdAnnotInfoMap.lower_bound(id);
642 if ( iter == m_IdAnnotInfoMap.end() || iter->first != id ) {
643 return;
644 }
645 _VERIFY(iter->second.m_Names.erase(name) == 1);
646 if ( iter->second.m_Names.empty() ) {
647 bool orphan = iter->second.m_Orphan;
648 m_IdAnnotInfoMap.erase(iter);
649 if ( HasDataSource() ) {
650 GetDataSource().x_UnindexAnnotTSE(id, this, orphan);
651 }
652 }
653 }
654
655
x_DoUpdate(TNeedUpdateFlags flags)656 void CTSE_Info::x_DoUpdate(TNeedUpdateFlags flags)
657 {
658 if ( flags & (fNeedUpdate_core|fNeedUpdate_children_core) ) {
659 if ( m_Split ) {
660 m_Split->x_UpdateCore();
661 }
662 }
663 TParent::x_DoUpdate(flags);
664 }
665
666
667 namespace {
x_SortUnique(CTSE_Info::TSeqIds & ids)668 static inline void x_SortUnique(CTSE_Info::TSeqIds& ids)
669 {
670 sort(ids.begin(), ids.end());
671 ids.erase(unique(ids.begin(), ids.end()), ids.end());
672 }
673 }
674
675
GetBioseqsIds(TSeqIds & ids) const676 void CTSE_Info::GetBioseqsIds(TSeqIds& ids) const
677 {
678
679 {{
680 CFastMutexGuard guard(m_BioseqsMutex);
681 ITERATE ( TBioseqs, it, m_Bioseqs ) {
682 ids.push_back(it->first);
683 }
684 }}
685 if ( m_Split ) {
686 m_Split->GetBioseqsIds(ids);
687 // after adding split bioseq Seq-ids the result may contain
688 // duplicates and need to be sorted
689 x_SortUnique(ids);
690 }
691 }
692
693
GetAnnotIds(TSeqIds & ids) const694 void CTSE_Info::GetAnnotIds(TSeqIds& ids) const
695 {
696 UpdateAnnotIndex();
697 {{
698 TAnnotLockReadGuard guard(GetAnnotLock());
699 ITERATE ( TNamedAnnotObjs, it, m_NamedAnnotObjs ) {
700 ITERATE ( TAnnotObjs, it2, it->second ) {
701 ids.push_back(it2->first);
702 }
703 }
704 }}
705 x_SortUnique(ids);
706 }
707
708
ContainsBioseq(const CSeq_id_Handle & id) const709 bool CTSE_Info::ContainsBioseq(const CSeq_id_Handle& id) const
710 {
711 {{
712 CFastMutexGuard guard(m_BioseqsMutex);
713 if ( m_Bioseqs.find(id) != m_Bioseqs.end() ) {
714 return true;
715 }
716 }}
717 if ( m_Split ) {
718 return m_Split->ContainsBioseq(id);
719 }
720 return false;
721 }
722
723
724 CSeq_id_Handle
ContainsMatchingBioseq(const CSeq_id_Handle & id) const725 CTSE_Info::ContainsMatchingBioseq(const CSeq_id_Handle& id) const
726 {
727 if ( ContainsBioseq(id) ) {
728 return id;
729 }
730 else if ( id.HaveMatchingHandles() ) {
731 CSeq_id_Handle::TMatches ids;
732 id.GetMatchingHandles(ids, eAllowWeakMatch);
733 ITERATE ( CSeq_id_Handle::TMatches, match_it, ids ) {
734 if ( *match_it != id ) {
735 if ( ContainsBioseq(*match_it) ) {
736 return *match_it;
737 }
738 }
739 }
740 }
741 return null;
742 }
743
744
FindBioseq(const CSeq_id_Handle & id) const745 CConstRef<CBioseq_Info> CTSE_Info::FindBioseq(const CSeq_id_Handle& id) const
746 {
747 CConstRef<CBioseq_Info> ret;
748 x_GetRecords(id, true);
749 {{
750 CFastMutexGuard guard(m_BioseqsMutex);
751 TBioseqs::const_iterator it = m_Bioseqs.find(id);
752 if ( it != m_Bioseqs.end() ) {
753 ret = it->second;
754 }
755 }}
756 return ret;
757 }
758
759
760 CConstRef<CBioseq_Info>
FindMatchingBioseq(const CSeq_id_Handle & id) const761 CTSE_Info::FindMatchingBioseq(const CSeq_id_Handle& id) const
762 {
763 return GetSeqMatch(id).m_Bioseq;
764 }
765
766
767 CConstRef<CBioseq_Info>
GetSegSetMaster(void) const768 CTSE_Info::GetSegSetMaster(void) const
769 {
770 for ( CConstRef<CSeq_entry_Info> entry(this); entry->IsSet(); ) {
771 const CBioseq_set_Info& seqset = entry->GetSet();
772 CConstRef<CSeq_entry_Info> first = seqset.GetFirstEntry();
773 if ( !first ) {
774 break;
775 }
776 if ( seqset.GetClass() == CBioseq_set::eClass_segset ) {
777 if ( first->IsSeq() ) {
778 return ConstRef(&first->GetSeq());
779 }
780 break;
781 }
782 entry = first;
783 }
784 return null;
785 }
786
787
GetMasterSeqSegments(void) const788 CConstRef<CMasterSeqSegments> CTSE_Info::GetMasterSeqSegments(void) const
789 {
790 if ( !m_MasterSeqSegmentsLoaded ) {
791 TAnnotLockWriteGuard guard(m_AnnotLock);
792 if ( !m_MasterSeqSegmentsLoaded ) {
793 CConstRef<CBioseq_Info> master_seq = GetSegSetMaster();
794 if ( master_seq ) {
795 try {
796 m_MasterSeqSegments = new CMasterSeqSegments(*master_seq);
797 }
798 catch ( CException& exc ) {
799 ERR_POST("Segment set cannot be initialized: "<<exc);
800 }
801 }
802 m_MasterSeqSegmentsLoaded = true;
803 }
804 }
805 return m_MasterSeqSegments;
806 }
807
808
GetSeqMatch(const CSeq_id_Handle & id) const809 SSeqMatch_TSE CTSE_Info::GetSeqMatch(const CSeq_id_Handle& id) const
810 {
811 SSeqMatch_TSE ret;
812 ret.m_Bioseq = FindBioseq(id);
813 if ( ret.m_Bioseq ) {
814 ret.m_Seq_id = id;
815 }
816 else if ( id.HaveMatchingHandles() ) {
817 CSeq_id_Handle::TMatches ids;
818 id.GetMatchingHandles(ids, eAllowWeakMatch);
819 ITERATE ( CSeq_id_Handle::TMatches, match_it, ids ) {
820 if ( *match_it != id ) {
821 ret.m_Bioseq = FindBioseq(*match_it);
822 if ( ret.m_Bioseq ) {
823 ret.m_Seq_id = *match_it;
824 break;
825 }
826 }
827 }
828 }
829 return ret;
830 }
831
832
x_GetRecords(const CSeq_id_Handle & id,bool bioseq) const833 void CTSE_Info::x_GetRecords(const CSeq_id_Handle& id, bool bioseq) const
834 {
835 if ( m_Split ) {
836 m_Split->x_GetRecords(id, bioseq);
837 }
838 }
839
840
x_LoadChunk(TChunkId chunk_id) const841 void CTSE_Info::x_LoadChunk(TChunkId chunk_id) const
842 {
843 m_Split->x_LoadChunk(chunk_id);
844 }
845
846
x_LoadChunks(const TChunkIds & chunk_ids) const847 void CTSE_Info::x_LoadChunks(const TChunkIds& chunk_ids) const
848 {
849 if ( !chunk_ids.empty() ) {
850 m_Split->x_LoadChunks(chunk_ids);
851 }
852 }
853
854
x_SetBioseqId(const CSeq_id_Handle & id,CBioseq_Info * info)855 void CTSE_Info::x_SetBioseqId(const CSeq_id_Handle& id,
856 CBioseq_Info* info)
857 {
858 _ASSERT(info);
859 {{
860 CFastMutexGuard guard(m_BioseqsMutex);
861 pair<TBioseqs::iterator, bool> ins =
862 m_Bioseqs.insert(TBioseqs::value_type(id, info));
863 if ( !ins.second ) {
864 // No duplicate bioseqs in the same TSE
865 NCBI_THROW_FMT(CObjMgrException, eAddDataError,
866 "duplicate Bioseq id " << id << " present in" <<
867 "\n seq1: " << ins.first->second->IdString() <<
868 "\n seq2: " << info->IdString());
869 }
870 }}
871 // register this TSE in data source as containing the sequence
872 x_IndexSeqTSE(id);
873 }
874
875
x_SetBioseqIds(CBioseq_Info * info)876 void CTSE_Info::x_SetBioseqIds(CBioseq_Info* info)
877 {
878 _ASSERT(info);
879 {{
880 CFastMutexGuard guard(m_BioseqsMutex);
881 ITERATE ( CBioseq_Info::TId, it, info->GetId() ) {
882 pair<TBioseqs::iterator, bool> ins =
883 m_Bioseqs.insert(TBioseqs::value_type(*it, info));
884 if ( !ins.second ) {
885 // No duplicate bioseqs in the same TSE
886 NCBI_THROW(CObjMgrException, eAddDataError,
887 "duplicate Bioseq id "+it->AsString()+" present in"+
888 "\n seq1: " + ins.first->second->IdString()+
889 "\n seq2: " + info->IdString());
890 }
891 }
892 if ( m_BioseqUpdater ) {
893 m_BioseqUpdater->Update(*info);
894 }
895 }}
896 // register this TSE in data source as containing the sequence
897 if ( HasDataSource() ) {
898 GetDataSource().x_IndexSeqTSE(info->GetId(), this);
899 }
900 }
901
902
x_ResetBioseqId(const CSeq_id_Handle & id,CBioseq_Info * info)903 void CTSE_Info::x_ResetBioseqId(const CSeq_id_Handle& id,
904 CBioseq_Info* info)
905 {
906 {{
907 CFastMutexGuard guard(m_BioseqsMutex);
908 TBioseqs::iterator iter = m_Bioseqs.lower_bound(id);
909 if ( iter == m_Bioseqs.end() || iter->first != id ) {
910 return;
911 }
912 _ASSERT(iter->second == info);
913 m_Bioseqs.erase(iter);
914
915 if (m_Split) {
916 iter = m_Removed_Bioseqs.find(id);
917 if (iter == m_Removed_Bioseqs.end())
918 m_Removed_Bioseqs.insert(TBioseqs::value_type(id, info));
919 }
920
921 }}
922 x_UnindexSeqTSE(id);
923 }
924
925
x_SetBioseq_setId(int key,CBioseq_set_Info * info)926 void CTSE_Info::x_SetBioseq_setId(int key,
927 CBioseq_set_Info* info)
928 {
929 pair<TBioseq_sets::iterator, bool> ins =
930 m_Bioseq_sets.insert(TBioseq_sets::value_type(key, info));
931 if ( ins.second ) {
932 // everything is fine
933 }
934 else {
935 // No duplicate bioseqs in the same TSE
936 NCBI_THROW(CObjMgrException, eAddDataError,
937 " duplicate Bioseq_set id '"+NStr::IntToString(key));
938 }
939 }
940
941
x_ResetBioseq_setId(int key,CBioseq_set_Info * info)942 void CTSE_Info::x_ResetBioseq_setId(int key,
943 CBioseq_set_Info* info)
944 {
945 TBioseq_sets::iterator iter = m_Bioseq_sets.lower_bound(key);
946 if ( iter != m_Bioseq_sets.end() && iter->first == key ) {
947 _ASSERT(iter->second == info);
948 m_Bioseq_sets.erase(iter);
949 if (m_Split) {
950 iter = m_Removed_Bioseq_sets.find(key);
951 if (iter == m_Removed_Bioseq_sets.end())
952 m_Removed_Bioseq_sets.insert(TBioseq_sets::value_type(key, info));
953 }
954 }
955 }
956
957
x_SetDirtyAnnotIndexNoParent(void)958 void CTSE_Info::x_SetDirtyAnnotIndexNoParent(void)
959 {
960 if ( HasDataSource() ) {
961 GetDataSource().x_SetDirtyAnnotIndex(*this);
962 }
963 }
964
965
x_ResetDirtyAnnotIndexNoParent(void)966 void CTSE_Info::x_ResetDirtyAnnotIndexNoParent(void)
967 {
968 if ( HasDataSource() ) {
969 GetDataSource().x_ResetDirtyAnnotIndex(*this);
970 }
971 }
972
973
UpdateFeatIdIndex(CSeqFeatData::E_Choice type,EFeatIdType id_type) const974 void CTSE_Info::UpdateFeatIdIndex(CSeqFeatData::E_Choice type,
975 EFeatIdType id_type) const
976 {
977 if ( m_Split ) {
978 m_Split.GetNCObject().x_UpdateFeatIdIndex(type, id_type);
979 }
980 UpdateAnnotIndex();
981 }
982
983
UpdateFeatIdIndex(CSeqFeatData::ESubtype subtype,EFeatIdType id_type) const984 void CTSE_Info::UpdateFeatIdIndex(CSeqFeatData::ESubtype subtype,
985 EFeatIdType id_type) const
986 {
987 if ( m_Split ) {
988 m_Split.GetNCObject().x_UpdateFeatIdIndex(subtype, id_type);
989 }
990 UpdateAnnotIndex();
991 }
992
993
UpdateAnnotIndex(const CSeq_id_Handle & id) const994 void CTSE_Info::UpdateAnnotIndex(const CSeq_id_Handle& id) const
995 {
996 x_GetRecords(id, false);
997 const_cast<CTSE_Info*>(this)->UpdateAnnotIndex();
998 }
999
1000
UpdateAnnotIndex(void) const1001 void CTSE_Info::UpdateAnnotIndex(void) const
1002 {
1003 const_cast<CTSE_Info*>(this)->UpdateAnnotIndex();
1004 }
1005
1006
UpdateAnnotIndex(const CTSE_Info_Object & object) const1007 void CTSE_Info::UpdateAnnotIndex(const CTSE_Info_Object& object) const
1008 {
1009 const_cast<CTSE_Info*>(this)->
1010 UpdateAnnotIndex(const_cast<CTSE_Info_Object&>(object));
1011 }
1012
1013
UpdateAnnotIndex(void)1014 void CTSE_Info::UpdateAnnotIndex(void)
1015 {
1016 UpdateAnnotIndex(*this);
1017 }
1018
1019
UpdateAnnotIndex(CTSE_Info_Object & object)1020 void CTSE_Info::UpdateAnnotIndex(CTSE_Info_Object& object)
1021 {
1022 _ASSERT(&object.GetTSE_Info() == this);
1023 if ( object.x_DirtyAnnotIndex() ) {
1024 CDataSource::TAnnotLockWriteGuard guard(eEmptyGuard);
1025 if (HasDataSource())
1026 guard.Guard(GetDataSource());
1027 TAnnotLockWriteGuard guard2(GetAnnotLock());
1028 //CStopWatch sw(CStopWatch::eStart);
1029 object.x_UpdateAnnotIndex(*this);
1030 _ASSERT(!object.x_DirtyAnnotIndex());
1031 //LOG_POST(Info<<"Updated annot index in "<<sw.Elapsed());
1032 }
1033 }
1034
1035 /*
1036 void CTSE_Info::UpdateAnnotIndex(CTSE_Chunk_Info& chunk)
1037 {
1038 CDataSource::TAnnotLockWriteGuard guard(GetDataSource());
1039 TAnnotLockWriteGuard guard2(GetAnnotLock());
1040 chunk.x_UpdateAnnotIndex(*this);
1041 }
1042 */
1043
x_UpdateAnnotIndexContents(CTSE_Info & tse)1044 void CTSE_Info::x_UpdateAnnotIndexContents(CTSE_Info& tse)
1045 {
1046 _ASSERT(this == &tse);
1047 if ( m_Split ) {
1048 m_Split->x_UpdateAnnotIndex();
1049 }
1050 TParent::x_UpdateAnnotIndexContents(tse);
1051 }
1052
1053
x_SetAnnotObjs(const CAnnotName & name)1054 CTSE_Info::TAnnotObjs& CTSE_Info::x_SetAnnotObjs(const CAnnotName& name)
1055 {
1056 TNamedAnnotObjs::iterator iter = m_NamedAnnotObjs.lower_bound(name);
1057 if ( iter == m_NamedAnnotObjs.end() || iter->first != name ) {
1058 typedef TNamedAnnotObjs::value_type value_type;
1059 iter = m_NamedAnnotObjs.insert(iter, value_type(name, TAnnotObjs()));
1060 }
1061 return iter->second;
1062 }
1063
1064
x_RemoveAnnotObjs(const CAnnotName & name)1065 void CTSE_Info::x_RemoveAnnotObjs(const CAnnotName& name)
1066 {
1067 m_NamedAnnotObjs.erase(name);
1068 }
1069
1070
1071 const CTSE_Info::TAnnotObjs*
x_GetAnnotObjs(const CAnnotName & name) const1072 CTSE_Info::x_GetAnnotObjs(const CAnnotName& name) const
1073 {
1074 TNamedAnnotObjs::const_iterator iter = m_NamedAnnotObjs.lower_bound(name);
1075 if ( iter == m_NamedAnnotObjs.end() || iter->first != name ) {
1076 return 0;
1077 }
1078 return &iter->second;
1079 }
1080
1081
1082 const CTSE_Info::TAnnotObjs*
x_GetUnnamedAnnotObjs(void) const1083 CTSE_Info::x_GetUnnamedAnnotObjs(void) const
1084 {
1085 TNamedAnnotObjs::const_iterator iter = m_NamedAnnotObjs.begin();
1086 if ( iter == m_NamedAnnotObjs.end() || iter->first.IsNamed() ) {
1087 return 0;
1088 }
1089 return &iter->second;
1090 }
1091
1092
1093 pair<SIdAnnotObjs*, bool>
x_SetIdObjects(TAnnotObjs & objs,const CAnnotName & name,const CSeq_id_Handle & id)1094 CTSE_Info::x_SetIdObjects(TAnnotObjs& objs,
1095 const CAnnotName& name,
1096 const CSeq_id_Handle& id)
1097 {
1098 // repeat for more generic types of selector
1099 bool new_id = false;
1100 TAnnotObjs::iterator it = objs.find(id);
1101 if ( it == objs.end() ) {
1102 // new id
1103 it = objs.insert(TAnnotObjs::value_type(id, SIdAnnotObjs())).first;
1104 new_id = x_IndexAnnotTSE(name, id);
1105 }
1106 _ASSERT(it != objs.end() && it->first == id);
1107 return make_pair(&it->second, new_id);
1108 }
1109
1110
1111 pair<SIdAnnotObjs*, bool>
x_SetIdObjects(const CAnnotName & name,const CSeq_id_Handle & id)1112 CTSE_Info::x_SetIdObjects(const CAnnotName& name,
1113 const CSeq_id_Handle& id)
1114 {
1115 return x_SetIdObjects(x_SetAnnotObjs(name), name, id);
1116 }
1117
1118
x_GetIdObjects(const TAnnotObjs & objs,const CSeq_id_Handle & idh) const1119 const SIdAnnotObjs* CTSE_Info::x_GetIdObjects(const TAnnotObjs& objs,
1120 const CSeq_id_Handle& idh) const
1121 {
1122 TAnnotObjs::const_iterator it = objs.find(idh);
1123 if ( it == objs.end() ) {
1124 return 0;
1125 }
1126 return &it->second;
1127 }
1128
1129
x_GetIdObjects(const CAnnotName & name,const CSeq_id_Handle & idh) const1130 const SIdAnnotObjs* CTSE_Info::x_GetIdObjects(const CAnnotName& name,
1131 const CSeq_id_Handle& idh) const
1132 {
1133 const TAnnotObjs* objs = x_GetAnnotObjs(name);
1134 if ( !objs ) {
1135 return 0;
1136 }
1137 return x_GetIdObjects(*objs, idh);
1138 }
1139
1140
1141 const SIdAnnotObjs*
x_GetUnnamedIdObjects(const CSeq_id_Handle & idh) const1142 CTSE_Info::x_GetUnnamedIdObjects(const CSeq_id_Handle& idh) const
1143 {
1144 const TAnnotObjs* objs = x_GetUnnamedAnnotObjs();
1145 if ( !objs ) {
1146 return 0;
1147 }
1148 return x_GetIdObjects(*objs, idh);
1149 }
1150
1151
x_HasIdObjects(const CSeq_id_Handle & idh) const1152 bool CTSE_Info::x_HasIdObjects(const CSeq_id_Handle& idh) const
1153 {
1154 // tse annot index should be locked by TAnnotLockReadGuard
1155 ITERATE ( TNamedAnnotObjs, it, m_NamedAnnotObjs ) {
1156 if ( x_GetIdObjects(it->second, idh) ) {
1157 return true;
1158 }
1159 }
1160 return false;
1161 }
1162
1163
1164 inline
x_MapAnnotObject(TRangeMap & rangeMap,const SAnnotObject_Key & key,const SAnnotObject_Index & index)1165 void CTSE_Info::x_MapAnnotObject(TRangeMap& rangeMap,
1166 const SAnnotObject_Key& key,
1167 const SAnnotObject_Index& index)
1168 {
1169 //_ASSERT(index.m_AnnotObject_Info == key.m_AnnotObject_Info);
1170 rangeMap.insert(TRangeMap::value_type(key.m_Range, index));
1171 }
1172
1173
1174 inline
x_UnmapAnnotObject(TRangeMap & rangeMap,const CAnnotObject_Info & info,const SAnnotObject_Key & key)1175 bool CTSE_Info::x_UnmapAnnotObject(TRangeMap& rangeMap,
1176 const CAnnotObject_Info& info,
1177 const SAnnotObject_Key& key)
1178 {
1179 for ( TRangeMap::iterator it = rangeMap.find(key.m_Range);
1180 it && it->first == key.m_Range; ++it ) {
1181 if ( it->second.m_AnnotObject_Info == &info ) {
1182 rangeMap.erase(it);
1183 return rangeMap.empty();
1184 }
1185 }
1186 _ASSERT(0);
1187 return rangeMap.empty();
1188 }
1189
1190
x_MapAnnotObject(SIdAnnotObjs & objs,const SAnnotObject_Key & key,const SAnnotObject_Index & index)1191 void CTSE_Info::x_MapAnnotObject(SIdAnnotObjs& objs,
1192 const SAnnotObject_Key& key,
1193 const SAnnotObject_Index& index)
1194 {
1195 if ( index.m_AnnotObject_Info->IsLocs() ) {
1196 // Locs may contain multiple indexes
1197 CAnnotObject_Info::TTypeIndexSet idx_set;
1198 index.m_AnnotObject_Info->GetLocsTypes(idx_set);
1199 ITERATE(CAnnotObject_Info::TTypeIndexSet, idx_rg, idx_set) {
1200 for (size_t idx = idx_rg->first; idx < idx_rg->second; ++idx) {
1201 x_MapAnnotObject(objs.x_GetRangeMap(idx), key, index);
1202 }
1203 }
1204 }
1205 else {
1206 CAnnotType_Index::TIndexRange idx_rg =
1207 CAnnotType_Index::GetTypeIndex(*index.m_AnnotObject_Info);
1208 for (size_t idx = idx_rg.first; idx < idx_rg.second; ++idx) {
1209 x_MapAnnotObject(objs.x_GetRangeMap(idx), key, index);
1210 }
1211 }
1212 }
1213
1214
x_UnmapAnnotObject(SIdAnnotObjs & objs,const CAnnotObject_Info & info,const SAnnotObject_Key & key)1215 bool CTSE_Info::x_UnmapAnnotObject(SIdAnnotObjs& objs,
1216 const CAnnotObject_Info& info,
1217 const SAnnotObject_Key& key)
1218 {
1219 CAnnotType_Index::TIndexRange idx_rg =
1220 CAnnotType_Index::GetTypeIndex(info);
1221 for (size_t idx = idx_rg.first; idx < idx_rg.second; ++idx) {
1222 _ASSERT(idx < objs.x_GetRangeMapCount());
1223 if ( x_UnmapAnnotObject(objs.x_GetRangeMap(idx), info, key) ) {
1224 if ( objs.x_CleanRangeMaps() ) {
1225 return objs.m_SNPSet.empty();
1226 }
1227 }
1228 }
1229 return false;
1230 }
1231
1232
x_MapAnnotObject(TAnnotObjs & objs,const CAnnotName & name,const SAnnotObject_Key & key,const SAnnotObject_Index & index)1233 bool CTSE_Info::x_MapAnnotObject(TAnnotObjs& objs,
1234 const CAnnotName& name,
1235 const SAnnotObject_Key& key,
1236 const SAnnotObject_Index& index)
1237 {
1238 auto id_objs = x_SetIdObjects(objs, name, key.m_Handle);
1239 x_MapAnnotObject(*id_objs.first, key, index);
1240 return id_objs.second;
1241 }
1242
1243
x_UnmapAnnotObject(TAnnotObjs & objs,const CAnnotName & name,const CAnnotObject_Info & info,const SAnnotObject_Key & key)1244 bool CTSE_Info::x_UnmapAnnotObject(TAnnotObjs& objs,
1245 const CAnnotName& name,
1246 const CAnnotObject_Info& info,
1247 const SAnnotObject_Key& key)
1248 {
1249 TAnnotObjs::iterator it = objs.find(key.m_Handle);
1250 if ( it != objs.end() && x_UnmapAnnotObject(it->second, info, key) ) {
1251 x_UnindexAnnotTSE(name, key.m_Handle);
1252 objs.erase(it);
1253 return objs.empty();
1254 }
1255 return false;
1256 }
1257
1258
x_MapSNP_Table(const CAnnotName & name,const CSeq_id_Handle & key,const CSeq_annot_SNP_Info & snp_info)1259 bool CTSE_Info::x_MapSNP_Table(const CAnnotName& name,
1260 const CSeq_id_Handle& key,
1261 const CSeq_annot_SNP_Info& snp_info)
1262 {
1263 auto objs = x_SetIdObjects(name, key);
1264 objs.first->m_SNPSet.push_back(ConstRef(&snp_info));
1265 return objs.second;
1266 }
1267
1268
x_UnmapSNP_Table(const CAnnotName & name,const CSeq_id_Handle & key,const CSeq_annot_SNP_Info & snp_info)1269 void CTSE_Info::x_UnmapSNP_Table(const CAnnotName& name,
1270 const CSeq_id_Handle& key,
1271 const CSeq_annot_SNP_Info& snp_info)
1272 {
1273 SIdAnnotObjs& objs = *x_SetIdObjects(name, key).first;
1274 TSNPSet::iterator iter = find(objs.m_SNPSet.begin(),
1275 objs.m_SNPSet.end(),
1276 ConstRef(&snp_info));
1277 if ( iter != objs.m_SNPSet.end() ) {
1278 objs.m_SNPSet.erase(iter);
1279 }
1280 }
1281
1282
x_MapAnnotObject(const CAnnotName & name,const SAnnotObject_Key & key,const SAnnotObject_Index & index)1283 bool CTSE_Info::x_MapAnnotObject(const CAnnotName& name,
1284 const SAnnotObject_Key& key,
1285 const SAnnotObject_Index& index)
1286 {
1287 return x_MapAnnotObject(x_SetAnnotObjs(name), name, key, index);
1288 }
1289
1290
x_UnmapAnnotObject(const CAnnotName & name,const CAnnotObject_Info & info,const SAnnotObject_Key & key)1291 void CTSE_Info::x_UnmapAnnotObject(const CAnnotName& name,
1292 const CAnnotObject_Info& info,
1293 const SAnnotObject_Key& key)
1294 {
1295 TAnnotObjs& index = x_SetAnnotObjs(name);
1296
1297 x_UnmapAnnotObject(index, name, info, key);
1298
1299 if ( index.empty() ) {
1300 x_RemoveAnnotObjs(name);
1301 }
1302 }
1303
1304
x_UnmapAnnotObjects(const SAnnotObjectsIndex & infos)1305 void CTSE_Info::x_UnmapAnnotObjects(const SAnnotObjectsIndex& infos)
1306 {
1307 if ( !infos.IsIndexed() ) {
1308 return;
1309 }
1310 const CAnnotName& name = infos.GetName();
1311 TAnnotObjs& index = x_SetAnnotObjs(name);
1312
1313 ITERATE ( SAnnotObjectsIndex::TObjectInfos, it, infos.GetInfos() ) {
1314 if ( it->HasSingleKey() ) {
1315 x_UnmapAnnotObject(index, name, *it, it->GetKey());
1316 }
1317 else {
1318 for ( size_t i = it->GetKeysBegin(); i < it->GetKeysEnd(); ++i ) {
1319 x_UnmapAnnotObject(index, name, *it, infos.GetKey(i));
1320 }
1321 }
1322 }
1323
1324 if ( index.empty() ) {
1325 x_RemoveAnnotObjs(name);
1326 }
1327 }
1328
1329
x_GetBioseq_set(int id)1330 CBioseq_set_Info& CTSE_Info::x_GetBioseq_set(int id)
1331 {
1332 TBioseq_sets::iterator iter;
1333 if (m_Split) {
1334 iter = m_Removed_Bioseq_sets.find(id);
1335 if ( iter != m_Removed_Bioseq_sets.end() )
1336 return *iter->second;
1337 }
1338
1339 iter = m_Bioseq_sets.find(id);
1340 if ( iter == m_Bioseq_sets.end() ) {
1341 NCBI_THROW(CObjMgrException, eRegisterError,
1342 "cannot find Bioseq-set by local id");
1343 }
1344 return *iter->second;
1345 }
1346
1347
x_GetBioseq(const CSeq_id_Handle & id)1348 CBioseq_Info& CTSE_Info::x_GetBioseq(const CSeq_id_Handle& id)
1349 {
1350 CFastMutexGuard guard(m_BioseqsMutex);
1351 TBioseqs::iterator iter;
1352 if (m_Split) {
1353 iter = m_Removed_Bioseqs.find(id);
1354 if ( iter != m_Removed_Bioseqs.end() )
1355 return *iter->second;
1356 }
1357
1358 iter = m_Bioseqs.find(id);
1359 if ( iter == m_Bioseqs.end() ) {
1360 NCBI_THROW(CObjMgrException, eRegisterError,
1361 "cannot find Bioseq by Seq-id "+id.AsString());
1362 }
1363 return *iter->second;
1364 }
1365
1366
HasSplitInfo(void) const1367 bool CTSE_Info::HasSplitInfo(void) const
1368 {
1369 return m_Split;
1370 }
1371
1372
GetSplitInfo(void) const1373 const CTSE_Split_Info& CTSE_Info::GetSplitInfo(void) const
1374 {
1375 _ASSERT(HasSplitInfo());
1376 return *m_Split;
1377 }
1378
1379
GetSplitInfo(void)1380 CTSE_Split_Info& CTSE_Info::GetSplitInfo(void)
1381 {
1382 if ( !m_Split ) {
1383 _ASSERT(m_LoadState == eNotLoaded);
1384 m_Split = new CTSE_Split_Info(GetBlobId(), GetBlobVersion());
1385 CRef<ITSE_Assigner> listener(new CTSE_Default_Assigner);
1386 m_Split->x_TSEAttach(*this, listener);
1387 }
1388 return *m_Split;
1389 }
1390
1391
x_NeedsDelayedMainChunk(void) const1392 bool CTSE_Info::x_NeedsDelayedMainChunk(void) const
1393 {
1394 return m_Split && m_Split->x_NeedsDelayedMainChunk();
1395 }
1396
1397
x_LoadDelayedMainChunk(void) const1398 void CTSE_Info::x_LoadDelayedMainChunk(void) const
1399 {
1400 if ( m_Split ) {
1401 m_Split->x_LoadDelayedMainChunk();
1402 }
1403 }
1404
1405
x_AddFeaturesById(TAnnotObjects & objects,const SFeatIdIndex & index,TFeatIdInt id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1406 void CTSE_Info::x_AddFeaturesById(TAnnotObjects& objects,
1407 const SFeatIdIndex& index,
1408 TFeatIdInt id,
1409 EFeatIdType id_type,
1410 const CSeq_annot_Info* src_annot) const
1411 {
1412 if ( !index.m_Chunks.empty() ) {
1413 x_LoadChunks(index.m_Chunks);
1414 UpdateAnnotIndex();
1415 }
1416 if ( !index.m_IndexInt ) {
1417 return;
1418 }
1419 const CSeq_entry_Info* xref_tse = 0;
1420 if ( src_annot ) {
1421 xref_tse = &src_annot->GetXrefTSE();
1422 if ( xref_tse == this ) {
1423 xref_tse = 0;
1424 }
1425 }
1426 const SFeatIdIndex::TIndexInt& index2 = *index.m_IndexInt;
1427 for ( SFeatIdIndex::TIndexInt::const_iterator iter2 = index2.find(id);
1428 iter2 != index2.end() && iter2->first == id; ++iter2 ) {
1429 const SFeatIdInfo& info = iter2->second;
1430 if ( info.m_Type == id_type ) {
1431 if ( info.m_IsChunk ) {
1432 x_LoadChunk(info.m_ChunkId);
1433 UpdateAnnotIndex();
1434 }
1435 else {
1436 if ( xref_tse && xref_tse != &info.m_Info->GetSeq_annot_Info().GetXrefTSE() ) {
1437 continue;
1438 }
1439 objects.push_back(info.m_Info);
1440 }
1441 }
1442 }
1443 }
1444
1445
x_HasFeaturesWithId(CSeqFeatData::ESubtype subtype) const1446 bool CTSE_Info::x_HasFeaturesWithId(CSeqFeatData::ESubtype subtype) const
1447 {
1448 TFeatIdIndex::const_iterator iter = m_FeatIdIndex.find(subtype);
1449 return iter != m_FeatIdIndex.end();
1450 }
1451
1452
x_AddFeaturesById(TAnnotObjects & objects,CSeqFeatData::ESubtype subtype,TFeatIdInt id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1453 void CTSE_Info::x_AddFeaturesById(TAnnotObjects& objects,
1454 CSeqFeatData::ESubtype subtype,
1455 TFeatIdInt id,
1456 EFeatIdType id_type,
1457 const CSeq_annot_Info* src_annot) const
1458 {
1459 TFeatIdIndex::const_iterator iter = m_FeatIdIndex.find(subtype);
1460 if ( iter == m_FeatIdIndex.end() ) {
1461 return;
1462 }
1463 x_AddFeaturesById(objects, iter->second, id, id_type, src_annot);
1464 }
1465
1466
x_AddAllFeaturesById(TAnnotObjects & objects,TFeatIdInt id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1467 void CTSE_Info::x_AddAllFeaturesById(TAnnotObjects& objects,
1468 TFeatIdInt id,
1469 EFeatIdType id_type,
1470 const CSeq_annot_Info* src_annot) const
1471 {
1472 //LOG_POST_X(1, this << ": ""x_AddAllFeaturesWithId: " << id);
1473 ITERATE ( TFeatIdIndex, iter, m_FeatIdIndex ) {
1474 x_AddFeaturesById(objects, iter->second, id, id_type, src_annot);
1475 }
1476 }
1477
1478
x_AddFeaturesById(TAnnotObjects & objects,const SFeatIdIndex & index,const TFeatIdStr & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1479 void CTSE_Info::x_AddFeaturesById(TAnnotObjects& objects,
1480 const SFeatIdIndex& index,
1481 const TFeatIdStr& id,
1482 EFeatIdType id_type,
1483 const CSeq_annot_Info* src_annot) const
1484 {
1485 if ( !index.m_Chunks.empty() ) {
1486 x_LoadChunks(index.m_Chunks);
1487 UpdateAnnotIndex();
1488 }
1489 if ( !index.m_IndexStr ) {
1490 return;
1491 }
1492 const CSeq_entry_Info* xref_tse = 0;
1493 if ( src_annot ) {
1494 xref_tse = &src_annot->GetXrefTSE();
1495 if ( xref_tse == this ) {
1496 xref_tse = 0;
1497 }
1498 }
1499 const SFeatIdIndex::TIndexStr& index2 = *index.m_IndexStr;
1500 for ( SFeatIdIndex::TIndexStr::const_iterator iter2 = index2.find(id);
1501 iter2 != index2.end() && iter2->first == id; ++iter2 ) {
1502 const SFeatIdInfo& info = iter2->second;
1503 if ( info.m_Type == id_type ) {
1504 if ( info.m_IsChunk ) {
1505 x_LoadChunk(info.m_ChunkId);
1506 UpdateAnnotIndex();
1507 }
1508 else {
1509 if ( xref_tse && xref_tse != &info.m_Info->GetSeq_annot_Info().GetXrefTSE() ) {
1510 continue;
1511 }
1512 objects.push_back(info.m_Info);
1513 }
1514 }
1515 }
1516 }
1517
1518
x_AddFeaturesById(TAnnotObjects & objects,CSeqFeatData::ESubtype subtype,const TFeatIdStr & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1519 void CTSE_Info::x_AddFeaturesById(TAnnotObjects& objects,
1520 CSeqFeatData::ESubtype subtype,
1521 const TFeatIdStr& id,
1522 EFeatIdType id_type,
1523 const CSeq_annot_Info* src_annot) const
1524 {
1525 TFeatIdIndex::const_iterator iter = m_FeatIdIndex.find(subtype);
1526 if ( iter == m_FeatIdIndex.end() ) {
1527 return;
1528 }
1529 x_AddFeaturesById(objects, iter->second, id, id_type, src_annot);
1530 }
1531
1532
x_AddAllFeaturesById(TAnnotObjects & objects,const TFeatIdStr & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1533 void CTSE_Info::x_AddAllFeaturesById(TAnnotObjects& objects,
1534 const TFeatIdStr& id,
1535 EFeatIdType id_type,
1536 const CSeq_annot_Info* src_annot) const
1537 {
1538 //LOG_POST_X(1, this << ": ""x_AddAllFeaturesWithId: " << id);
1539 ITERATE ( TFeatIdIndex, iter, m_FeatIdIndex ) {
1540 x_AddFeaturesById(objects, iter->second, id, id_type, src_annot);
1541 }
1542 }
1543
1544
1545 CTSE_Info::SFeatIdIndex::TIndexInt&
x_GetFeatIdIndexInt(CSeqFeatData::ESubtype type)1546 CTSE_Info::x_GetFeatIdIndexInt(CSeqFeatData::ESubtype type)
1547 {
1548 //LOG_POST_X(2, this << ": ""x_MapFeatById: " << type);
1549 SFeatIdIndex& index = m_FeatIdIndex[type];
1550 if ( !index.m_IndexInt ) {
1551 index.m_IndexInt.reset(new SFeatIdIndex::TIndexInt);
1552 }
1553 return *index.m_IndexInt;
1554 }
1555
1556
1557 CTSE_Info::SFeatIdIndex::TIndexStr&
x_GetFeatIdIndexStr(CSeqFeatData::ESubtype type)1558 CTSE_Info::x_GetFeatIdIndexStr(CSeqFeatData::ESubtype type)
1559 {
1560 //LOG_POST_X(2, this << ": ""x_MapFeatById: " << type);
1561 SFeatIdIndex& index = m_FeatIdIndex[type];
1562 if ( !index.m_IndexStr ) {
1563 index.m_IndexStr.reset(new SFeatIdIndex::TIndexStr);
1564 }
1565 return *index.m_IndexStr;
1566 }
1567
1568
x_MapFeatById(TFeatIdInt id,CAnnotObject_Info & info,EFeatIdType id_type)1569 void CTSE_Info::x_MapFeatById(TFeatIdInt id,
1570 CAnnotObject_Info& info,
1571 EFeatIdType id_type)
1572 {
1573 //LOG_POST_X(2, this << ": ""x_MapFeatById: " << id << " " << id_type<<" "<<&info);
1574 SFeatIdIndex::TIndexInt& index =
1575 x_GetFeatIdIndexInt(info.GetFeatSubtype());
1576 SFeatIdIndex::TIndexInt::value_type value(id, SFeatIdInfo(id_type, &info));
1577 index.insert(value);
1578 }
1579
1580
x_UnmapFeatById(TFeatIdInt id,CAnnotObject_Info & info,EFeatIdType id_type)1581 void CTSE_Info::x_UnmapFeatById(TFeatIdInt id,
1582 CAnnotObject_Info& info,
1583 EFeatIdType id_type)
1584 {
1585 //LOG_POST_X(3, this << ": ""x_UnmapFeatById: " << id << " " << id_type<<" "<<&info);
1586 SFeatIdIndex::TIndexInt& index =
1587 x_GetFeatIdIndexInt(info.GetFeatSubtype());
1588 for ( SFeatIdIndex::TIndexInt::iterator iter = index.lower_bound(id);
1589 iter != index.end() && iter->first == id; ++iter ) {
1590 if ( iter->second.m_Info == &info && iter->second.m_Type == id_type ) {
1591 index.erase(iter);
1592 return;
1593 }
1594 }
1595 _ASSERT("x_UnmapFeatById: not found" && 0);
1596 }
1597
1598
x_MapFeatById(const TFeatIdStr & id,CAnnotObject_Info & info,EFeatIdType id_type)1599 void CTSE_Info::x_MapFeatById(const TFeatIdStr& id,
1600 CAnnotObject_Info& info,
1601 EFeatIdType id_type)
1602 {
1603 //LOG_POST_X(2, this << ": ""x_MapFeatById: " << id << " " << id_type<<" "<<&info);
1604 SFeatIdIndex::TIndexStr& index =
1605 x_GetFeatIdIndexStr(info.GetFeatSubtype());
1606 SFeatIdIndex::TIndexStr::value_type value(id, SFeatIdInfo(id_type, &info));
1607 index.insert(value);
1608 }
1609
1610
x_UnmapFeatById(const TFeatIdStr & id,CAnnotObject_Info & info,EFeatIdType id_type)1611 void CTSE_Info::x_UnmapFeatById(const TFeatIdStr& id,
1612 CAnnotObject_Info& info,
1613 EFeatIdType id_type)
1614 {
1615 //LOG_POST_X(3, this << ": ""x_UnmapFeatById: " << id << " " << id_type<<" "<<&info);
1616 SFeatIdIndex::TIndexStr& index =
1617 x_GetFeatIdIndexStr(info.GetFeatSubtype());
1618 for ( SFeatIdIndex::TIndexStr::iterator iter = index.lower_bound(id);
1619 iter != index.end() && iter->first == id; ++iter ) {
1620 if ( iter->second.m_Info == &info && iter->second.m_Type == id_type ) {
1621 index.erase(iter);
1622 return;
1623 }
1624 }
1625 _ASSERT("x_UnmapFeatById: not found" && 0);
1626 }
1627
1628
x_MapFeatById(const TFeatId & id,CAnnotObject_Info & info,EFeatIdType id_type)1629 void CTSE_Info::x_MapFeatById(const TFeatId& id,
1630 CAnnotObject_Info& info,
1631 EFeatIdType id_type)
1632 {
1633 if ( id.IsId() ) {
1634 x_MapFeatById(id.GetId(), info, id_type);
1635 }
1636 else {
1637 x_MapFeatById(id.GetStr(), info, id_type);
1638 }
1639 }
1640
1641
x_UnmapFeatById(const TFeatId & id,CAnnotObject_Info & info,EFeatIdType id_type)1642 void CTSE_Info::x_UnmapFeatById(const TFeatId& id,
1643 CAnnotObject_Info& info,
1644 EFeatIdType id_type)
1645 {
1646 if ( id.IsId() ) {
1647 x_UnmapFeatById(id.GetId(), info, id_type);
1648 }
1649 else {
1650 x_UnmapFeatById(id.GetStr(), info, id_type);
1651 }
1652 }
1653
1654
x_MapFeatByLocus(const string & locus,bool tag,CAnnotObject_Info & info)1655 void CTSE_Info::x_MapFeatByLocus(const string& locus, bool tag,
1656 CAnnotObject_Info& info)
1657 {
1658 m_LocusIndex.insert(TLocusIndex::value_type(TLocusKey(locus, tag), &info));
1659 }
1660
1661
x_UnmapFeatByLocus(const string & locus,bool tag,CAnnotObject_Info & info)1662 void CTSE_Info::x_UnmapFeatByLocus(const string& locus, bool tag,
1663 CAnnotObject_Info& info)
1664 {
1665 for ( TLocusIndex::iterator it =
1666 m_LocusIndex.lower_bound(TLocusKey(locus, tag));
1667 it != m_LocusIndex.end() &&
1668 it->first.first == locus &&
1669 it->first.second == tag;
1670 ++it ) {
1671 if ( it->second == &info ) {
1672 m_LocusIndex.erase(it);
1673 return;
1674 }
1675 }
1676 }
1677
1678
x_MapChunkByFeatId(TFeatIdInt id,CSeqFeatData::ESubtype subtype,TChunkId chunk_id,EFeatIdType id_type)1679 void CTSE_Info::x_MapChunkByFeatId(TFeatIdInt id,
1680 CSeqFeatData::ESubtype subtype,
1681 TChunkId chunk_id,
1682 EFeatIdType id_type)
1683 {
1684 SFeatIdIndex::TIndexInt& index = x_GetFeatIdIndexInt(subtype);
1685 SFeatIdIndex::TIndexInt::value_type value(id, SFeatIdInfo(id_type, chunk_id));
1686 index.insert(value);
1687 }
1688
1689
x_MapChunkByFeatId(TFeatIdInt id,CSeqFeatData::E_Choice type,TChunkId chunk_id,EFeatIdType id_type)1690 void CTSE_Info::x_MapChunkByFeatId(TFeatIdInt id,
1691 CSeqFeatData::E_Choice type,
1692 TChunkId chunk_id,
1693 EFeatIdType id_type)
1694 {
1695 CAnnotType_Index::TIndexRange range =
1696 CAnnotType_Index::GetFeatTypeRange(type);
1697 for ( size_t index = range.first; index < range.second; ++index ) {
1698 CSeqFeatData::ESubtype subtype =
1699 CAnnotType_Index::GetSubtypeForIndex(index);
1700 x_MapChunkByFeatId(id, subtype, chunk_id, id_type);
1701 }
1702 }
1703
1704
x_MapChunkByFeatId(TFeatIdInt id,const SAnnotTypeSelector & type,TChunkId chunk_id,EFeatIdType id_type)1705 void CTSE_Info::x_MapChunkByFeatId(TFeatIdInt id,
1706 const SAnnotTypeSelector& type,
1707 TChunkId chunk_id,
1708 EFeatIdType id_type)
1709 {
1710 if ( type.GetFeatSubtype() != CSeqFeatData::eSubtype_any ) {
1711 x_MapChunkByFeatId(id, type.GetFeatSubtype(), chunk_id, id_type);
1712 }
1713 else {
1714 x_MapChunkByFeatId(id, type.GetFeatType(), chunk_id, id_type);
1715 }
1716 }
1717
1718
x_MapChunkByFeatId(const TFeatIdStr & id,CSeqFeatData::ESubtype subtype,TChunkId chunk_id,EFeatIdType id_type)1719 void CTSE_Info::x_MapChunkByFeatId(const TFeatIdStr& id,
1720 CSeqFeatData::ESubtype subtype,
1721 TChunkId chunk_id,
1722 EFeatIdType id_type)
1723 {
1724 SFeatIdIndex::TIndexStr& index = x_GetFeatIdIndexStr(subtype);
1725 SFeatIdIndex::TIndexStr::value_type value(id, SFeatIdInfo(id_type, chunk_id));
1726 index.insert(value);
1727 }
1728
1729
x_MapChunkByFeatId(const TFeatIdStr & id,CSeqFeatData::E_Choice type,TChunkId chunk_id,EFeatIdType id_type)1730 void CTSE_Info::x_MapChunkByFeatId(const TFeatIdStr& id,
1731 CSeqFeatData::E_Choice type,
1732 TChunkId chunk_id,
1733 EFeatIdType id_type)
1734 {
1735 CAnnotType_Index::TIndexRange range =
1736 CAnnotType_Index::GetFeatTypeRange(type);
1737 for ( size_t index = range.first; index < range.second; ++index ) {
1738 CSeqFeatData::ESubtype subtype =
1739 CAnnotType_Index::GetSubtypeForIndex(index);
1740 x_MapChunkByFeatId(id, subtype, chunk_id, id_type);
1741 }
1742 }
1743
1744
x_MapChunkByFeatId(const TFeatIdStr & id,const SAnnotTypeSelector & type,TChunkId chunk_id,EFeatIdType id_type)1745 void CTSE_Info::x_MapChunkByFeatId(const TFeatIdStr& id,
1746 const SAnnotTypeSelector& type,
1747 TChunkId chunk_id,
1748 EFeatIdType id_type)
1749 {
1750 if ( type.GetFeatSubtype() != CSeqFeatData::eSubtype_any ) {
1751 x_MapChunkByFeatId(id, type.GetFeatSubtype(), chunk_id, id_type);
1752 }
1753 else {
1754 x_MapChunkByFeatId(id, type.GetFeatType(), chunk_id, id_type);
1755 }
1756 }
1757
1758
x_MapChunkByFeatId(const TFeatId & id,CSeqFeatData::ESubtype subtype,TChunkId chunk_id,EFeatIdType id_type)1759 void CTSE_Info::x_MapChunkByFeatId(const TFeatId& id,
1760 CSeqFeatData::ESubtype subtype,
1761 TChunkId chunk_id,
1762 EFeatIdType id_type)
1763 {
1764 if ( id.IsId() ) {
1765 x_MapChunkByFeatId(id.GetId(), subtype, chunk_id, id_type);
1766 }
1767 else {
1768 x_MapChunkByFeatId(id.GetStr(), subtype, chunk_id, id_type);
1769 }
1770 }
1771
1772
x_MapChunkByFeatId(const TFeatId & id,CSeqFeatData::E_Choice type,TChunkId chunk_id,EFeatIdType id_type)1773 void CTSE_Info::x_MapChunkByFeatId(const TFeatId& id,
1774 CSeqFeatData::E_Choice type,
1775 TChunkId chunk_id,
1776 EFeatIdType id_type)
1777 {
1778 if ( id.IsId() ) {
1779 x_MapChunkByFeatId(id.GetId(), type, chunk_id, id_type);
1780 }
1781 else {
1782 x_MapChunkByFeatId(id.GetStr(), type, chunk_id, id_type);
1783 }
1784 }
1785
1786
x_MapChunkByFeatId(const TFeatId & id,const SAnnotTypeSelector & type,TChunkId chunk_id,EFeatIdType id_type)1787 void CTSE_Info::x_MapChunkByFeatId(const TFeatId& id,
1788 const SAnnotTypeSelector& type,
1789 TChunkId chunk_id,
1790 EFeatIdType id_type)
1791 {
1792 if ( id.IsId() ) {
1793 x_MapChunkByFeatId(id.GetId(), type, chunk_id, id_type);
1794 }
1795 else {
1796 x_MapChunkByFeatId(id.GetStr(), type, chunk_id, id_type);
1797 }
1798 }
1799
1800
x_MapChunkByFeatType(CSeqFeatData::ESubtype subtype,TChunkId chunk_id)1801 void CTSE_Info::x_MapChunkByFeatType(CSeqFeatData::ESubtype subtype,
1802 TChunkId chunk_id)
1803 {
1804 m_FeatIdIndex[subtype].m_Chunks.push_back(chunk_id);
1805 }
1806
1807
x_MapChunkByFeatType(CSeqFeatData::E_Choice type,TChunkId chunk_id)1808 void CTSE_Info::x_MapChunkByFeatType(CSeqFeatData::E_Choice type,
1809 TChunkId chunk_id)
1810 {
1811 CAnnotType_Index::TIndexRange range =
1812 CAnnotType_Index::GetFeatTypeRange(type);
1813 for ( size_t index = range.first; index < range.second; ++index ) {
1814 CSeqFeatData::ESubtype subtype =
1815 CAnnotType_Index::GetSubtypeForIndex(index);
1816 x_MapChunkByFeatType(subtype, chunk_id);
1817 }
1818 }
1819
1820
x_MapChunkByFeatType(const SAnnotTypeSelector & type,TChunkId chunk_id)1821 void CTSE_Info::x_MapChunkByFeatType(const SAnnotTypeSelector& type,
1822 TChunkId chunk_id)
1823 {
1824 if ( type.GetFeatSubtype() != CSeqFeatData::eSubtype_any ) {
1825 x_MapChunkByFeatType(type.GetFeatSubtype(), chunk_id);
1826 }
1827 else {
1828 x_MapChunkByFeatType(type.GetFeatType(), chunk_id);
1829 }
1830 }
1831
1832
1833 CTSE_Info::TAnnotObjects
x_GetFeaturesById(CSeqFeatData::ESubtype subtype,TFeatIdInt id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1834 CTSE_Info::x_GetFeaturesById(CSeqFeatData::ESubtype subtype,
1835 TFeatIdInt id,
1836 EFeatIdType id_type,
1837 const CSeq_annot_Info* src_annot) const
1838 {
1839 TAnnotObjects objects;
1840 UpdateFeatIdIndex(subtype, id_type);
1841 if ( subtype == CSeqFeatData::eSubtype_any ) {
1842 x_AddAllFeaturesById(objects, id, id_type, src_annot);
1843 }
1844 else {
1845 x_AddFeaturesById(objects, subtype, id, id_type, src_annot);
1846 }
1847 return objects;
1848 }
1849
1850
1851 CTSE_Info::TAnnotObjects
x_GetFeaturesById(CSeqFeatData::E_Choice type,TFeatIdInt id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1852 CTSE_Info::x_GetFeaturesById(CSeqFeatData::E_Choice type,
1853 TFeatIdInt id,
1854 EFeatIdType id_type,
1855 const CSeq_annot_Info* src_annot) const
1856 {
1857 TAnnotObjects objects;
1858 UpdateFeatIdIndex(type, id_type);
1859 if ( type == CSeqFeatData::e_not_set ) {
1860 x_AddAllFeaturesById(objects, id, id_type, src_annot);
1861 }
1862 else {
1863 CAnnotType_Index::TIndexRange range =
1864 CAnnotType_Index::GetFeatTypeRange(type);
1865 for ( size_t index = range.first; index < range.second; ++index ) {
1866 CSeqFeatData::ESubtype subtype =
1867 CAnnotType_Index::GetSubtypeForIndex(index);
1868 x_AddFeaturesById(objects, subtype, id, id_type, src_annot);
1869 }
1870 }
1871 return objects;
1872 }
1873
1874
1875 CTSE_Info::TAnnotObjects
x_GetFeaturesById(CSeqFeatData::ESubtype subtype,const TFeatIdStr & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1876 CTSE_Info::x_GetFeaturesById(CSeqFeatData::ESubtype subtype,
1877 const TFeatIdStr& id,
1878 EFeatIdType id_type,
1879 const CSeq_annot_Info* src_annot) const
1880 {
1881 TAnnotObjects objects;
1882 UpdateFeatIdIndex(subtype, id_type);
1883 if ( subtype == CSeqFeatData::eSubtype_any ) {
1884 x_AddAllFeaturesById(objects, id, id_type, src_annot);
1885 }
1886 else {
1887 x_AddFeaturesById(objects, subtype, id, id_type, src_annot);
1888 }
1889 return objects;
1890 }
1891
1892
1893 CTSE_Info::TAnnotObjects
x_GetFeaturesById(CSeqFeatData::E_Choice type,const TFeatIdStr & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1894 CTSE_Info::x_GetFeaturesById(CSeqFeatData::E_Choice type,
1895 const TFeatIdStr& id,
1896 EFeatIdType id_type,
1897 const CSeq_annot_Info* src_annot) const
1898 {
1899 TAnnotObjects objects;
1900 UpdateFeatIdIndex(type, id_type);
1901 if ( type == CSeqFeatData::e_not_set ) {
1902 x_AddAllFeaturesById(objects, id, id_type, src_annot);
1903 }
1904 else {
1905 CAnnotType_Index::TIndexRange range =
1906 CAnnotType_Index::GetFeatTypeRange(type);
1907 for ( size_t index = range.first; index < range.second; ++index ) {
1908 CSeqFeatData::ESubtype subtype =
1909 CAnnotType_Index::GetSubtypeForIndex(index);
1910 x_AddFeaturesById(objects, subtype, id, id_type, src_annot);
1911 }
1912 }
1913 return objects;
1914 }
1915
1916
1917 CTSE_Info::TAnnotObjects
x_GetFeaturesById(CSeqFeatData::ESubtype subtype,const TFeatId & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1918 CTSE_Info::x_GetFeaturesById(CSeqFeatData::ESubtype subtype,
1919 const TFeatId& id,
1920 EFeatIdType id_type,
1921 const CSeq_annot_Info* src_annot) const
1922 {
1923 TAnnotObjects objects;
1924 if ( id.IsId() ) {
1925 x_GetFeaturesById(subtype, id.GetId(), id_type, src_annot).swap(objects);
1926 }
1927 else {
1928 x_GetFeaturesById(subtype, id.GetStr(), id_type, src_annot).swap(objects);
1929 }
1930 return objects;
1931 }
1932
1933
1934 CTSE_Info::TAnnotObjects
x_GetFeaturesById(CSeqFeatData::E_Choice type,const TFeatId & id,EFeatIdType id_type,const CSeq_annot_Info * src_annot) const1935 CTSE_Info::x_GetFeaturesById(CSeqFeatData::E_Choice type,
1936 const TFeatId& id,
1937 EFeatIdType id_type,
1938 const CSeq_annot_Info* src_annot) const
1939 {
1940 TAnnotObjects objects;
1941 if ( id.IsId() ) {
1942 x_GetFeaturesById(type, id.GetId(), id_type, src_annot).swap(objects);
1943 }
1944 else {
1945 x_GetFeaturesById(type, id.GetStr(), id_type, src_annot).swap(objects);
1946 }
1947 return objects;
1948 }
1949
1950
x_GetFeaturesByLocus(const string & locus,bool tag,const CSeq_annot_Info * src_annot) const1951 CTSE_Info::TAnnotObjects CTSE_Info::x_GetFeaturesByLocus(const string& locus,
1952 bool tag,
1953 const CSeq_annot_Info* src_annot) const
1954 {
1955 UpdateAnnotIndex();
1956 TAnnotObjects objects;
1957 const CSeq_entry_Info* xref_tse = 0;
1958 if ( src_annot ) {
1959 xref_tse = &src_annot->GetXrefTSE();
1960 if ( xref_tse == this ) {
1961 xref_tse = 0;
1962 }
1963 }
1964 for ( TLocusIndex::const_iterator it =
1965 m_LocusIndex.lower_bound(TLocusKey(locus, tag));
1966 it != m_LocusIndex.end() &&
1967 it->first.first == locus &&
1968 it->first.second == tag;
1969 ++it ) {
1970 if ( xref_tse && xref_tse != &it->second->GetSeq_annot_Info().GetXrefTSE() ) {
1971 continue;
1972 }
1973 objects.push_back(it->second);
1974 }
1975 return objects;
1976 }
1977
1978
1979 CTSE_Info::TSeq_feat_Lock
x_FindSeq_feat(const CSeq_id_Handle & loc_id,TSeqPos loc_pos,const CSeq_feat & feat) const1980 CTSE_Info::x_FindSeq_feat(const CSeq_id_Handle& loc_id,
1981 TSeqPos loc_pos,
1982 const CSeq_feat& feat) const
1983 {
1984 TSeq_feat_Lock ret;
1985 CSeqFeatData::ESubtype subtype = feat.GetData().GetSubtype();
1986 size_t index = CAnnotType_Index::GetSubtypeIndex(subtype);
1987 TRange range(loc_pos, loc_pos);
1988 ITERATE ( TNamedAnnotObjs, it_n, m_NamedAnnotObjs ) {
1989 const SIdAnnotObjs* objs = x_GetIdObjects(it_n->second, loc_id);
1990 if ( !objs ) {
1991 continue;
1992 }
1993 if ( index < objs->x_GetRangeMapCount() &&
1994 !objs->x_RangeMapIsEmpty(index) ) {
1995 const TRangeMap& rmap = objs->x_GetRangeMap(index);
1996 for ( TRangeMap::const_iterator it(rmap.begin(range)); it; ++it ) {
1997 const CAnnotObject_Info& annot_info =
1998 *it->second.m_AnnotObject_Info;
1999 if ( !annot_info.IsRegular() ) {
2000 continue;
2001 }
2002 const CSeq_feat* found_feat = annot_info.GetFeatFast();
2003 if ( found_feat == &feat ) {
2004 ret.first.first = &annot_info.GetSeq_annot_Info();
2005 ret.second = annot_info.GetAnnotIndex();
2006 return ret;
2007 }
2008 }
2009 }
2010 /*
2011 if ( subtype == CSeqFeatData::eSubtype_variation &&
2012 !objs->m_SNPSet.empty() ) {
2013
2014 }
2015 */
2016 }
2017 return ret;
2018 }
2019
2020
SetBioseqUpdater(CRef<CBioseqUpdater> updater)2021 void CTSE_Info::SetBioseqUpdater(CRef<CBioseqUpdater> updater)
2022 {
2023 CFastMutexGuard guard(m_BioseqsMutex);
2024 m_BioseqUpdater = updater;
2025 set<CBioseq_Info*> seen;
2026 NON_CONST_ITERATE ( TBioseqs, it, m_Bioseqs ) {
2027 if ( seen.insert(it->second).second ) {
2028 m_BioseqUpdater->Update(*it->second);
2029 }
2030 }
2031 }
2032
2033
GetDescription(void) const2034 string CTSE_Info::GetDescription(void) const
2035 {
2036 string ret;
2037 if ( m_BlobId ) {
2038 ret = GetBlobId().ToString();
2039 }
2040 else {
2041 ret = NStr::PtrToString(this);
2042 }
2043 if ( GetName().IsNamed() ) {
2044 ret += '/';
2045 ret += GetName().GetName();
2046 }
2047 return ret;
2048 }
2049
2050
GetTopLevelObjectType(void) const2051 CTSE_Info::ETopLevelObjectType CTSE_Info::GetTopLevelObjectType(void) const
2052 {
2053 return m_TopLevelObjectType;
2054 }
2055
2056
GetTopLevelObjectPtr(void) const2057 const CSerialObject* CTSE_Info::GetTopLevelObjectPtr(void) const
2058 {
2059 return m_TopLevelObjectPtr.GetPointerOrNull();
2060 }
2061
2062
SetTopLevelObject(ETopLevelObjectType type,CSerialObject * ptr)2063 void CTSE_Info::SetTopLevelObject(ETopLevelObjectType type, CSerialObject* ptr)
2064 {
2065 m_TopLevelObjectType = type;
2066 m_TopLevelObjectPtr = ptr;
2067 }
2068
2069
IsTopLevelSeq_submit() const2070 bool CTSE_Info::IsTopLevelSeq_submit() const
2071 {
2072 return GetTopLevelObjectType() == CTSE_Handle::eTopLevel_Seq_submit;
2073 }
2074
2075
x_GetTopLevelSeq_submit() const2076 CSeq_submit& CTSE_Info::x_GetTopLevelSeq_submit() const
2077 {
2078 if ( !IsTopLevelSeq_submit() ) {
2079 NCBI_THROW(CObjMgrException, eInvalidHandle,
2080 "CTSE_Handle::GetTopLevelSeq_submit: "
2081 "Top level object is not Seq-submit");
2082 }
2083 CSeq_submit* submit = dynamic_cast<CSeq_submit*>(m_TopLevelObjectPtr.GetNCPointerOrNull());
2084 if ( !submit ) {
2085 NCBI_THROW(CObjMgrException, eInvalidHandle,
2086 "CTSE_Handle::GetTopLevelSeq_submit: "
2087 "Top level object is not Seq-submit");
2088 }
2089 return *submit;
2090 }
2091
2092
GetTopLevelSeq_submit() const2093 const CSeq_submit& CTSE_Info::GetTopLevelSeq_submit() const
2094 {
2095 CSeq_submit& submit = x_GetTopLevelSeq_submit();
2096 if ( IsSet() ) {
2097 const TSet& set = GetSet();
2098 // update entry/annot lists
2099 if ( set.IsSetSeq_set() && !set.GetSeq_set().empty() ) {
2100 submit.SetData().SetEntrys() = set.GetBioseq_setCore()->GetSeq_set();
2101 }
2102 else if ( set.IsSetAnnot() && !set.GetAnnot().empty() ) {
2103 submit.SetData().SetAnnots() = set.GetBioseq_setCore()->GetAnnot();
2104 }
2105 else {
2106 switch ( submit.GetData().Which() ) {
2107 case CSeq_submit::TData::e_Entrys:
2108 submit.SetData().SetEntrys().clear();
2109 break;
2110 case CSeq_submit::TData::e_Annots:
2111 submit.SetData().SetAnnots().clear();
2112 break;
2113 default:
2114 break;
2115 }
2116 }
2117 }
2118 return submit;
2119 }
2120
2121
GetTopLevelSubmit_block() const2122 const CSubmit_block& CTSE_Info::GetTopLevelSubmit_block() const
2123 {
2124 return x_GetTopLevelSeq_submit().GetSub();
2125 }
2126
2127
SetTopLevelSubmit_block() const2128 CSubmit_block& CTSE_Info::SetTopLevelSubmit_block() const
2129 {
2130 return x_GetTopLevelSeq_submit().SetSub();
2131 }
2132
2133
SetTopLevelSubmit_block(CSubmit_block & sub) const2134 void CTSE_Info::SetTopLevelSubmit_block(CSubmit_block& sub) const
2135 {
2136 x_GetTopLevelSeq_submit().SetSub(sub);
2137 }
2138
2139
SetTopLevelObjectType(ETopLevelObjectType type)2140 void CTSE_Info::SetTopLevelObjectType(ETopLevelObjectType type)
2141 {
2142 SetTopLevelObject(type, 0);
2143 }
2144
2145
CTSE_SetObjectInfo(void)2146 CTSE_SetObjectInfo::CTSE_SetObjectInfo(void)
2147 {
2148 }
2149
2150
~CTSE_SetObjectInfo(void)2151 CTSE_SetObjectInfo::~CTSE_SetObjectInfo(void)
2152 {
2153 }
2154
2155
2156
2157 END_SCOPE(objects)
2158 END_NCBI_SCOPE
2159