1 /*  $Id: dispatcher.cpp 610970 2020-06-26 12:56:46Z grichenk $
2  * ===========================================================================
3  *                            PUBLIC DOMAIN NOTICE
4  *               National Center for Biotechnology Information
5  *
6  *  This software/database is a "United States Government Work" under the
7  *  terms of the United States Copyright Act.  It was written as part of
8  *  the author's official duties as a United States Government employee and
9  *  thus cannot be copyrighted.  This software/database is freely available
10  *  to the public for use. The National Library of Medicine and the U.S.
11  *  Government have not placed any restriction on its use or reproduction.
12  *
13  *  Although all reasonable efforts have been taken to ensure the accuracy
14  *  and reliability of the software and data, the NLM and the U.S.
15  *  Government do not and cannot warrant the performance or results that
16  *  may be obtained by using this software or data. The NLM and the U.S.
17  *  Government disclaim all warranties, express or implied, including
18  *  warranties of performance, merchantability or fitness for any particular
19  *  purpose.
20  *
21  *  Please cite the author in any work or product based on this material.
22  * ===========================================================================
23  *
24  *  Author:  Anton Butanaev, Eugene Vasilchenko
25  *
26  *  File Description: Base data reader interface
27  *
28  */
29 
30 #include <ncbi_pch.hpp>
31 #include <objtools/data_loaders/genbank/impl/dispatcher.hpp>
32 #include <objtools/data_loaders/genbank/reader.hpp>
33 #include <objtools/data_loaders/genbank/writer.hpp>
34 #include <objtools/data_loaders/genbank/impl/processor.hpp>
35 #include <objtools/data_loaders/genbank/impl/request_result.hpp>
36 #include <objtools/data_loaders/genbank/impl/statistics.hpp>
37 #include <objtools/error_codes.hpp>
38 #include <objmgr/objmgr_exception.hpp>
39 #include <objmgr/impl/tse_split_info.hpp>
40 #include <objmgr/impl/tse_chunk_info.hpp>
41 #include <objects/general/Dbtag.hpp>
42 
43 
44 #define NCBI_USE_ERRCODE_X   Objtools_Rd_Disp
45 
46 BEGIN_NCBI_SCOPE
47 
48 NCBI_DEFINE_ERR_SUBCODE_X(10);
49 
50 BEGIN_SCOPE(objects)
51 
52 NCBI_PARAM_DECL(bool, GENBANK, ALLOW_INCOMPLETE_COMMANDS);
53 NCBI_PARAM_DEF_EX(bool, GENBANK, ALLOW_INCOMPLETE_COMMANDS, false,
54                   eParam_NoThread, GENBANK_ALLOW_INCOMPLETE_COMMANDS);
55 
56 static
s_AllowIncompleteCommands(void)57 bool s_AllowIncompleteCommands(void)
58 {
59     static CSafeStatic<NCBI_PARAM_TYPE(GENBANK, ALLOW_INCOMPLETE_COMMANDS)> s_Value;
60     return s_Value->Get();
61 }
62 
63 
64 /////////////////////////////////////////////////////////////////////////////
65 // CReadDispatcher
66 /////////////////////////////////////////////////////////////////////////////
67 
68 
69 static CGBRequestStatistics sx_Statistics[CGBRequestStatistics::eStats_Count] =
70 {
71     CGBRequestStatistics("resolved", "string ids"),
72     CGBRequestStatistics("resolved", "seq-ids"),
73     CGBRequestStatistics("resolved", "gis"),
74     CGBRequestStatistics("resolved", "accs"),
75     CGBRequestStatistics("resolved", "labels"),
76     CGBRequestStatistics("resolved", "taxids"),
77     CGBRequestStatistics("resolved", "blob ids"),
78     CGBRequestStatistics("resolved", "blob state"),
79     CGBRequestStatistics("resolved", "blob versions"),
80     CGBRequestStatistics("loaded", "blob data"),
81     CGBRequestStatistics("loaded", "SNP data"),
82     CGBRequestStatistics("loaded", "split data"),
83     CGBRequestStatistics("loaded", "chunk data"),
84     CGBRequestStatistics("parsed", "blob data"),
85     CGBRequestStatistics("parsed", "SNP data"),
86     CGBRequestStatistics("parsed", "split data"),
87     CGBRequestStatistics("parsed", "chunk data"),
88     CGBRequestStatistics("loaded", "sequence hash"),
89     CGBRequestStatistics("loaded", "sequence length"),
90     CGBRequestStatistics("loaded", "sequence type")
91 };
92 
CGBRequestStatistics(const char * action,const char * entity)93 CGBRequestStatistics::CGBRequestStatistics(const char* action,
94                                            const char* entity)
95     : m_Action(action), m_Entity(entity),
96       m_Count(0), m_Time(0), m_Size(0)
97 {
98 }
99 
GetStatistics(EStatType type)100 const CGBRequestStatistics& CGBRequestStatistics::GetStatistics(EStatType type)
101 {
102     if ( type < eStat_First || type > eStat_Last ) {
103         NCBI_THROW_FMT(CLoaderException, eOtherError,
104                        "CGBRequestStatistics::GetStatistics: "
105                        "invalid statistics type: "<<type);
106     }
107     return sx_Statistics[type];
108 }
109 
PrintStat(void) const110 void CGBRequestStatistics::PrintStat(void) const
111 {
112     size_t count = GetCount();
113     if ( count > 0 ) {
114         double time = GetTime();
115         double size = GetSize();
116         if ( size <= 0 ) {
117             LOG_POST_X(5, "GBLoader: " << GetAction() << ' ' <<
118                        count << ' ' << GetEntity() << " in " <<
119                        setiosflags(ios::fixed) <<
120                        setprecision(3) <<
121                        (time) << " s (" <<
122                        (time*1000/count) << " ms/one)");
123         }
124         else {
125             LOG_POST_X(6, "GBLoader: " << GetAction() << ' ' <<
126                        count << ' ' << GetEntity() << " in " <<
127                        setiosflags(ios::fixed) <<
128                        setprecision(3) <<
129                        (time) << " s (" <<
130                        (time*1000/count) << " ms/one)" <<
131                        setprecision(2) << " (" <<
132                        (size/1024.0) << " kB " <<
133                        (size/time/1024) << " kB/s)");
134         }
135     }
136 }
137 
138 
PrintStatistics(void)139 void CGBRequestStatistics::PrintStatistics(void)
140 {
141     for ( int type = eStat_First; type <= eStat_Last; ++type ) {
142         sx_Statistics[type].PrintStat();
143     }
144 }
145 
146 inline
CollectStatistics(void)147 int CReadDispatcher::CollectStatistics(void)
148 {
149     static CSafeStatic<NCBI_PARAM_TYPE(GENBANK, READER_STATS)> s_Value;
150     return s_Value->Get();
151 }
152 
153 
CReadDispatcher(void)154 CReadDispatcher::CReadDispatcher(void)
155 {
156     CollectStatistics();
157     CProcessor::RegisterAllProcessors(*this);
158 }
159 
160 
~CReadDispatcher(void)161 CReadDispatcher::~CReadDispatcher(void)
162 {
163     if ( CollectStatistics() > 0 ) {
164         CGBRequestStatistics::PrintStatistics();
165     }
166 }
167 
168 
InsertReader(TLevel level,CRef<CReader> reader)169 void CReadDispatcher::InsertReader(TLevel level, CRef<CReader> reader)
170 {
171     if ( !reader ) {
172         return;
173     }
174 
175     m_Readers[level] = reader;
176     reader->m_Dispatcher = this;
177 }
178 
179 
InsertWriter(TLevel level,CRef<CWriter> writer)180 void CReadDispatcher::InsertWriter(TLevel level, CRef<CWriter> writer)
181 {
182     if ( !writer ) {
183         return;
184     }
185 
186     m_Writers[level] = writer;
187 }
188 
189 
InsertProcessor(CRef<CProcessor> processor)190 void CReadDispatcher::InsertProcessor(CRef<CProcessor> processor)
191 {
192     if ( !processor ) {
193         return;
194     }
195 
196     m_Processors[processor->GetType()] = processor;
197 }
198 
199 
GetWriter(const CReaderRequestResult & result,CWriter::EType type) const200 CWriter* CReadDispatcher::GetWriter(const CReaderRequestResult& result,
201                                     CWriter::EType type) const
202 {
203     ITERATE ( TWriters, i, m_Writers ) {
204         if ( i->first >= result.GetLevel() ) {
205             break;
206         }
207         if ( i->second->CanWrite(type) ) {
208             return const_cast<CWriter*>(i->second.GetPointer());
209         }
210     }
211     return 0;
212 }
213 
214 
GetProcessor(CProcessor::EType type) const215 const CProcessor& CReadDispatcher::GetProcessor(CProcessor::EType type) const
216 {
217     TProcessors::const_iterator iter = m_Processors.find(type);
218     if ( iter == m_Processors.end() ) {
219         NCBI_THROW_FMT(CLoaderException, eLoaderFailed,
220                        "CReadDispatcher::GetProcessor: "
221                        "processor unknown: "<<type);
222     }
223     return *iter->second;
224 }
225 
226 
CheckReaders(void) const227 void CReadDispatcher::CheckReaders(void) const
228 {
229     if ( m_Readers.empty() ) {
230         NCBI_THROW(CLoaderException, eLoaderFailed, "no reader loaded");
231     }
232 }
233 
234 
ResetCaches(void)235 void CReadDispatcher::ResetCaches(void)
236 {
237     NON_CONST_ITERATE(TReaders, rd, m_Readers) {
238         rd->second->ResetCache();
239     }
240     NON_CONST_ITERATE(TWriters, wr, m_Writers) {
241         wr->second->ResetCache();
242     }
243 }
244 
245 
CannotProcess(const CSeq_id_Handle & sih)246 bool CReadDispatcher::CannotProcess(const CSeq_id_Handle& sih)
247 {
248     return !sih || sih.Which() == CSeq_id::e_Local ||
249         (sih.Which() == CSeq_id::e_General &&
250          NStr::EqualNocase(sih.GetSeqId()->GetGeneral().GetDb(), "SRA"));
251 }
252 
253 
CReadDispatcherCommand(CReaderRequestResult & result)254 CReadDispatcherCommand::CReadDispatcherCommand(CReaderRequestResult& result)
255     : m_Result(result)
256 {
257 }
258 
259 
~CReadDispatcherCommand(void)260 CReadDispatcherCommand::~CReadDispatcherCommand(void)
261 {
262 }
263 
264 
MayBeSkipped(void) const265 bool CReadDispatcherCommand::MayBeSkipped(void) const
266 {
267     return false;
268 }
269 
270 
GetStatisticsCount(void) const271 size_t CReadDispatcherCommand::GetStatisticsCount(void) const
272 {
273     return 1;
274 }
275 
276 
277 namespace {
278     class CCommandLoadSeq_idSeq_ids : public CReadDispatcherCommand
279     {
280     public:
281         typedef CSeq_id_Handle TKey;
282         typedef CLoadLockSeqIds TLock;
CCommandLoadSeq_idSeq_ids(CReaderRequestResult & result,const TKey & key)283         CCommandLoadSeq_idSeq_ids(CReaderRequestResult& result,
284                                   const TKey& key)
285             : CReadDispatcherCommand(result),
286               m_Key(key), m_Lock(result, key)
287             {
288             }
289 
IsDone(void)290         bool IsDone(void)
291             {
292                 return m_Lock.IsLoaded();
293             }
Execute(CReader & reader)294         bool Execute(CReader& reader)
295             {
296                 return reader.LoadSeq_idSeq_ids(GetResult(), m_Key);
297             }
GetErrMsg(void) const298         string GetErrMsg(void) const
299             {
300                 return "LoadSeq_idSeq_ids("+m_Key.AsString()+"): "
301                     "data not found";
302             }
GetStatistics(void) const303         CGBRequestStatistics::EStatType GetStatistics(void) const
304             {
305                 return CGBRequestStatistics::eStat_Seq_idSeq_ids;
306             }
GetStatisticsDescription(void) const307         string GetStatisticsDescription(void) const
308             {
309                 return "Seq-ids("+m_Key.AsString()+")";
310             }
311 
312     private:
313         TKey m_Key;
314         TLock m_Lock;
315     };
316 
317     class CCommandLoadSeq_idGi : public CReadDispatcherCommand
318     {
319     public:
320         typedef CSeq_id_Handle TKey;
321         typedef CLoadLockGi TLock;
CCommandLoadSeq_idGi(CReaderRequestResult & result,const TKey & key)322         CCommandLoadSeq_idGi(CReaderRequestResult& result,
323                              const TKey& key)
324             : CReadDispatcherCommand(result),
325               m_Key(key), m_Lock(result, key)
326             {
327             }
328 
IsDone(void)329         bool IsDone(void)
330             {
331                 return m_Lock.IsLoadedGi();
332             }
Execute(CReader & reader)333         bool Execute(CReader& reader)
334             {
335                 return reader.LoadSeq_idGi(GetResult(), m_Key);
336             }
GetErrMsg(void) const337         string GetErrMsg(void) const
338             {
339                 return "LoadSeq_idGi("+m_Key.AsString()+"): "
340                     "data not found";
341             }
GetStatistics(void) const342         CGBRequestStatistics::EStatType GetStatistics(void) const
343             {
344                 return CGBRequestStatistics::eStat_Seq_idGi;
345             }
GetStatisticsDescription(void) const346         string GetStatisticsDescription(void) const
347             {
348                 return "gi("+m_Key.AsString()+")";
349             }
350 
351     private:
352         TKey m_Key;
353         TLock m_Lock;
354     };
355 
356     class CCommandLoadSeq_idAccVer : public CReadDispatcherCommand
357     {
358     public:
359         typedef CSeq_id_Handle TKey;
360         typedef CLoadLockAcc TLock;
CCommandLoadSeq_idAccVer(CReaderRequestResult & result,const TKey & key)361         CCommandLoadSeq_idAccVer(CReaderRequestResult& result,
362                                  const TKey& key)
363             : CReadDispatcherCommand(result),
364               m_Key(key), m_Lock(result, key)
365             {
366             }
367 
IsDone(void)368         bool IsDone(void)
369             {
370                 return m_Lock.IsLoadedAccVer();
371             }
Execute(CReader & reader)372         bool Execute(CReader& reader)
373             {
374                 return reader.LoadSeq_idAccVer(GetResult(), m_Key);
375             }
GetErrMsg(void) const376         string GetErrMsg(void) const
377             {
378                 return "LoadSeq_idAccVer("+m_Key.AsString()+"): "
379                     "data not found";
380             }
GetStatistics(void) const381         CGBRequestStatistics::EStatType GetStatistics(void) const
382             {
383                 return CGBRequestStatistics::eStat_Seq_idAcc;
384             }
GetStatisticsDescription(void) const385         string GetStatisticsDescription(void) const
386             {
387                 return "acc("+m_Key.AsString()+")";
388             }
389 
390     private:
391         TKey m_Key;
392         TLock m_Lock;
393     };
394 
395     class CCommandLoadSeq_idLabel : public CReadDispatcherCommand
396     {
397     public:
398         typedef CSeq_id_Handle TKey;
399         typedef CLoadLockLabel TLock;
CCommandLoadSeq_idLabel(CReaderRequestResult & result,const TKey & key)400         CCommandLoadSeq_idLabel(CReaderRequestResult& result,
401                                 const TKey& key)
402             : CReadDispatcherCommand(result),
403               m_Key(key), m_Lock(result, key)
404             {
405             }
406 
IsDone(void)407         bool IsDone(void)
408             {
409                 return m_Lock.IsLoadedLabel();
410             }
Execute(CReader & reader)411         bool Execute(CReader& reader)
412             {
413                 return reader.LoadSeq_idLabel(GetResult(), m_Key);
414             }
GetErrMsg(void) const415         string GetErrMsg(void) const
416             {
417                 return "LoadSeq_idLabel("+m_Key.AsString()+"): "
418                     "data not found";
419             }
GetStatistics(void) const420         CGBRequestStatistics::EStatType GetStatistics(void) const
421             {
422                 return CGBRequestStatistics::eStat_Seq_idLabel;
423             }
GetStatisticsDescription(void) const424         string GetStatisticsDescription(void) const
425             {
426                 return "label("+m_Key.AsString()+")";
427             }
428 
429     private:
430         TKey m_Key;
431         TLock m_Lock;
432     };
433 
434     class CCommandLoadSeq_idTaxId : public CReadDispatcherCommand
435     {
436     public:
437         typedef CSeq_id_Handle TKey;
438         typedef CLoadLockTaxId TLock;
CCommandLoadSeq_idTaxId(CReaderRequestResult & result,const TKey & key)439         CCommandLoadSeq_idTaxId(CReaderRequestResult& result,
440                                 const TKey& key)
441             : CReadDispatcherCommand(result),
442               m_Key(key), m_Lock(result, key)
443             {
444             }
445 
IsDone(void)446         bool IsDone(void)
447             {
448                 return m_Lock.IsLoadedTaxId();
449             }
Execute(CReader & reader)450         bool Execute(CReader& reader)
451             {
452                 return reader.LoadSeq_idTaxId(GetResult(), m_Key);
453             }
MayBeSkipped(void) const454         bool MayBeSkipped(void) const
455             {
456                 return true;
457             }
GetErrMsg(void) const458         string GetErrMsg(void) const
459             {
460                 return "LoadSeq_idTaxId("+m_Key.AsString()+"): "
461                     "data not found";
462             }
GetStatistics(void) const463         CGBRequestStatistics::EStatType GetStatistics(void) const
464             {
465                 return CGBRequestStatistics::eStat_Seq_idTaxId;
466             }
GetStatisticsDescription(void) const467         string GetStatisticsDescription(void) const
468             {
469                 return "taxid("+m_Key.AsString()+")";
470             }
471 
472     private:
473         TKey m_Key;
474         TLock m_Lock;
475     };
476 
477     class CCommandLoadSequenceHash : public CReadDispatcherCommand
478     {
479     public:
480         typedef CSeq_id_Handle TKey;
481         typedef CLoadLockHash TLock;
CCommandLoadSequenceHash(CReaderRequestResult & result,const TKey & key)482         CCommandLoadSequenceHash(CReaderRequestResult& result,
483                                  const TKey& key)
484             : CReadDispatcherCommand(result),
485               m_Key(key), m_Lock(result, key)
486             {
487             }
488 
IsDone(void)489         bool IsDone(void)
490             {
491                 return m_Lock.IsLoadedHash();
492             }
Execute(CReader & reader)493         bool Execute(CReader& reader)
494             {
495                 return reader.LoadSequenceHash(GetResult(), m_Key);
496             }
MayBeSkipped(void) const497         bool MayBeSkipped(void) const
498             {
499                 return true;
500             }
GetErrMsg(void) const501         string GetErrMsg(void) const
502             {
503                 return "LoadSequenceHash("+m_Key.AsString()+"): "
504                     "data not found";
505             }
GetStatistics(void) const506         CGBRequestStatistics::EStatType GetStatistics(void) const
507             {
508                 return CGBRequestStatistics::eStat_Hash;
509             }
GetStatisticsDescription(void) const510         string GetStatisticsDescription(void) const
511             {
512                 return "hash("+m_Key.AsString()+")";
513             }
514 
515     private:
516         TKey m_Key;
517         TLock m_Lock;
518     };
519 
520     class CCommandLoadSequenceLength : public CReadDispatcherCommand
521     {
522     public:
523         typedef CSeq_id_Handle TKey;
524         typedef CLoadLockLength TLock;
CCommandLoadSequenceLength(CReaderRequestResult & result,const TKey & key)525         CCommandLoadSequenceLength(CReaderRequestResult& result,
526                                  const TKey& key)
527             : CReadDispatcherCommand(result),
528               m_Key(key), m_Lock(result, key)
529             {
530             }
531 
IsDone(void)532         bool IsDone(void)
533             {
534                 return m_Lock.IsLoadedLength();
535             }
Execute(CReader & reader)536         bool Execute(CReader& reader)
537             {
538                 return reader.LoadSequenceLength(GetResult(), m_Key);
539             }
MayBeSkipped(void) const540         bool MayBeSkipped(void) const
541             {
542                 return true;
543             }
GetErrMsg(void) const544         string GetErrMsg(void) const
545             {
546                 return "LoadSequenceLength("+m_Key.AsString()+"): "
547                     "data not found";
548             }
GetStatistics(void) const549         CGBRequestStatistics::EStatType GetStatistics(void) const
550             {
551                 return CGBRequestStatistics::eStat_Length;
552             }
GetStatisticsDescription(void) const553         string GetStatisticsDescription(void) const
554             {
555                 return "length("+m_Key.AsString()+")";
556             }
557 
558     private:
559         TKey m_Key;
560         TLock m_Lock;
561     };
562 
563     class CCommandLoadSequenceType : public CReadDispatcherCommand
564     {
565     public:
566         typedef CSeq_id_Handle TKey;
567         typedef CLoadLockType TLock;
CCommandLoadSequenceType(CReaderRequestResult & result,const TKey & key)568         CCommandLoadSequenceType(CReaderRequestResult& result,
569                                  const TKey& key)
570             : CReadDispatcherCommand(result),
571               m_Key(key), m_Lock(result, key)
572             {
573             }
574 
IsDone(void)575         bool IsDone(void)
576             {
577                 return m_Lock.IsLoadedType();
578             }
Execute(CReader & reader)579         bool Execute(CReader& reader)
580             {
581                 return reader.LoadSequenceType(GetResult(), m_Key);
582             }
MayBeSkipped(void) const583         bool MayBeSkipped(void) const
584             {
585                 return true;
586             }
GetErrMsg(void) const587         string GetErrMsg(void) const
588             {
589                 return "LoadSequenceType("+m_Key.AsString()+"): "
590                     "data not found";
591             }
GetStatistics(void) const592         CGBRequestStatistics::EStatType GetStatistics(void) const
593             {
594                 return CGBRequestStatistics::eStat_Type;
595             }
GetStatisticsDescription(void) const596         string GetStatisticsDescription(void) const
597             {
598                 return "type("+m_Key.AsString()+")";
599             }
600 
601     private:
602         TKey m_Key;
603         TLock m_Lock;
604     };
605 
s_Blob_idsLoaded(CLoadLockBlobIds & ids,CReaderRequestResult & result,const CSeq_id_Handle & seq_id)606     bool s_Blob_idsLoaded(CLoadLockBlobIds& ids,
607                           CReaderRequestResult& result,
608                           const CSeq_id_Handle& seq_id)
609     {
610         if ( ids.IsLoaded() ) {
611             return true;
612         }
613         // check if seq-id is known as absent
614         CLoadLockSeqIds seq_ids(result, seq_id, eAlreadyLoaded);
615         if ( seq_ids && !seq_ids.GetData().IsFound() ) {
616             // mark blob-ids as absent too
617             ids.SetNoBlob_ids(seq_ids.GetState());
618             return true;
619         }
620         return false;
621     }
622 
623     class CCommandLoadSeq_idBlob_ids : public CReadDispatcherCommand
624     {
625     public:
626         typedef CSeq_id_Handle TKey;
627         typedef CLoadLockBlobIds TLock;
CCommandLoadSeq_idBlob_ids(CReaderRequestResult & result,const TKey & key,const SAnnotSelector * sel)628         CCommandLoadSeq_idBlob_ids(CReaderRequestResult& result,
629                                    const TKey& key,
630                                    const SAnnotSelector* sel)
631             : CReadDispatcherCommand(result),
632               m_Key(key), m_Selector(sel),
633               m_Lock(result, key, sel)
634             {
635             }
636 
IsDone(void)637         bool IsDone(void)
638             {
639                 return s_Blob_idsLoaded(m_Lock, GetResult(), m_Key);
640             }
Execute(CReader & reader)641         bool Execute(CReader& reader)
642             {
643                 return reader.LoadSeq_idBlob_ids(GetResult(),
644                                                  m_Key, m_Selector);
645             }
GetErrMsg(void) const646         string GetErrMsg(void) const
647             {
648                 return "LoadSeq_idBlob_ids("+m_Key.AsString()+"): "
649                     "data not found";
650             }
GetStatistics(void) const651         CGBRequestStatistics::EStatType GetStatistics(void) const
652             {
653                 return CGBRequestStatistics::eStat_Seq_idBlob_ids;
654             }
GetStatisticsDescription(void) const655         string GetStatisticsDescription(void) const
656             {
657                 return "blob-ids("+m_Key.AsString()+")";
658             }
659 
660     private:
661         TKey m_Key;
662         const SAnnotSelector* m_Selector;
663         TLock m_Lock;
664     };
665 
666     template<class CLoadLock>
sx_IsLoaded(size_t i,CReaderRequestResult & result,const vector<CSeq_id_Handle> & ids,const vector<bool> & loaded)667     bool sx_IsLoaded(size_t i,
668                      CReaderRequestResult& result,
669                      const vector<CSeq_id_Handle>& ids,
670                      const vector<bool>& loaded)
671     {
672         if ( loaded[i] || CReadDispatcher::CannotProcess(ids[i]) ) {
673             return true;
674         }
675         CLoadLock lock(result, ids[i]);
676         if ( lock.IsLoaded() && !lock.IsFound() ) {
677             return true;
678         }
679         return false;
680     }
681 
682     template<class CLoadLock>
sx_BulkIsDone(CReaderRequestResult & result,const vector<CSeq_id_Handle> & ids,const vector<bool> & loaded)683     bool sx_BulkIsDone(CReaderRequestResult& result,
684                        const vector<CSeq_id_Handle>& ids,
685                        const vector<bool>& loaded)
686     {
687         for ( size_t i = 0; i < ids.size(); ++i ) {
688             if ( sx_IsLoaded<CLoadLock>(i, result, ids, loaded) ) {
689                 continue;
690             }
691             return false;
692         }
693         return true;
694     }
695 
696     template<class CLoadLock>
sx_DescribeError(CReaderRequestResult & result,const vector<CSeq_id_Handle> & ids,const vector<bool> & loaded)697     string sx_DescribeError(CReaderRequestResult& result,
698                             const vector<CSeq_id_Handle>& ids,
699                             const vector<bool>& loaded)
700     {
701         string ret;
702         for ( size_t i = 0; i < ids.size(); ++i ) {
703             if ( sx_IsLoaded<CLoadLock>(i, result, ids, loaded) ) {
704                 continue;
705             }
706             if ( !ret.empty() ) {
707                 ret += ", ";
708             }
709             ret += ids[i].AsString();
710         }
711         ret += " ["+NStr::SizetToString(ids.size())+"]";
712         return ret;
713     }
714 
715     class CCommandLoadAccVers : public CReadDispatcherCommand
716     {
717     public:
718         typedef vector<CSeq_id_Handle> TKey;
719         typedef vector<bool> TLoaded;
720         typedef vector<CSeq_id_Handle> TRet;
721         typedef CLoadLockAcc CLoadLock;
CCommandLoadAccVers(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)722         CCommandLoadAccVers(CReaderRequestResult& result,
723                             const TKey& key, TLoaded& loaded, TRet& ret)
724             : CReadDispatcherCommand(result),
725               m_Key(key), m_Loaded(loaded), m_Ret(ret)
726             {
727             }
728 
Execute(CReader & reader)729         bool Execute(CReader& reader)
730             {
731                 return reader.LoadAccVers(GetResult(), m_Key, m_Loaded, m_Ret);
732             }
IsDone(void)733         bool IsDone(void)
734             {
735                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
736             }
GetErrMsg(void) const737         string GetErrMsg(void) const
738             {
739                 return "LoadAccVers("+
740                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
741                     "): data not found";
742             }
GetStatisticsDescription(void) const743         string GetStatisticsDescription(void) const
744             {
745                 return "accs("+
746                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
747                     ")";
748             }
GetStatistics(void) const749         CGBRequestStatistics::EStatType GetStatistics(void) const
750             {
751                 return CGBRequestStatistics::eStat_Seq_idAcc;
752             }
GetStatisticsCount(void) const753         size_t GetStatisticsCount(void) const
754             {
755                 return m_Key.size();
756             }
757 
758     private:
759         const TKey& m_Key;
760         TLoaded& m_Loaded;
761         TRet& m_Ret;
762     };
763 
764     class CCommandLoadGis : public CReadDispatcherCommand
765     {
766     public:
767         typedef vector<CSeq_id_Handle> TKey;
768         typedef vector<bool> TLoaded;
769         typedef vector<TGi> TRet;
770         typedef CLoadLockGi CLoadLock;
CCommandLoadGis(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)771         CCommandLoadGis(CReaderRequestResult& result,
772                         const TKey& key, TLoaded& loaded, TRet& ret)
773             : CReadDispatcherCommand(result),
774               m_Key(key), m_Loaded(loaded), m_Ret(ret)
775             {
776             }
777 
Execute(CReader & reader)778         bool Execute(CReader& reader)
779             {
780                 return reader.LoadGis(GetResult(), m_Key, m_Loaded, m_Ret);
781             }
IsDone(void)782         bool IsDone(void)
783             {
784                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
785             }
GetErrMsg(void) const786         string GetErrMsg(void) const
787             {
788                 return "LoadGis("+
789                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
790                     "): data not found";
791             }
GetStatisticsDescription(void) const792         string GetStatisticsDescription(void) const
793             {
794                 return "gis("+
795                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
796                     ")";
797             }
GetStatistics(void) const798         CGBRequestStatistics::EStatType GetStatistics(void) const
799             {
800                 return CGBRequestStatistics::eStat_Seq_idGi;
801             }
GetStatisticsCount(void) const802         size_t GetStatisticsCount(void) const
803             {
804                 return m_Key.size();
805             }
806 
807     private:
808         const TKey& m_Key;
809         TLoaded& m_Loaded;
810         TRet& m_Ret;
811     };
812 
813     class CCommandLoadLabels : public CReadDispatcherCommand
814     {
815     public:
816         typedef vector<CSeq_id_Handle> TKey;
817         typedef vector<bool> TLoaded;
818         typedef vector<string> TRet;
819         typedef CLoadLockLabel CLoadLock;
CCommandLoadLabels(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)820         CCommandLoadLabels(CReaderRequestResult& result,
821                            const TKey& key, TLoaded& loaded, TRet& ret)
822             : CReadDispatcherCommand(result),
823               m_Key(key), m_Loaded(loaded), m_Ret(ret)
824             {
825             }
826 
Execute(CReader & reader)827         bool Execute(CReader& reader)
828             {
829                 return reader.LoadLabels(GetResult(), m_Key, m_Loaded, m_Ret);
830             }
IsDone(void)831         bool IsDone(void)
832             {
833                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
834             }
GetErrMsg(void) const835         string GetErrMsg(void) const
836             {
837                 return "LoadLabels("+
838                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
839                     "): data not found";
840             }
GetStatisticsDescription(void) const841         string GetStatisticsDescription(void) const
842             {
843                 return "labels("+
844                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
845                     ")";
846             }
GetStatistics(void) const847         CGBRequestStatistics::EStatType GetStatistics(void) const
848             {
849                 return CGBRequestStatistics::eStat_Seq_idLabel;
850             }
GetStatisticsCount(void) const851         size_t GetStatisticsCount(void) const
852             {
853                 return m_Key.size();
854             }
855 
856     private:
857         const TKey& m_Key;
858         TLoaded& m_Loaded;
859         TRet& m_Ret;
860     };
861 
862     class CCommandLoadTaxIds : public CReadDispatcherCommand
863     {
864     public:
865         typedef vector<CSeq_id_Handle> TKey;
866         typedef vector<bool> TLoaded;
867         typedef vector<TTaxId> TRet;
868         typedef CLoadLockTaxId CLoadLock;
CCommandLoadTaxIds(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)869         CCommandLoadTaxIds(CReaderRequestResult& result,
870                            const TKey& key, TLoaded& loaded, TRet& ret)
871             : CReadDispatcherCommand(result),
872               m_Key(key), m_Loaded(loaded), m_Ret(ret)
873             {
874             }
875 
Execute(CReader & reader)876         bool Execute(CReader& reader)
877             {
878                 return reader.LoadTaxIds(GetResult(), m_Key, m_Loaded, m_Ret);
879             }
MayBeSkipped(void) const880         bool MayBeSkipped(void) const
881             {
882                 return true;
883             }
IsDone(void)884         bool IsDone(void)
885             {
886                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
887             }
GetErrMsg(void) const888         string GetErrMsg(void) const
889             {
890                 return "LoadTaxIds("+
891                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
892                     "): data not found";
893             }
GetStatisticsDescription(void) const894         string GetStatisticsDescription(void) const
895             {
896                 return "taxids("+
897                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
898                     ")";
899             }
GetStatistics(void) const900         CGBRequestStatistics::EStatType GetStatistics(void) const
901             {
902                 return CGBRequestStatistics::eStat_Seq_idTaxId;
903             }
GetStatisticsCount(void) const904         size_t GetStatisticsCount(void) const
905             {
906                 return m_Key.size();
907             }
908 
909     private:
910         const TKey& m_Key;
911         TLoaded& m_Loaded;
912         TRet& m_Ret;
913     };
914 
915     class CCommandLoadHashes : public CReadDispatcherCommand
916     {
917     public:
918         typedef vector<CSeq_id_Handle> TKey;
919         typedef vector<bool> TLoaded;
920         typedef vector<bool> TKnown;
921         typedef vector<int> TRet;
922         typedef CLoadLockHash CLoadLock;
CCommandLoadHashes(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret,TKnown & known)923         CCommandLoadHashes(CReaderRequestResult& result,
924                            const TKey& key, TLoaded& loaded,
925                            TRet& ret, TKnown& known)
926             : CReadDispatcherCommand(result),
927               m_Key(key), m_Loaded(loaded), m_Ret(ret), m_Known(known)
928             {
929             }
930 
Execute(CReader & reader)931         bool Execute(CReader& reader)
932             {
933                 return reader.LoadHashes(GetResult(), m_Key, m_Loaded,
934                                          m_Ret, m_Known);
935             }
MayBeSkipped(void) const936         bool MayBeSkipped(void) const
937             {
938                 return true;
939             }
IsDone(void)940         bool IsDone(void)
941             {
942                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
943             }
GetErrMsg(void) const944         string GetErrMsg(void) const
945             {
946                 return "LoadHashes("+
947                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
948                     "): data not found";
949             }
GetStatisticsDescription(void) const950         string GetStatisticsDescription(void) const
951             {
952                 return "hashes("+
953                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
954                     ")";
955             }
GetStatistics(void) const956         CGBRequestStatistics::EStatType GetStatistics(void) const
957             {
958                 return CGBRequestStatistics::eStat_Hash;
959             }
GetStatisticsCount(void) const960         size_t GetStatisticsCount(void) const
961             {
962                 return m_Key.size();
963             }
964 
965     private:
966         const TKey& m_Key;
967         TLoaded& m_Loaded;
968         TRet& m_Ret;
969         TKnown& m_Known;
970     };
971 
972     class CCommandLoadLengths : public CReadDispatcherCommand
973     {
974     public:
975         typedef vector<CSeq_id_Handle> TKey;
976         typedef vector<bool> TLoaded;
977         typedef vector<TSeqPos> TRet;
978         typedef CLoadLockLength CLoadLock;
CCommandLoadLengths(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)979         CCommandLoadLengths(CReaderRequestResult& result,
980                            const TKey& key, TLoaded& loaded, TRet& ret)
981             : CReadDispatcherCommand(result),
982               m_Key(key), m_Loaded(loaded), m_Ret(ret)
983             {
984             }
985 
Execute(CReader & reader)986         bool Execute(CReader& reader)
987             {
988                 return reader.LoadLengths(GetResult(), m_Key, m_Loaded, m_Ret);
989             }
MayBeSkipped(void) const990         bool MayBeSkipped(void) const
991             {
992                 return true;
993             }
IsDone(void)994         bool IsDone(void)
995             {
996                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
997             }
GetErrMsg(void) const998         string GetErrMsg(void) const
999             {
1000                 return "LoadLengths("+
1001                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
1002                     "): data not found";
1003             }
GetStatisticsDescription(void) const1004         string GetStatisticsDescription(void) const
1005             {
1006                 return "lengths("+
1007                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
1008                     ")";
1009             }
GetStatistics(void) const1010         CGBRequestStatistics::EStatType GetStatistics(void) const
1011             {
1012                 return CGBRequestStatistics::eStat_Length;
1013             }
GetStatisticsCount(void) const1014         size_t GetStatisticsCount(void) const
1015             {
1016                 return m_Key.size();
1017             }
1018 
1019     private:
1020         const TKey& m_Key;
1021         TLoaded& m_Loaded;
1022         TRet& m_Ret;
1023     };
1024 
1025     class CCommandLoadTypes : public CReadDispatcherCommand
1026     {
1027     public:
1028         typedef vector<CSeq_id_Handle> TKey;
1029         typedef vector<bool> TLoaded;
1030         typedef vector<CSeq_inst::EMol> TRet;
1031         typedef CLoadLockType CLoadLock;
CCommandLoadTypes(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)1032         CCommandLoadTypes(CReaderRequestResult& result,
1033                            const TKey& key, TLoaded& loaded, TRet& ret)
1034             : CReadDispatcherCommand(result),
1035               m_Key(key), m_Loaded(loaded), m_Ret(ret)
1036             {
1037             }
1038 
Execute(CReader & reader)1039         bool Execute(CReader& reader)
1040             {
1041                 return reader.LoadTypes(GetResult(), m_Key, m_Loaded, m_Ret);
1042             }
MayBeSkipped(void) const1043         bool MayBeSkipped(void) const
1044             {
1045                 return true;
1046             }
IsDone(void)1047         bool IsDone(void)
1048             {
1049                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
1050             }
GetErrMsg(void) const1051         string GetErrMsg(void) const
1052             {
1053                 return "LoadTypes("+
1054                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
1055                     "): data not found";
1056             }
GetStatisticsDescription(void) const1057         string GetStatisticsDescription(void) const
1058             {
1059                 return "types("+
1060                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
1061                     ")";
1062             }
GetStatistics(void) const1063         CGBRequestStatistics::EStatType GetStatistics(void) const
1064             {
1065                 return CGBRequestStatistics::eStat_Type;
1066             }
GetStatisticsCount(void) const1067         size_t GetStatisticsCount(void) const
1068             {
1069                 return m_Key.size();
1070             }
1071 
1072     private:
1073         const TKey& m_Key;
1074         TLoaded& m_Loaded;
1075         TRet& m_Ret;
1076     };
1077 
1078     class CCommandLoadStates : public CReadDispatcherCommand
1079     {
1080     public:
1081         typedef vector<CSeq_id_Handle> TKey;
1082         typedef vector<bool> TLoaded;
1083         typedef vector<int> TRet;
1084         typedef CLoadLockBlobIds CLoadLock;
CCommandLoadStates(CReaderRequestResult & result,const TKey & key,TLoaded & loaded,TRet & ret)1085         CCommandLoadStates(CReaderRequestResult& result,
1086                            const TKey& key, TLoaded& loaded, TRet& ret)
1087             : CReadDispatcherCommand(result),
1088               m_Key(key), m_Loaded(loaded), m_Ret(ret)
1089             {
1090             }
1091 
Execute(CReader & reader)1092         bool Execute(CReader& reader)
1093             {
1094                 return reader.LoadStates(GetResult(), m_Key, m_Loaded, m_Ret);
1095             }
IsDone(void)1096         bool IsDone(void)
1097             {
1098                 return sx_BulkIsDone<CLoadLock>(GetResult(), m_Key, m_Loaded);
1099             }
GetErrMsg(void) const1100         string GetErrMsg(void) const
1101             {
1102                 return "LoadStates("+
1103                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
1104                     "): data not found";
1105             }
GetStatisticsDescription(void) const1106         string GetStatisticsDescription(void) const
1107             {
1108                 return "states("+
1109                     sx_DescribeError<CLoadLock>(GetResult(), m_Key, m_Loaded)+
1110                     ")";
1111             }
GetStatistics(void) const1112         CGBRequestStatistics::EStatType GetStatistics(void) const
1113             {
1114                 return CGBRequestStatistics::eStat_BlobState;
1115             }
GetStatisticsCount(void) const1116         size_t GetStatisticsCount(void) const
1117             {
1118                 return m_Key.size();
1119             }
1120 
1121     private:
1122         const TKey& m_Key;
1123         TLoaded& m_Loaded;
1124         TRet& m_Ret;
1125     };
1126 
1127     class CCommandLoadBlobState : public CReadDispatcherCommand
1128     {
1129     public:
1130         typedef CBlob_id TKey;
1131         typedef CLoadLockBlobState TLock;
CCommandLoadBlobState(CReaderRequestResult & result,const TKey & key)1132         CCommandLoadBlobState(CReaderRequestResult& result,
1133                               const TKey& key)
1134             : CReadDispatcherCommand(result),
1135               m_Key(key), m_Lock(result, key)
1136             {
1137             }
1138 
IsDone(void)1139         bool IsDone(void)
1140             {
1141                 return m_Lock.IsLoadedBlobState();
1142             }
Execute(CReader & reader)1143         bool Execute(CReader& reader)
1144             {
1145                 return reader.LoadBlobState(GetResult(), m_Key);
1146             }
GetErrMsg(void) const1147         string GetErrMsg(void) const
1148             {
1149                 return "LoadBlobVersion("+m_Key.ToString()+"): "
1150                     "data not found";
1151             }
GetStatistics(void) const1152         CGBRequestStatistics::EStatType GetStatistics(void) const
1153             {
1154                 return CGBRequestStatistics::eStat_BlobState;
1155             }
GetStatisticsDescription(void) const1156         string GetStatisticsDescription(void) const
1157             {
1158                 return "blob-version("+m_Key.ToString()+")";
1159             }
1160 
1161     private:
1162         TKey m_Key;
1163         TLock m_Lock;
1164     };
1165 
1166     class CCommandLoadBlobVersion : public CReadDispatcherCommand
1167     {
1168     public:
1169         typedef CBlob_id TKey;
1170         typedef CLoadLockBlobVersion TLock;
CCommandLoadBlobVersion(CReaderRequestResult & result,const TKey & key)1171         CCommandLoadBlobVersion(CReaderRequestResult& result,
1172                                 const TKey& key)
1173             : CReadDispatcherCommand(result),
1174               m_Key(key), m_Lock(result, key)
1175             {
1176             }
1177 
IsDone(void)1178         bool IsDone(void)
1179             {
1180                 return m_Lock.IsLoadedBlobVersion();
1181             }
Execute(CReader & reader)1182         bool Execute(CReader& reader)
1183             {
1184                 return reader.LoadBlobVersion(GetResult(), m_Key);
1185             }
GetErrMsg(void) const1186         string GetErrMsg(void) const
1187             {
1188                 return "LoadBlobVersion("+m_Key.ToString()+"): "
1189                     "data not found";
1190             }
GetStatistics(void) const1191         CGBRequestStatistics::EStatType GetStatistics(void) const
1192             {
1193                 return CGBRequestStatistics::eStat_BlobVersion;
1194             }
GetStatisticsDescription(void) const1195         string GetStatisticsDescription(void) const
1196             {
1197                 return "blob-version("+m_Key.ToString()+")";
1198             }
1199 
1200     private:
1201         TKey m_Key;
1202         TLock m_Lock;
1203     };
1204 
s_AllBlobsAreLoaded(CReaderRequestResult & result,const CLoadLockBlobIds & blobs,CReadDispatcher::TContentsMask mask,const SAnnotSelector * sel)1205     bool s_AllBlobsAreLoaded(CReaderRequestResult& result,
1206                              const CLoadLockBlobIds& blobs,
1207                              CReadDispatcher::TContentsMask mask,
1208                              const SAnnotSelector* sel)
1209     {
1210         _ASSERT(blobs.IsLoaded());
1211 
1212         CFixedBlob_ids blob_ids = blobs.GetBlob_ids();
1213         ITERATE ( CFixedBlob_ids, it, blob_ids ) {
1214             const CBlob_Info& info = *it;
1215             if ( !info.Matches(mask, sel) ) {
1216                 continue;
1217             }
1218             CLoadLockBlob blob(result, *info.GetBlob_id());
1219             if ( !blob.IsLoadedBlob() ) {
1220                 return false;
1221             }
1222         }
1223         return true;
1224     }
1225 
1226     class CCommandLoadBlobs : public CReadDispatcherCommand
1227     {
1228     public:
1229         typedef CLoadLockBlobIds TIds;
1230         typedef CReadDispatcher::TContentsMask TMask;
CCommandLoadBlobs(CReaderRequestResult & result,TIds ids,TMask mask,const SAnnotSelector * sel)1231         CCommandLoadBlobs(CReaderRequestResult& result,
1232                           TIds ids, TMask mask, const SAnnotSelector* sel)
1233             : CReadDispatcherCommand(result),
1234               m_Ids(ids), m_Mask(mask), m_Selector(sel)
1235             {
1236             }
1237 
IsDone(void)1238         bool IsDone(void)
1239             {
1240                 return s_AllBlobsAreLoaded(GetResult(),
1241                                            m_Ids, m_Mask, m_Selector);
1242             }
Execute(CReader & reader)1243         bool Execute(CReader& reader)
1244             {
1245                 return reader.LoadBlobs(GetResult(),
1246                                         m_Ids, m_Mask, m_Selector);
1247             }
GetErrMsg(void) const1248         string GetErrMsg(void) const
1249             {
1250                 return "LoadBlobs(CLoadInfoBlob_ids): "
1251                     "data not found";
1252             }
GetStatistics(void) const1253         CGBRequestStatistics::EStatType GetStatistics(void) const
1254             {
1255                 return CGBRequestStatistics::eStat_LoadBlob;
1256             }
GetStatisticsDescription(void) const1257         string GetStatisticsDescription(void) const
1258             {
1259                 return "blobs(...)";
1260             }
1261 
1262     private:
1263         TIds m_Ids;
1264         TMask m_Mask;
1265         const SAnnotSelector* m_Selector;
1266     };
1267     class CCommandLoadSeq_idBlobs : public CReadDispatcherCommand
1268     {
1269     public:
1270         typedef CSeq_id_Handle TKey;
1271         typedef CLoadLockBlobIds TIds;
1272         typedef CReadDispatcher::TContentsMask TMask;
CCommandLoadSeq_idBlobs(CReaderRequestResult & result,const TKey & key,TMask mask,const SAnnotSelector * sel)1273         CCommandLoadSeq_idBlobs(CReaderRequestResult& result,
1274                                 const TKey& key, TMask mask,
1275                                 const SAnnotSelector* sel)
1276             : CReadDispatcherCommand(result),
1277               m_Key(key), m_Ids(result, key, sel),
1278               m_Mask(mask), m_Selector(sel)
1279             {
1280             }
1281 
IsDone(void)1282         bool IsDone(void)
1283             {
1284                 return s_Blob_idsLoaded(m_Ids, GetResult(), m_Key) &&
1285                     s_AllBlobsAreLoaded(GetResult(),
1286                                         m_Ids, m_Mask, m_Selector);
1287             }
Execute(CReader & reader)1288         bool Execute(CReader& reader)
1289             {
1290                 return reader.LoadBlobs(GetResult(),
1291                                         m_Key, m_Mask, m_Selector);
1292             }
GetErrMsg(void) const1293         string GetErrMsg(void) const
1294             {
1295                 return "LoadBlobs("+m_Key.AsString()+"): "
1296                     "data not found";
1297             }
GetStatistics(void) const1298         CGBRequestStatistics::EStatType GetStatistics(void) const
1299             {
1300                 return CGBRequestStatistics::eStat_LoadBlob;
1301             }
GetStatisticsDescription(void) const1302         string GetStatisticsDescription(void) const
1303             {
1304                 return "blobs("+m_Key.AsString()+")";
1305             }
1306 
1307     private:
1308         TKey m_Key;
1309         TIds m_Ids;
1310         TMask m_Mask;
1311         const SAnnotSelector* m_Selector;
1312     };
1313 
1314     class CCommandLoadBlob : public CReadDispatcherCommand
1315     {
1316     public:
1317         typedef CBlob_id TKey;
1318         typedef CLoadLockBlob TLock;
CCommandLoadBlob(CReaderRequestResult & result,const TKey & key,const CBlob_Info * blob_info=0)1319         CCommandLoadBlob(CReaderRequestResult& result,
1320                          const TKey& key,
1321                          const CBlob_Info* blob_info = 0)
1322             : CReadDispatcherCommand(result),
1323               m_Key(key),
1324               m_Lock(result, key),
1325               m_BlobInfo(blob_info)
1326             {
1327             }
1328 
IsDone(void)1329         bool IsDone(void)
1330             {
1331                 return m_Lock.IsLoadedBlob();
1332             }
Execute(CReader & reader)1333         bool Execute(CReader& reader)
1334             {
1335                 if ( m_BlobInfo ) {
1336                     return reader.LoadBlob(GetResult(), *m_BlobInfo);
1337                 }
1338                 else {
1339                     return reader.LoadBlob(GetResult(), m_Key);
1340                 }
1341             }
GetErrMsg(void) const1342         string GetErrMsg(void) const
1343             {
1344                 return "LoadBlob("+m_Key.ToString()+"): "
1345                     "data not found";
1346             }
GetStatistics(void) const1347         CGBRequestStatistics::EStatType GetStatistics(void) const
1348             {
1349                 return CGBRequestStatistics::eStat_LoadBlob;
1350             }
GetStatisticsDescription(void) const1351         string GetStatisticsDescription(void) const
1352             {
1353                 return "blob("+m_Key.ToString()+")";
1354             }
1355 
1356     private:
1357         TKey m_Key;
1358         TLock m_Lock;
1359         const CBlob_Info* m_BlobInfo;
1360     };
1361 
1362     class CCommandLoadChunk : public CReadDispatcherCommand
1363     {
1364     public:
1365         typedef CBlob_id TKey;
1366         typedef CLoadLockBlob TLock;
1367         typedef int TChunkId;
1368         typedef CTSE_Chunk_Info TChunkInfo;
CCommandLoadChunk(CReaderRequestResult & result,const TKey & key,TChunkId chunk_id)1369         CCommandLoadChunk(CReaderRequestResult& result,
1370                           const TKey& key,
1371                           TChunkId chunk_id)
1372             : CReadDispatcherCommand(result),
1373               m_Key(key), m_Lock(result, key, chunk_id),
1374               m_ChunkId(chunk_id)
1375             {
1376             }
1377 
IsDone(void)1378         bool IsDone(void)
1379             {
1380                 return m_Lock.IsLoadedChunk();
1381             }
Execute(CReader & reader)1382         bool Execute(CReader& reader)
1383             {
1384                 return reader.LoadChunk(GetResult(), m_Key, m_ChunkId);
1385             }
GetErrMsg(void) const1386         string GetErrMsg(void) const
1387             {
1388                 return "LoadChunk("+m_Key.ToString()+", "+
1389                     NStr::IntToString(m_ChunkId)+"): "
1390                     "data not found";
1391             }
GetStatistics(void) const1392         CGBRequestStatistics::EStatType GetStatistics(void) const
1393             {
1394                 return CGBRequestStatistics::eStat_LoadChunk;
1395             }
GetStatisticsDescription(void) const1396         string GetStatisticsDescription(void) const
1397             {
1398                 return "chunk("+m_Key.ToString()+"."+
1399                     NStr::IntToString(m_ChunkId)+")";
1400             }
1401 
1402     private:
1403         TKey m_Key;
1404         TLock m_Lock;
1405         TChunkId m_ChunkId;
1406     };
1407 
1408     class CCommandLoadChunks : public CReadDispatcherCommand
1409     {
1410     public:
1411         typedef CBlob_id TKey;
1412         typedef CLoadLockBlob TLock;
1413         typedef int TChunkId;
1414         typedef vector<TChunkId> TChunkIds;
1415         typedef CTSE_Chunk_Info TChunkInfo;
CCommandLoadChunks(CReaderRequestResult & result,const TKey & key,const TChunkIds chunk_ids)1416         CCommandLoadChunks(CReaderRequestResult& result,
1417                            const TKey& key,
1418                            const TChunkIds chunk_ids)
1419             : CReadDispatcherCommand(result),
1420               m_Key(key), m_Lock(result, key),
1421               m_ChunkIds(chunk_ids)
1422             {
1423             }
1424 
IsDone(void)1425         bool IsDone(void)
1426             {
1427                 ITERATE ( TChunkIds, it, m_ChunkIds ) {
1428                     if ( !m_Lock.IsLoadedChunk(*it) ) {
1429                         return false;
1430                     }
1431                 }
1432                 return true;
1433             }
Execute(CReader & reader)1434         bool Execute(CReader& reader)
1435             {
1436                 return reader.LoadChunks(GetResult(), m_Key, m_ChunkIds);
1437             }
GetErrMsg(void) const1438         string GetErrMsg(void) const
1439             {
1440                 CNcbiOstrstream str;
1441                 str << "LoadChunks(" << m_Key.ToString() << ", {";
1442                 int cnt = 0;
1443                 ITERATE ( TChunkIds, it, m_ChunkIds ) {
1444                     if ( !m_Lock.IsLoadedChunk(*it) ) {
1445                         if ( cnt++ ) str << ',';
1446                         str << ' ' << *it;
1447                     }
1448                 }
1449                 str << " }): data not found";
1450                 return CNcbiOstrstreamToString(str);
1451             }
GetStatistics(void) const1452         CGBRequestStatistics::EStatType GetStatistics(void) const
1453             {
1454                 return CGBRequestStatistics::eStat_LoadChunk;
1455             }
GetStatisticsDescription(void) const1456         string GetStatisticsDescription(void) const
1457             {
1458                 CNcbiOstrstream str;
1459                 int cnt = 0;
1460                 ITERATE ( TChunkIds, it, m_ChunkIds ) {
1461                     int id = *it;
1462                     if ( id >= 0 && id < kMax_Int ) {
1463                         if ( !cnt ) {
1464                             str << "chunk(" << m_Key.ToString() << '.';
1465                             cnt = 1;
1466                         }
1467                         else {
1468                             str << ',';
1469                         }
1470                         str << id;
1471                     }
1472                 }
1473                 if ( !cnt ) {
1474                     str << "blob(" << m_Key.ToString();
1475                 }
1476                 str << ')';
1477                 return CNcbiOstrstreamToString(str);
1478             }
1479 
1480     private:
1481         TKey m_Key;
1482         TLock m_Lock;
1483         TChunkIds m_ChunkIds;
1484     };
1485 
1486     class CCommandLoadBlobSet : public CReadDispatcherCommand
1487     {
1488     public:
1489         typedef CReadDispatcher::TIds TIds;
CCommandLoadBlobSet(CReaderRequestResult & result,const TIds & seq_ids)1490         CCommandLoadBlobSet(CReaderRequestResult& result,
1491                             const TIds& seq_ids)
1492             : CReadDispatcherCommand(result),
1493               m_Ids(seq_ids)
1494             {
1495             }
1496 
IsDone(void)1497         bool IsDone(void)
1498             {
1499                 CReaderRequestResult& result = GetResult();
1500                 ITERATE(TIds, id, m_Ids) {
1501                     CLoadLockBlobIds blob_ids(result, *id, 0);
1502                     if ( !blob_ids ) {
1503                         return false;
1504                     }
1505                     if ( !s_Blob_idsLoaded(blob_ids, result, *id) ) {
1506                         return false;
1507                     }
1508                     CFixedBlob_ids ids = blob_ids.GetBlob_ids();
1509                     ITERATE ( CFixedBlob_ids, it, ids ) {
1510                         if ( !it->Matches(fBlobHasCore, 0) ) {
1511                             continue;
1512                         }
1513                         CLoadLockBlob blob(result, *it->GetBlob_id());
1514                         if ( !blob.IsLoadedBlob() ) {
1515                             return false;
1516                         }
1517                     }
1518                 }
1519                 return true;
1520             }
Execute(CReader & reader)1521         bool Execute(CReader& reader)
1522             {
1523                 return reader.LoadBlobSet(GetResult(), m_Ids);
1524             }
GetErrMsg(void) const1525         string GetErrMsg(void) const
1526             {
1527                 return "LoadBlobSet(" +
1528                     NStr::SizetToString(m_Ids.size()) + " ids): "
1529                     "data not found";
1530             }
GetStatistics(void) const1531         CGBRequestStatistics::EStatType GetStatistics(void) const
1532             {
1533                 return CGBRequestStatistics::eStat_LoadBlob;
1534             }
GetStatisticsDescription(void) const1535         string GetStatisticsDescription(void) const
1536             {
1537                 return "blobs(" +
1538                     NStr::SizetToString(m_Ids.size()) + " ids)";
1539             }
1540 
1541     private:
1542         TIds    m_Ids;
1543     };
1544 }
1545 
1546 BEGIN_LOCAL_NAMESPACE;
1547 
1548 struct SSaveResultLevel
1549 {
SSaveResultLevelSSaveResultLevel1550     SSaveResultLevel(CReadDispatcherCommand& command)
1551         : m_Command(command),
1552           m_SavedLevel(command.GetResult().GetLevel())
1553         {
1554         }
1555 
~SSaveResultLevelSSaveResultLevel1556     ~SSaveResultLevel(void)
1557         {
1558             m_Command.GetResult().SetLevel(m_SavedLevel);
1559         }
1560 
1561     CReadDispatcherCommand& m_Command;
1562     CReadDispatcher::TLevel m_SavedLevel;
1563 };
1564 
1565 END_LOCAL_NAMESPACE;
1566 
1567 
Process(CReadDispatcherCommand & command,const CReader * asking_reader)1568 void CReadDispatcher::Process(CReadDispatcherCommand& command,
1569                               const CReader* asking_reader)
1570 {
1571     CheckReaders();
1572 
1573     if ( command.IsDone() ) {
1574         return;
1575     }
1576 
1577     SSaveResultLevel save_level(command);
1578     NON_CONST_ITERATE ( TReaders, rdr, m_Readers ) {
1579         if ( asking_reader ) {
1580             // skip all readers before the asking one
1581             if ( rdr->second == asking_reader ) {
1582                 // found the asking reader, start processing next readers
1583                 asking_reader = 0;
1584             }
1585             continue;
1586         }
1587         CReader& reader = *rdr->second;
1588         command.GetResult().SetLevel(rdr->first);
1589         int retry_count = 0;
1590         int max_retry_count = reader.GetRetryCount();
1591         do {
1592             ++retry_count;
1593             try {
1594                 CReaderRequestResultRecursion r(command.GetResult());
1595                 if ( !command.Execute(reader) ) {
1596                     retry_count = kMax_Int;
1597                 }
1598                 LogStat(command, r);
1599             }
1600             catch ( CLoaderException& exc ) {
1601                 if ( exc.GetErrCode() == exc.eRepeatAgain ) {
1602                     // no actual error, just restart
1603                     --retry_count;
1604                     LOG_POST_X(10, Info<<
1605                                "CReadDispatcher: connection reopened "
1606                                "due to inactivity timeout");
1607                 }
1608                 else if ( exc.GetErrCode() == exc.eNoConnection ) {
1609                     LOG_POST_X(1, Warning<<
1610                                "CReadDispatcher: Exception: "<<exc);
1611                     retry_count = kMax_Int;
1612                 }
1613                 else {
1614                     if ( retry_count >= max_retry_count &&
1615                          !command.MayBeSkipped() &&
1616                          !reader.MayBeSkippedOnErrors() ) {
1617                         throw;
1618                     }
1619                     LOG_POST_X(2, Warning<<
1620                                "CReadDispatcher: Exception: "<<exc);
1621                 }
1622             }
1623             catch ( CException& exc ) {
1624                 // error in the command
1625                 if ( retry_count >= max_retry_count &&
1626                      !command.MayBeSkipped() &&
1627                      !reader.MayBeSkippedOnErrors() ) {
1628                     throw;
1629                 }
1630                 LOG_POST_X(3, Warning <<
1631                            "CReadDispatcher: Exception: "<<exc);
1632             }
1633             catch ( exception& exc ) {
1634                 // error in the command
1635                 if ( retry_count >= max_retry_count &&
1636                      !command.MayBeSkipped() &&
1637                      !reader.MayBeSkippedOnErrors() ) {
1638                     throw;
1639                 }
1640                 LOG_POST_X(4, Warning <<
1641                            "CReadDispatcher: Exception: "<<exc.what());
1642             }
1643             if ( command.IsDone() ) {
1644                 return;
1645             }
1646         } while ( retry_count < max_retry_count );
1647         if ( !command.MayBeSkipped() &&
1648              !reader.MayBeSkippedOnErrors() &&
1649              !s_AllowIncompleteCommands() ) {
1650             NCBI_THROW(CLoaderException, eLoaderFailed, command.GetErrMsg());
1651         }
1652     }
1653 
1654     if ( !command.MayBeSkipped() &&
1655          !s_AllowIncompleteCommands() ) {
1656         NCBI_THROW(CLoaderException, eLoaderFailed, command.GetErrMsg());
1657     }
1658 }
1659 
1660 
LoadSeq_idSeq_ids(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1661 void CReadDispatcher::LoadSeq_idSeq_ids(CReaderRequestResult& result,
1662                                         const CSeq_id_Handle& seq_id)
1663 {
1664     CCommandLoadSeq_idSeq_ids command(result, seq_id);
1665     Process(command);
1666 }
1667 
1668 
LoadSeq_idGi(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1669 void CReadDispatcher::LoadSeq_idGi(CReaderRequestResult& result,
1670                                    const CSeq_id_Handle& seq_id)
1671 {
1672     CCommandLoadSeq_idGi command(result, seq_id);
1673     Process(command);
1674 }
1675 
1676 
LoadSeq_idAccVer(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1677 void CReadDispatcher::LoadSeq_idAccVer(CReaderRequestResult& result,
1678                                     const CSeq_id_Handle& seq_id)
1679 {
1680     CCommandLoadSeq_idAccVer command(result, seq_id);
1681     Process(command);
1682 }
1683 
1684 
LoadSeq_idLabel(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1685 void CReadDispatcher::LoadSeq_idLabel(CReaderRequestResult& result,
1686                                       const CSeq_id_Handle& seq_id)
1687 {
1688     CCommandLoadSeq_idLabel command(result, seq_id);
1689     Process(command);
1690 }
1691 
1692 
LoadSeq_idTaxId(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1693 void CReadDispatcher::LoadSeq_idTaxId(CReaderRequestResult& result,
1694                                       const CSeq_id_Handle& seq_id)
1695 {
1696     CCommandLoadSeq_idTaxId command(result, seq_id);
1697     Process(command);
1698 }
1699 
1700 
LoadSequenceHash(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1701 void CReadDispatcher::LoadSequenceHash(CReaderRequestResult& result,
1702                                        const CSeq_id_Handle& seq_id)
1703 {
1704     CCommandLoadSequenceHash command(result, seq_id);
1705     Process(command);
1706 }
1707 
1708 
LoadSequenceLength(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1709 void CReadDispatcher::LoadSequenceLength(CReaderRequestResult& result,
1710                                          const CSeq_id_Handle& seq_id)
1711 {
1712     CCommandLoadSequenceLength command(result, seq_id);
1713     Process(command);
1714 }
1715 
1716 
LoadSequenceType(CReaderRequestResult & result,const CSeq_id_Handle & seq_id)1717 void CReadDispatcher::LoadSequenceType(CReaderRequestResult& result,
1718                                        const CSeq_id_Handle& seq_id)
1719 {
1720     CCommandLoadSequenceType command(result, seq_id);
1721     Process(command);
1722 }
1723 
1724 
LoadAccVers(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TIds & ret)1725 void CReadDispatcher::LoadAccVers(CReaderRequestResult& result,
1726                                   const TIds& ids, TLoaded& loaded, TIds& ret)
1727 {
1728     CCommandLoadAccVers command(result, ids, loaded, ret);
1729     Process(command);
1730 }
1731 
1732 
LoadGis(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TGis & ret)1733 void CReadDispatcher::LoadGis(CReaderRequestResult& result,
1734                               const TIds& ids, TLoaded& loaded, TGis& ret)
1735 {
1736     CCommandLoadGis command(result, ids, loaded, ret);
1737     Process(command);
1738 }
1739 
1740 
LoadLabels(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TLabels & ret)1741 void CReadDispatcher::LoadLabels(CReaderRequestResult& result,
1742                                  const TIds& ids, TLoaded& loaded, TLabels& ret)
1743 {
1744     CCommandLoadLabels command(result, ids, loaded, ret);
1745     Process(command);
1746 }
1747 
1748 
LoadTaxIds(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TTaxIds & ret)1749 void CReadDispatcher::LoadTaxIds(CReaderRequestResult& result,
1750                                  const TIds& ids, TLoaded& loaded, TTaxIds& ret)
1751 {
1752     CCommandLoadTaxIds command(result, ids, loaded, ret);
1753     Process(command);
1754 }
1755 
1756 
LoadHashes(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,THashes & ret,TKnown & known)1757 void CReadDispatcher::LoadHashes(CReaderRequestResult& result,
1758                                  const TIds& ids, TLoaded& loaded,
1759                                  THashes& ret, TKnown& known)
1760 {
1761     CCommandLoadHashes command(result, ids, loaded, ret, known);
1762     Process(command);
1763 }
1764 
1765 
LoadLengths(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TLengths & ret)1766 void CReadDispatcher::LoadLengths(CReaderRequestResult& result,
1767                                   const TIds& ids, TLoaded& loaded, TLengths& ret)
1768 {
1769     CCommandLoadLengths command(result, ids, loaded, ret);
1770     Process(command);
1771 }
1772 
1773 
LoadTypes(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TTypes & ret)1774 void CReadDispatcher::LoadTypes(CReaderRequestResult& result,
1775                                 const TIds& ids, TLoaded& loaded, TTypes& ret)
1776 {
1777     CCommandLoadTypes command(result, ids, loaded, ret);
1778     Process(command);
1779 }
1780 
1781 
LoadStates(CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TStates & ret)1782 void CReadDispatcher::LoadStates(CReaderRequestResult& result,
1783                                  const TIds& ids, TLoaded& loaded, TStates& ret)
1784 {
1785     CCommandLoadStates command(result, ids, loaded, ret);
1786     Process(command);
1787 }
1788 
1789 
LoadSeq_idBlob_ids(CReaderRequestResult & result,const CSeq_id_Handle & seq_id,const SAnnotSelector * sel)1790 void CReadDispatcher::LoadSeq_idBlob_ids(CReaderRequestResult& result,
1791                                          const CSeq_id_Handle& seq_id,
1792                                          const SAnnotSelector* sel)
1793 {
1794     CCommandLoadSeq_idBlob_ids command(result, seq_id, sel);
1795     Process(command);
1796 }
1797 
1798 
LoadBlobState(CReaderRequestResult & result,const TBlobId & blob_id)1799 void CReadDispatcher::LoadBlobState(CReaderRequestResult& result,
1800                                     const TBlobId& blob_id)
1801 {
1802     CCommandLoadBlobState command(result, blob_id);
1803     Process(command);
1804 }
1805 
LoadBlobVersion(CReaderRequestResult & result,const TBlobId & blob_id,const CReader * asking_reader)1806 void CReadDispatcher::LoadBlobVersion(CReaderRequestResult& result,
1807                                       const TBlobId& blob_id,
1808                                       const CReader* asking_reader)
1809 {
1810     CCommandLoadBlobVersion command(result, blob_id);
1811     Process(command, asking_reader);
1812 }
1813 
LoadBlobs(CReaderRequestResult & result,const CSeq_id_Handle & seq_id,TContentsMask mask,const SAnnotSelector * sel)1814 void CReadDispatcher::LoadBlobs(CReaderRequestResult& result,
1815                                 const CSeq_id_Handle& seq_id,
1816                                 TContentsMask mask,
1817                                 const SAnnotSelector* sel)
1818 {
1819     CCommandLoadSeq_idBlobs command(result, seq_id, mask, sel);
1820     Process(command);
1821 }
1822 
1823 
LoadBlobs(CReaderRequestResult & result,const CLoadLockBlobIds & blobs,TContentsMask mask,const SAnnotSelector * sel)1824 void CReadDispatcher::LoadBlobs(CReaderRequestResult& result,
1825                                 const CLoadLockBlobIds& blobs,
1826                                 TContentsMask mask,
1827                                 const SAnnotSelector* sel)
1828 {
1829     CCommandLoadBlobs command(result, blobs, mask, sel);
1830     Process(command);
1831 }
1832 
1833 
LoadBlob(CReaderRequestResult & result,const CBlob_id & blob_id)1834 void CReadDispatcher::LoadBlob(CReaderRequestResult& result,
1835                                const CBlob_id& blob_id)
1836 {
1837     CCommandLoadBlob command(result, blob_id);
1838     Process(command);
1839 }
1840 
1841 
LoadBlob(CReaderRequestResult & result,const CBlob_Info & blob_info)1842 void CReadDispatcher::LoadBlob(CReaderRequestResult& result,
1843                                const CBlob_Info& blob_info)
1844 {
1845     CCommandLoadBlob command(result, *blob_info.GetBlob_id(), &blob_info);
1846     Process(command);
1847 }
1848 
1849 
LoadChunk(CReaderRequestResult & result,const TBlobId & blob_id,TChunkId chunk_id)1850 void CReadDispatcher::LoadChunk(CReaderRequestResult& result,
1851                                 const TBlobId& blob_id, TChunkId chunk_id)
1852 {
1853     CCommandLoadChunk command(result, blob_id, chunk_id);
1854     Process(command);
1855 }
1856 
1857 
LoadChunks(CReaderRequestResult & result,const TBlobId & blob_id,const TChunkIds & chunk_ids)1858 void CReadDispatcher::LoadChunks(CReaderRequestResult& result,
1859                                  const TBlobId& blob_id,
1860                                  const TChunkIds& chunk_ids)
1861 {
1862     CCommandLoadChunks command(result, blob_id, chunk_ids);
1863     Process(command);
1864 }
1865 
1866 
LoadBlobSet(CReaderRequestResult & result,const TIds & seq_ids)1867 void CReadDispatcher::LoadBlobSet(CReaderRequestResult& result,
1868                                   const TIds& seq_ids)
1869 {
1870     CCommandLoadBlobSet command(result, seq_ids);
1871     Process(command);
1872 }
1873 
1874 
SetBlobState(size_t i,CReaderRequestResult & result,const TIds & ids,TLoaded & loaded,TStates & ret)1875 bool CReadDispatcher::SetBlobState(size_t i,
1876                                    CReaderRequestResult& result,
1877                                    const TIds& ids, TLoaded& loaded,
1878                                    TStates& ret)
1879 {
1880     if ( loaded[i] || CannotProcess(ids[i]) ) {
1881         return true;
1882     }
1883     CLoadLockBlobIds lock(result, ids[i]);
1884     if ( lock.IsLoaded() ) {
1885         CFixedBlob_ids blob_ids = lock.GetBlob_ids();
1886         if ( !blob_ids.IsFound() ) {
1887             ret[i] = lock.GetState();
1888             return true;
1889         }
1890         ITERATE ( CFixedBlob_ids, it, blob_ids ) {
1891             if ( it->Matches(fBlobHasCore, 0) ) {
1892                 CFixedBlob_ids::TState state = lock.GetState();
1893                 if ( state == CFixedBlob_ids::kUnknownState ) {
1894                     CLoadLockBlobState state_lock(result, *it->GetBlob_id());
1895                     if ( state_lock.IsLoadedBlobState() ) {
1896                         state = state_lock.GetBlobState();
1897                     }
1898                 }
1899                 if ( state != CFixedBlob_ids::kUnknownState ) {
1900                     ret[i] = state;
1901                     loaded[i] = true;
1902                     return true;
1903                 }
1904                 return false;
1905             }
1906         }
1907     }
1908     else {
1909         CLoadLockSeqIds ids_lock(result, ids[i], eAlreadyLoaded);
1910         if ( ids_lock && !ids_lock.GetData().IsFound() ) {
1911             ret[i] = ids_lock.GetState();
1912             return true;
1913         }
1914     }
1915     return false;
1916 }
1917 
1918 
LogStat(CReadDispatcherCommand & command,CReaderRequestResultRecursion & recursion)1919 void CReadDispatcher::LogStat(CReadDispatcherCommand& command,
1920                               CReaderRequestResultRecursion& recursion)
1921 {
1922     CReaderRequestResult& result = command.GetResult();
1923     double time = recursion.GetCurrentRequestTime();
1924     size_t count = command.GetStatisticsCount();
1925     CGBRequestStatistics& stat = sx_Statistics[command.GetStatistics()];
1926     stat.AddTime(time, count);
1927     if ( CollectStatistics() >= 2 ) {
1928         string descr = command.GetStatisticsDescription();
1929         const CSeq_id_Handle& idh = result.GetRequestedId();
1930         if ( idh ) {
1931             descr = descr + " for " + idh.AsString();
1932         }
1933         LOG_POST_X(8, setw(recursion.GetRecursionLevel()) << "" <<
1934                    "Dispatcher: read " <<
1935                    descr << " in " <<
1936                    setiosflags(ios::fixed) <<
1937                    setprecision(3) << (time*1000) << " ms");
1938     }
1939 }
1940 
1941 
LogStat(CReadDispatcherCommand & command,CReaderRequestResultRecursion & recursion,double size)1942 void CReadDispatcher::LogStat(CReadDispatcherCommand& command,
1943                               CReaderRequestResultRecursion& recursion,
1944                               double size)
1945 {
1946     CReaderRequestResult& result = command.GetResult();
1947     double time = recursion.GetCurrentRequestTime();
1948     CGBRequestStatistics& stat = sx_Statistics[command.GetStatistics()];
1949     stat.AddTimeSize(time, size);
1950     if ( CollectStatistics() >= 2 ) {
1951         string descr = command.GetStatisticsDescription();
1952         const CSeq_id_Handle& idh = result.GetRequestedId();
1953         if ( idh ) {
1954             descr = descr + " for " + idh.AsString();
1955         }
1956         LOG_POST_X(9, setw(recursion.GetRecursionLevel()) << "" <<
1957                    descr << " in " <<
1958                    setiosflags(ios::fixed) <<
1959                    setprecision(3) <<
1960                    (time*1000) << " ms (" <<
1961                    setprecision(2) <<
1962                    (size/1024.0) << " kB " <<
1963                    setprecision(2) <<
1964                    (size/time/1024) << " kB/s)");
1965     }
1966 }
1967 
1968 
1969 END_SCOPE(objects)
1970 END_NCBI_SCOPE
1971