|
NCBI C++ ToolKit
|
00001 /* $Id: dispatcher.cpp 50836 2011-08-11 16:49:59Z vasilche $ 00002 * =========================================================================== 00003 * PUBLIC DOMAIN NOTICE 00004 * National Center for Biotechnology Information 00005 * 00006 * This software/database is a "United States Government Work" under the 00007 * terms of the United States Copyright Act. It was written as part of 00008 * the author's official duties as a United States Government employee and 00009 * thus cannot be copyrighted. This software/database is freely available 00010 * to the public for use. The National Library of Medicine and the U.S. 00011 * Government have not placed any restriction on its use or reproduction. 00012 * 00013 * Although all reasonable efforts have been taken to ensure the accuracy 00014 * and reliability of the software and data, the NLM and the U.S. 00015 * Government do not and cannot warrant the performance or results that 00016 * may be obtained by using this software or data. The NLM and the U.S. 00017 * Government disclaim all warranties, express or implied, including 00018 * warranties of performance, merchantability or fitness for any particular 00019 * purpose. 00020 * 00021 * Please cite the author in any work or product based on this material. 00022 * =========================================================================== 00023 * 00024 * Author: Anton Butanaev, Eugene Vasilchenko 00025 * 00026 * File Description: Base data reader interface 00027 * 00028 */ 00029 00030 #include <ncbi_pch.hpp> 00031 #include <objtools/data_loaders/genbank/dispatcher.hpp> 00032 #include <objtools/data_loaders/genbank/reader.hpp> 00033 #include <objtools/data_loaders/genbank/writer.hpp> 00034 #include <objtools/data_loaders/genbank/processor.hpp> 00035 #include <objtools/data_loaders/genbank/request_result.hpp> 00036 #include <objtools/data_loaders/genbank/statistics.hpp> 00037 #include <objtools/error_codes.hpp> 00038 #include <objmgr/objmgr_exception.hpp> 00039 #include <objmgr/impl/tse_split_info.hpp> 00040 #include <objmgr/impl/tse_chunk_info.hpp> 00041 00042 00043 #define NCBI_USE_ERRCODE_X Objtools_Rd_Disp 00044 00045 BEGIN_NCBI_SCOPE 00046 00047 NCBI_DEFINE_ERR_SUBCODE_X(10); 00048 00049 BEGIN_SCOPE(objects) 00050 00051 ///////////////////////////////////////////////////////////////////////////// 00052 // CReadDispatcher 00053 ///////////////////////////////////////////////////////////////////////////// 00054 00055 00056 static CGBRequestStatistics sx_Statistics[CGBRequestStatistics::eStats_Count] = 00057 { 00058 CGBRequestStatistics("resolved", "string ids"), 00059 CGBRequestStatistics("resolved", "seq-ids"), 00060 CGBRequestStatistics("resolved", "gis"), 00061 CGBRequestStatistics("resolved", "accs"), 00062 CGBRequestStatistics("resolved", "labels"), 00063 CGBRequestStatistics("resolved", "taxids"), 00064 CGBRequestStatistics("resolved", "blob ids"), 00065 CGBRequestStatistics("resolved", "blob versions"), 00066 CGBRequestStatistics("loaded", "blob data"), 00067 CGBRequestStatistics("loaded", "SNP data"), 00068 CGBRequestStatistics("loaded", "split data"), 00069 CGBRequestStatistics("loaded", "chunk data"), 00070 CGBRequestStatistics("parsed", "blob data"), 00071 CGBRequestStatistics("parsed", "SNP data"), 00072 CGBRequestStatistics("parsed", "split data"), 00073 CGBRequestStatistics("parsed", "chunk data") 00074 }; 00075 00076 CGBRequestStatistics::CGBRequestStatistics(const char* action, 00077 const char* entity) 00078 : m_Action(action), m_Entity(entity), 00079 m_Count(0), m_Time(0), m_Size(0) 00080 { 00081 } 00082 00083 const CGBRequestStatistics& CGBRequestStatistics::GetStatistics(EStatType type) 00084 { 00085 if ( type < eStat_First || type > eStat_Last ) { 00086 NCBI_THROW_FMT(CLoaderException, eOtherError, 00087 "CGBRequestStatistics::GetStatistics: " 00088 "invalid statistics type: "<<type); 00089 } 00090 return sx_Statistics[type]; 00091 } 00092 00093 void CGBRequestStatistics::PrintStat(void) const 00094 { 00095 size_t count = GetCount(); 00096 if ( count > 0 ) { 00097 double time = GetTime(); 00098 double size = GetSize(); 00099 if ( size <= 0 ) { 00100 LOG_POST_X(5, "GBLoader: " << GetAction() << ' ' << 00101 count << ' ' << GetEntity() << " in " << 00102 setiosflags(ios::fixed) << 00103 setprecision(3) << 00104 (time) << " s (" << 00105 (time*1000/count) << " ms/one)"); 00106 } 00107 else { 00108 LOG_POST_X(6, "GBLoader: " << GetAction() << ' ' << 00109 count << ' ' << GetEntity() << " in " << 00110 setiosflags(ios::fixed) << 00111 setprecision(3) << 00112 (time) << " s (" << 00113 (time*1000/count) << " ms/one)" << 00114 setprecision(2) << " (" << 00115 (size/1024.0) << " kB " << 00116 (size/time/1024) << " kB/s)"); 00117 } 00118 } 00119 } 00120 00121 00122 void CGBRequestStatistics::PrintStatistics(void) 00123 { 00124 for ( int type = eStat_First; type <= eStat_Last; ++type ) { 00125 sx_Statistics[type].PrintStat(); 00126 } 00127 } 00128 00129 inline 00130 int CReadDispatcher::CollectStatistics(void) 00131 { 00132 static NCBI_PARAM_TYPE(GENBANK, READER_STATS) s_Value; 00133 return s_Value.Get(); 00134 } 00135 00136 00137 CReadDispatcher::CReadDispatcher(void) 00138 { 00139 CollectStatistics(); 00140 CProcessor::RegisterAllProcessors(*this); 00141 } 00142 00143 00144 CReadDispatcher::~CReadDispatcher(void) 00145 { 00146 if ( CollectStatistics() > 0 ) { 00147 CGBRequestStatistics::PrintStatistics(); 00148 } 00149 } 00150 00151 00152 void CReadDispatcher::InsertReader(TLevel level, CRef<CReader> reader) 00153 { 00154 if ( !reader ) { 00155 return; 00156 } 00157 00158 m_Readers[level] = reader; 00159 reader->m_Dispatcher = this; 00160 } 00161 00162 00163 void CReadDispatcher::InsertWriter(TLevel level, CRef<CWriter> writer) 00164 { 00165 if ( !writer ) { 00166 return; 00167 } 00168 00169 m_Writers[level] = writer; 00170 } 00171 00172 00173 void CReadDispatcher::InsertProcessor(CRef<CProcessor> processor) 00174 { 00175 if ( !processor ) { 00176 return; 00177 } 00178 00179 m_Processors[processor->GetType()] = processor; 00180 } 00181 00182 00183 CWriter* CReadDispatcher::GetWriter(const CReaderRequestResult& result, 00184 CWriter::EType type) const 00185 { 00186 ITERATE ( TWriters, i, m_Writers ) { 00187 if ( i->first >= result.GetLevel() ) { 00188 break; 00189 } 00190 if ( i->second->CanWrite(type) ) { 00191 return const_cast<CWriter*>(i->second.GetPointer()); 00192 } 00193 } 00194 return 0; 00195 } 00196 00197 00198 const CProcessor& CReadDispatcher::GetProcessor(CProcessor::EType type) const 00199 { 00200 TProcessors::const_iterator iter = m_Processors.find(type); 00201 if ( iter == m_Processors.end() ) { 00202 NCBI_THROW_FMT(CLoaderException, eLoaderFailed, 00203 "CReadDispatcher::GetProcessor: " 00204 "processor unknown: "<<type); 00205 } 00206 return *iter->second; 00207 } 00208 00209 00210 void CReadDispatcher::CheckReaders(void) const 00211 { 00212 if ( m_Readers.empty() ) { 00213 NCBI_THROW(CLoaderException, eLoaderFailed, "no reader loaded"); 00214 } 00215 } 00216 00217 00218 void CReadDispatcher::ResetCaches(void) 00219 { 00220 NON_CONST_ITERATE(TReaders, rd, m_Readers) { 00221 rd->second->ResetCache(); 00222 } 00223 NON_CONST_ITERATE(TWriters, wr, m_Writers) { 00224 wr->second->ResetCache(); 00225 } 00226 } 00227 00228 00229 CReadDispatcherCommand::CReadDispatcherCommand(CReaderRequestResult& result) 00230 : m_Result(result) 00231 { 00232 } 00233 00234 00235 CReadDispatcherCommand::~CReadDispatcherCommand(void) 00236 { 00237 } 00238 00239 00240 bool CReadDispatcherCommand::MayBeSkipped(void) const 00241 { 00242 return false; 00243 } 00244 00245 00246 namespace { 00247 class CCommandLoadStringSeq_ids : public CReadDispatcherCommand 00248 { 00249 public: 00250 typedef string TKey; 00251 typedef CLoadLockSeq_ids TLock; 00252 CCommandLoadStringSeq_ids(CReaderRequestResult& result, 00253 const TKey& key) 00254 : CReadDispatcherCommand(result), 00255 m_Key(key), m_Lock(result, key) 00256 { 00257 } 00258 00259 bool IsDone(void) 00260 { 00261 return m_Lock.IsLoaded(); 00262 } 00263 bool Execute(CReader& reader) 00264 { 00265 return reader.LoadStringSeq_ids(GetResult(), m_Key); 00266 } 00267 string GetErrMsg(void) const 00268 { 00269 return "LoadStringSeq_ids("+m_Key+"): " 00270 "data not found"; 00271 } 00272 CGBRequestStatistics::EStatType GetStatistics(void) const 00273 { 00274 return CGBRequestStatistics::eStat_StringSeq_ids; 00275 } 00276 string GetStatisticsDescription(void) const 00277 { 00278 return "Seq-ids(string "+m_Key+")"; 00279 } 00280 00281 private: 00282 TKey m_Key; 00283 TLock m_Lock; 00284 }; 00285 00286 class CCommandLoadSeq_idSeq_ids : public CReadDispatcherCommand 00287 { 00288 public: 00289 typedef CSeq_id_Handle TKey; 00290 typedef CLoadLockSeq_ids TLock; 00291 CCommandLoadSeq_idSeq_ids(CReaderRequestResult& result, 00292 const TKey& key) 00293 : CReadDispatcherCommand(result), 00294 m_Key(key), m_Lock(result, key) 00295 { 00296 } 00297 00298 bool IsDone(void) 00299 { 00300 return m_Lock.IsLoaded(); 00301 } 00302 bool Execute(CReader& reader) 00303 { 00304 return reader.LoadSeq_idSeq_ids(GetResult(), m_Key); 00305 } 00306 string GetErrMsg(void) const 00307 { 00308 return "LoadSeq_idSeq_ids("+m_Key.AsString()+"): " 00309 "data not found"; 00310 } 00311 CGBRequestStatistics::EStatType GetStatistics(void) const 00312 { 00313 return CGBRequestStatistics::eStat_Seq_idSeq_ids; 00314 } 00315 string GetStatisticsDescription(void) const 00316 { 00317 return "Seq-ids("+m_Key.AsString()+")"; 00318 } 00319 00320 private: 00321 TKey m_Key; 00322 TLock m_Lock; 00323 }; 00324 00325 class CCommandLoadSeq_idGi : public CReadDispatcherCommand 00326 { 00327 public: 00328 typedef CSeq_id_Handle TKey; 00329 typedef CLoadLockSeq_ids TLock; 00330 CCommandLoadSeq_idGi(CReaderRequestResult& result, 00331 const TKey& key) 00332 : CReadDispatcherCommand(result), 00333 m_Key(key), m_Lock(result, key) 00334 { 00335 } 00336 00337 bool IsDone(void) 00338 { 00339 return m_Lock->IsLoadedGi(); 00340 } 00341 bool Execute(CReader& reader) 00342 { 00343 return reader.LoadSeq_idGi(GetResult(), m_Key); 00344 } 00345 string GetErrMsg(void) const 00346 { 00347 return "LoadSeq_idGi("+m_Key.AsString()+"): " 00348 "data not found"; 00349 } 00350 CGBRequestStatistics::EStatType GetStatistics(void) const 00351 { 00352 return CGBRequestStatistics::eStat_Seq_idGi; 00353 } 00354 string GetStatisticsDescription(void) const 00355 { 00356 return "gi("+m_Key.AsString()+")"; 00357 } 00358 00359 private: 00360 TKey m_Key; 00361 TLock m_Lock; 00362 }; 00363 00364 class CCommandLoadSeq_idAccVer : public CReadDispatcherCommand 00365 { 00366 public: 00367 typedef CSeq_id_Handle TKey; 00368 typedef CLoadLockSeq_ids TLock; 00369 CCommandLoadSeq_idAccVer(CReaderRequestResult& result, 00370 const TKey& key) 00371 : CReadDispatcherCommand(result), 00372 m_Key(key), m_Lock(result, key) 00373 { 00374 } 00375 00376 bool IsDone(void) 00377 { 00378 return m_Lock->IsLoadedAccVer(); 00379 } 00380 bool Execute(CReader& reader) 00381 { 00382 return reader.LoadSeq_idAccVer(GetResult(), m_Key); 00383 } 00384 string GetErrMsg(void) const 00385 { 00386 return "LoadSeq_idAccVer("+m_Key.AsString()+"): " 00387 "data not found"; 00388 } 00389 CGBRequestStatistics::EStatType GetStatistics(void) const 00390 { 00391 return CGBRequestStatistics::eStat_Seq_idAcc; 00392 } 00393 string GetStatisticsDescription(void) const 00394 { 00395 return "acc("+m_Key.AsString()+")"; 00396 } 00397 00398 private: 00399 TKey m_Key; 00400 TLock m_Lock; 00401 }; 00402 00403 class CCommandLoadSeq_idLabel : public CReadDispatcherCommand 00404 { 00405 public: 00406 typedef CSeq_id_Handle TKey; 00407 typedef CLoadLockSeq_ids TLock; 00408 CCommandLoadSeq_idLabel(CReaderRequestResult& result, 00409 const TKey& key) 00410 : CReadDispatcherCommand(result), 00411 m_Key(key), m_Lock(result, key) 00412 { 00413 } 00414 00415 bool IsDone(void) 00416 { 00417 return m_Lock->IsLoadedLabel(); 00418 } 00419 bool Execute(CReader& reader) 00420 { 00421 return reader.LoadSeq_idLabel(GetResult(), m_Key); 00422 } 00423 string GetErrMsg(void) const 00424 { 00425 return "LoadSeq_idLabel("+m_Key.AsString()+"): " 00426 "data not found"; 00427 } 00428 CGBRequestStatistics::EStatType GetStatistics(void) const 00429 { 00430 return CGBRequestStatistics::eStat_Seq_idLabel; 00431 } 00432 string GetStatisticsDescription(void) const 00433 { 00434 return "label("+m_Key.AsString()+")"; 00435 } 00436 00437 private: 00438 TKey m_Key; 00439 TLock m_Lock; 00440 }; 00441 00442 class CCommandLoadSeq_idTaxId : public CReadDispatcherCommand 00443 { 00444 public: 00445 typedef CSeq_id_Handle TKey; 00446 typedef CLoadLockSeq_ids TLock; 00447 CCommandLoadSeq_idTaxId(CReaderRequestResult& result, 00448 const TKey& key) 00449 : CReadDispatcherCommand(result), 00450 m_Key(key), m_Lock(result, key) 00451 { 00452 } 00453 00454 bool IsDone(void) 00455 { 00456 return m_Lock->IsLoadedTaxId(); 00457 } 00458 bool Execute(CReader& reader) 00459 { 00460 return reader.LoadSeq_idTaxId(GetResult(), m_Key); 00461 } 00462 bool MayBeSkipped(void) const 00463 { 00464 return true; 00465 } 00466 string GetErrMsg(void) const 00467 { 00468 return "LoadSeq_idTaxId("+m_Key.AsString()+"): " 00469 "data not found"; 00470 } 00471 CGBRequestStatistics::EStatType GetStatistics(void) const 00472 { 00473 return CGBRequestStatistics::eStat_Seq_idTaxId; 00474 } 00475 string GetStatisticsDescription(void) const 00476 { 00477 return "taxid("+m_Key.AsString()+")"; 00478 } 00479 00480 private: 00481 TKey m_Key; 00482 TLock m_Lock; 00483 }; 00484 00485 class CCommandLoadSeq_idBlob_ids : public CReadDispatcherCommand 00486 { 00487 public: 00488 typedef CSeq_id_Handle TKey; 00489 typedef CLoadLockBlob_ids TLock; 00490 CCommandLoadSeq_idBlob_ids(CReaderRequestResult& result, 00491 const TKey& key, 00492 const SAnnotSelector* sel) 00493 : CReadDispatcherCommand(result), 00494 m_Key(key), m_Selector(sel), m_Lock(result, key, sel) 00495 { 00496 } 00497 00498 bool IsDone(void) 00499 { 00500 return m_Lock.IsLoaded(); 00501 } 00502 bool Execute(CReader& reader) 00503 { 00504 return reader.LoadSeq_idBlob_ids(GetResult(), 00505 m_Key, m_Selector); 00506 } 00507 string GetErrMsg(void) const 00508 { 00509 return "LoadSeq_idBlob_ids("+m_Key.AsString()+"): " 00510 "data not found"; 00511 } 00512 CGBRequestStatistics::EStatType GetStatistics(void) const 00513 { 00514 return CGBRequestStatistics::eStat_Seq_idBlob_ids; 00515 } 00516 string GetStatisticsDescription(void) const 00517 { 00518 return "blob-ids("+m_Key.AsString()+")"; 00519 } 00520 00521 private: 00522 TKey m_Key; 00523 const SAnnotSelector* m_Selector; 00524 TLock m_Lock; 00525 }; 00526 00527 class CCommandLoadAccVers : public CReadDispatcherCommand 00528 { 00529 public: 00530 typedef vector<CSeq_id_Handle> TKey; 00531 typedef vector<bool> TLoaded; 00532 typedef vector<CSeq_id_Handle> TRet; 00533 CCommandLoadAccVers(CReaderRequestResult& result, 00534 const TKey& key, TLoaded& loaded, TRet& ret) 00535 : CReadDispatcherCommand(result), 00536 m_Key(key), m_Loaded(loaded), m_Ret(ret) 00537 { 00538 } 00539 00540 bool IsDone(void) 00541 { 00542 return std::find(m_Loaded.begin(), m_Loaded.end(), false) == 00543 m_Loaded.end(); 00544 } 00545 bool Execute(CReader& reader) 00546 { 00547 return reader.LoadAccVers(GetResult(), m_Key, m_Loaded, m_Ret); 00548 } 00549 string GetErrMsg(void) const 00550 { 00551 return "LoadAccVers("+NStr::SizetToString(m_Key.size())+": "+ 00552 m_Key[0].AsString()+", ...): " 00553 "data not found"; 00554 } 00555 CGBRequestStatistics::EStatType GetStatistics(void) const 00556 { 00557 return CGBRequestStatistics::eStat_Seq_idAcc; 00558 } 00559 string GetStatisticsDescription(void) const 00560 { 00561 return "accs("+NStr::SizetToString(m_Key.size())+": "+ 00562 m_Key[0].AsString()+", ...)"; 00563 } 00564 00565 private: 00566 const TKey& m_Key; 00567 TLoaded& m_Loaded; 00568 TRet& m_Ret; 00569 }; 00570 00571 class CCommandLoadGis : public CReadDispatcherCommand 00572 { 00573 public: 00574 typedef vector<CSeq_id_Handle> TKey; 00575 typedef vector<bool> TLoaded; 00576 typedef vector<int> TRet; 00577 CCommandLoadGis(CReaderRequestResult& result, 00578 const TKey& key, TLoaded& loaded, TRet& ret) 00579 : CReadDispatcherCommand(result), 00580 m_Key(key), m_Loaded(loaded), m_Ret(ret) 00581 { 00582 } 00583 00584 bool IsDone(void) 00585 { 00586 return std::find(m_Loaded.begin(), m_Loaded.end(), false) == 00587 m_Loaded.end(); 00588 } 00589 bool Execute(CReader& reader) 00590 { 00591 return reader.LoadGis(GetResult(), m_Key, m_Loaded, m_Ret); 00592 } 00593 string GetErrMsg(void) const 00594 { 00595 return "LoadGis("+NStr::SizetToString(m_Key.size())+": "+ 00596 m_Key[0].AsString()+", ...): " 00597 "data not found"; 00598 } 00599 CGBRequestStatistics::EStatType GetStatistics(void) const 00600 { 00601 return CGBRequestStatistics::eStat_Seq_idGi; 00602 } 00603 string GetStatisticsDescription(void) const 00604 { 00605 return "gis("+NStr::SizetToString(m_Key.size())+": "+ 00606 m_Key[0].AsString()+", ...)"; 00607 } 00608 00609 private: 00610 const TKey& m_Key; 00611 TLoaded& m_Loaded; 00612 TRet& m_Ret; 00613 }; 00614 00615 class CCommandLoadLabels : public CReadDispatcherCommand 00616 { 00617 public: 00618 typedef vector<CSeq_id_Handle> TKey; 00619 typedef vector<bool> TLoaded; 00620 typedef vector<string> TRet; 00621 CCommandLoadLabels(CReaderRequestResult& result, 00622 const TKey& key, TLoaded& loaded, TRet& ret) 00623 : CReadDispatcherCommand(result), 00624 m_Key(key), m_Loaded(loaded), m_Ret(ret) 00625 { 00626 } 00627 00628 bool IsDone(void) 00629 { 00630 return std::find(m_Loaded.begin(), m_Loaded.end(), false) == 00631 m_Loaded.end(); 00632 } 00633 bool Execute(CReader& reader) 00634 { 00635 return reader.LoadLabels(GetResult(), m_Key, m_Loaded, m_Ret); 00636 } 00637 string GetErrMsg(void) const 00638 { 00639 return "LoadLabels("+NStr::SizetToString(m_Key.size())+": "+ 00640 m_Key[0].AsString()+", ...): " 00641 "data not found"; 00642 } 00643 CGBRequestStatistics::EStatType GetStatistics(void) const 00644 { 00645 return CGBRequestStatistics::eStat_Seq_idLabel; 00646 } 00647 string GetStatisticsDescription(void) const 00648 { 00649 return "labels("+NStr::SizetToString(m_Key.size())+": "+ 00650 m_Key[0].AsString()+", ...)"; 00651 } 00652 00653 private: 00654 const TKey& m_Key; 00655 TLoaded& m_Loaded; 00656 TRet& m_Ret; 00657 }; 00658 00659 class CCommandLoadTaxIds : public CReadDispatcherCommand 00660 { 00661 public: 00662 typedef vector<CSeq_id_Handle> TKey; 00663 typedef vector<bool> TLoaded; 00664 typedef vector<int> TRet; 00665 CCommandLoadTaxIds(CReaderRequestResult& result, 00666 const TKey& key, TLoaded& loaded, TRet& ret) 00667 : CReadDispatcherCommand(result), 00668 m_Key(key), m_Loaded(loaded), m_Ret(ret) 00669 { 00670 } 00671 00672 bool IsDone(void) 00673 { 00674 return std::find(m_Loaded.begin(), m_Loaded.end(), false) == 00675 m_Loaded.end(); 00676 } 00677 bool Execute(CReader& reader) 00678 { 00679 return reader.LoadTaxIds(GetResult(), m_Key, m_Loaded, m_Ret); 00680 } 00681 string GetErrMsg(void) const 00682 { 00683 return "LoadTaxIds("+NStr::SizetToString(m_Key.size())+": "+ 00684 m_Key[0].AsString()+", ...): " 00685 "data not found"; 00686 } 00687 CGBRequestStatistics::EStatType GetStatistics(void) const 00688 { 00689 return CGBRequestStatistics::eStat_Seq_idTaxId; 00690 } 00691 string GetStatisticsDescription(void) const 00692 { 00693 return "taxids("+NStr::SizetToString(m_Key.size())+": "+ 00694 m_Key[0].AsString()+", ...)"; 00695 } 00696 00697 private: 00698 const TKey& m_Key; 00699 TLoaded& m_Loaded; 00700 TRet& m_Ret; 00701 }; 00702 00703 class CCommandLoadBlobVersion : public CReadDispatcherCommand 00704 { 00705 public: 00706 typedef CBlob_id TKey; 00707 typedef CLoadLockBlob TLock; 00708 CCommandLoadBlobVersion(CReaderRequestResult& result, 00709 const TKey& key) 00710 : CReadDispatcherCommand(result), 00711 m_Key(key), m_Lock(result, key) 00712 { 00713 } 00714 00715 bool IsDone(void) 00716 { 00717 return m_Lock.IsSetBlobVersion(); 00718 } 00719 bool Execute(CReader& reader) 00720 { 00721 return reader.LoadBlobVersion(GetResult(), m_Key); 00722 } 00723 string GetErrMsg(void) const 00724 { 00725 return "LoadBlobVersion("+m_Key.ToString()+"): " 00726 "data not found"; 00727 } 00728 CGBRequestStatistics::EStatType GetStatistics(void) const 00729 { 00730 return CGBRequestStatistics::eStat_BlobVersion; 00731 } 00732 string GetStatisticsDescription(void) const 00733 { 00734 return "blob-version("+m_Key.ToString()+")"; 00735 } 00736 00737 private: 00738 TKey m_Key; 00739 TLock m_Lock; 00740 }; 00741 00742 bool s_AllBlobsAreLoaded(CReaderRequestResult& result, 00743 const CLoadLockBlob_ids& blobs, 00744 CReadDispatcher::TContentsMask mask, 00745 const SAnnotSelector* sel) 00746 { 00747 _ASSERT(blobs.IsLoaded()); 00748 00749 ITERATE ( CLoadInfoBlob_ids, it, *blobs ) { 00750 const CBlob_Info& info = it->second; 00751 if ( info.Matches(*it->first, mask, sel) ) { 00752 if ( !result.IsBlobLoaded(*it->first) ) { 00753 return false; 00754 } 00755 } 00756 } 00757 return true; 00758 } 00759 00760 class CCommandLoadBlobs : public CReadDispatcherCommand 00761 { 00762 public: 00763 typedef CLoadLockBlob_ids TIds; 00764 typedef CReadDispatcher::TContentsMask TMask; 00765 CCommandLoadBlobs(CReaderRequestResult& result, 00766 TIds ids, TMask mask, const SAnnotSelector* sel) 00767 : CReadDispatcherCommand(result), 00768 m_Ids(ids), m_Mask(mask), m_Selector(sel) 00769 { 00770 } 00771 00772 bool IsDone(void) 00773 { 00774 return s_AllBlobsAreLoaded(GetResult(), 00775 m_Ids, m_Mask, m_Selector); 00776 } 00777 bool Execute(CReader& reader) 00778 { 00779 return reader.LoadBlobs(GetResult(), 00780 m_Ids, m_Mask, m_Selector); 00781 } 00782 string GetErrMsg(void) const 00783 { 00784 return "LoadBlobs(CLoadInfoBlob_ids): " 00785 "data not found"; 00786 } 00787 CGBRequestStatistics::EStatType GetStatistics(void) const 00788 { 00789 return CGBRequestStatistics::eStat_LoadBlob; 00790 } 00791 string GetStatisticsDescription(void) const 00792 { 00793 return "blobs(...)"; 00794 } 00795 00796 private: 00797 TIds m_Ids; 00798 TMask m_Mask; 00799 const SAnnotSelector* m_Selector; 00800 }; 00801 class CCommandLoadSeq_idBlobs : public CReadDispatcherCommand 00802 { 00803 public: 00804 typedef CSeq_id_Handle TKey; 00805 typedef CLoadLockBlob_ids TIds; 00806 typedef CReadDispatcher::TContentsMask TMask; 00807 CCommandLoadSeq_idBlobs(CReaderRequestResult& result, 00808 const TKey& key, TMask mask, 00809 const SAnnotSelector* sel) 00810 : CReadDispatcherCommand(result), 00811 m_Key(key), m_Ids(result, key, sel), 00812 m_Mask(mask), m_Selector(sel) 00813 { 00814 } 00815 00816 bool IsDone(void) 00817 { 00818 return m_Ids.IsLoaded() && 00819 s_AllBlobsAreLoaded(GetResult(), 00820 m_Ids, m_Mask, m_Selector); 00821 } 00822 bool Execute(CReader& reader) 00823 { 00824 return reader.LoadBlobs(GetResult(), 00825 m_Key, m_Mask, m_Selector); 00826 } 00827 string GetErrMsg(void) const 00828 { 00829 return "LoadBlobs("+m_Key.AsString()+"): " 00830 "data not found"; 00831 } 00832 CGBRequestStatistics::EStatType GetStatistics(void) const 00833 { 00834 return CGBRequestStatistics::eStat_LoadBlob; 00835 } 00836 string GetStatisticsDescription(void) const 00837 { 00838 return "blobs("+m_Key.AsString()+")"; 00839 } 00840 00841 private: 00842 TKey m_Key; 00843 TIds m_Ids; 00844 TMask m_Mask; 00845 const SAnnotSelector* m_Selector; 00846 }; 00847 00848 class CCommandLoadBlob : public CReadDispatcherCommand 00849 { 00850 public: 00851 typedef CBlob_id TKey; 00852 CCommandLoadBlob(CReaderRequestResult& result, 00853 const TKey& key, 00854 const CBlob_Info* blob_info = 0) 00855 : CReadDispatcherCommand(result), 00856 m_Key(key), 00857 m_BlobInfo(blob_info) 00858 { 00859 } 00860 00861 bool IsDone(void) 00862 { 00863 return GetResult().IsBlobLoaded(m_Key); 00864 } 00865 bool Execute(CReader& reader) 00866 { 00867 if ( m_BlobInfo ) { 00868 return reader.LoadBlob(GetResult(), m_Key, *m_BlobInfo); 00869 } 00870 else { 00871 return reader.LoadBlob(GetResult(), m_Key); 00872 } 00873 } 00874 string GetErrMsg(void) const 00875 { 00876 return "LoadBlob("+m_Key.ToString()+"): " 00877 "data not found"; 00878 } 00879 CGBRequestStatistics::EStatType GetStatistics(void) const 00880 { 00881 return CGBRequestStatistics::eStat_LoadBlob; 00882 } 00883 string GetStatisticsDescription(void) const 00884 { 00885 return "blob("+m_Key.ToString()+")"; 00886 } 00887 00888 private: 00889 TKey m_Key; 00890 const CBlob_Info* m_BlobInfo; 00891 }; 00892 00893 class CCommandLoadChunk : public CReadDispatcherCommand 00894 { 00895 public: 00896 typedef CBlob_id TKey; 00897 typedef CLoadLockBlob TLock; 00898 typedef int TChunkId; 00899 typedef CTSE_Chunk_Info TChunkInfo; 00900 CCommandLoadChunk(CReaderRequestResult& result, 00901 const TKey& key, 00902 TChunkId chunk_id) 00903 : CReadDispatcherCommand(result), 00904 m_Key(key), m_Lock(result, key), 00905 m_ChunkId(chunk_id), 00906 m_ChunkInfo(m_Lock->GetSplitInfo().GetChunk(chunk_id)) 00907 { 00908 } 00909 00910 bool IsDone(void) 00911 { 00912 return m_ChunkInfo.IsLoaded(); 00913 } 00914 bool Execute(CReader& reader) 00915 { 00916 return reader.LoadChunk(GetResult(), m_Key, m_ChunkId); 00917 } 00918 string GetErrMsg(void) const 00919 { 00920 return "LoadChunk("+m_Key.ToString()+", "+ 00921 NStr::IntToString(m_ChunkId)+"): " 00922 "data not found"; 00923 } 00924 CGBRequestStatistics::EStatType GetStatistics(void) const 00925 { 00926 return CGBRequestStatistics::eStat_LoadChunk; 00927 } 00928 string GetStatisticsDescription(void) const 00929 { 00930 return "chunk("+m_Key.ToString()+"."+ 00931 NStr::IntToString(m_ChunkId)+")"; 00932 } 00933 00934 private: 00935 TKey m_Key; 00936 TLock m_Lock; 00937 TChunkId m_ChunkId; 00938 TChunkInfo& m_ChunkInfo; 00939 }; 00940 00941 class CCommandLoadChunks : public CReadDispatcherCommand 00942 { 00943 public: 00944 typedef CBlob_id TKey; 00945 typedef CLoadLockBlob TLock; 00946 typedef int TChunkId; 00947 typedef vector<TChunkId> TChunkIds; 00948 typedef CTSE_Chunk_Info TChunkInfo; 00949 typedef vector<CTSE_Chunk_Info*> TChunkInfos; 00950 CCommandLoadChunks(CReaderRequestResult& result, 00951 const TKey& key, 00952 const TChunkIds chunk_ids) 00953 : CReadDispatcherCommand(result), 00954 m_Key(key), m_Lock(result, key), 00955 m_ChunkIds(chunk_ids) 00956 { 00957 ITERATE(TChunkIds, it, m_ChunkIds) { 00958 m_ChunkInfos.push_back( 00959 &m_Lock->GetSplitInfo().GetChunk(*it)); 00960 } 00961 } 00962 00963 bool IsDone(void) 00964 { 00965 ITERATE(TChunkInfos, it, m_ChunkInfos) { 00966 if ( !(*it)->IsLoaded() ) { 00967 return false; 00968 } 00969 } 00970 return true; 00971 } 00972 bool Execute(CReader& reader) 00973 { 00974 return reader.LoadChunks(GetResult(), m_Key, m_ChunkIds); 00975 } 00976 string GetErrMsg(void) const 00977 { 00978 CNcbiOstrstream str; 00979 str << "LoadChunks(" << m_Key.ToString() << ", {"; 00980 int cnt = 0; 00981 ITERATE(TChunkInfos, it, m_ChunkInfos) { 00982 if ( !(*it)->IsLoaded() ) { 00983 if ( cnt++ ) str << ','; 00984 str << ' ' << (*it)->GetChunkId(); 00985 } 00986 } 00987 str << " }): data not found"; 00988 return CNcbiOstrstreamToString(str); 00989 } 00990 CGBRequestStatistics::EStatType GetStatistics(void) const 00991 { 00992 return CGBRequestStatistics::eStat_LoadChunk; 00993 } 00994 string GetStatisticsDescription(void) const 00995 { 00996 CNcbiOstrstream str; 00997 int cnt = 0; 00998 ITERATE(TChunkInfos, it, m_ChunkInfos) { 00999 int id = (*it)->GetChunkId(); 01000 if ( id >= 0 && id < kMax_Int ) { 01001 if ( !cnt ) { 01002 str << "chunk(" << m_Key.ToString() << '.'; 01003 cnt = 1; 01004 } 01005 else { 01006 str << ','; 01007 } 01008 str << id; 01009 } 01010 } 01011 if ( !cnt ) { 01012 str << "blob(" << m_Key.ToString(); 01013 } 01014 str << ')'; 01015 return CNcbiOstrstreamToString(str); 01016 } 01017 01018 private: 01019 TKey m_Key; 01020 TLock m_Lock; 01021 TChunkIds m_ChunkIds; 01022 TChunkInfos m_ChunkInfos; 01023 }; 01024 01025 class CCommandLoadBlobSet : public CReadDispatcherCommand 01026 { 01027 public: 01028 typedef CReadDispatcher::TIds TIds; 01029 CCommandLoadBlobSet(CReaderRequestResult& result, 01030 const TIds& seq_ids) 01031 : CReadDispatcherCommand(result), 01032 m_Ids(seq_ids) 01033 { 01034 } 01035 01036 bool IsDone(void) 01037 { 01038 CReaderRequestResult& result = GetResult(); 01039 ITERATE(TIds, id, m_Ids) { 01040 CLoadLockBlob_ids blob_ids(result, *id, 0); 01041 if ( !blob_ids.IsLoaded() ) { 01042 return false; 01043 } 01044 ITERATE ( CLoadInfoBlob_ids, it, *blob_ids ) { 01045 const CBlob_Info& info = it->second; 01046 if ( (info.GetContentsMask() & fBlobHasCore) == 0 ) { 01047 continue; // skip this blob 01048 } 01049 if ( !result.IsBlobLoaded(*it->first) ) { 01050 return false; 01051 } 01052 } 01053 } 01054 return true; 01055 } 01056 bool Execute(CReader& reader) 01057 { 01058 return reader.LoadBlobSet(GetResult(), m_Ids); 01059 } 01060 string GetErrMsg(void) const 01061 { 01062 return "LoadBlobSet(" + 01063 NStr::SizetToString(m_Ids.size()) + " ids): " 01064 "data not found"; 01065 } 01066 CGBRequestStatistics::EStatType GetStatistics(void) const 01067 { 01068 return CGBRequestStatistics::eStat_LoadBlob; 01069 } 01070 string GetStatisticsDescription(void) const 01071 { 01072 return "blobs(" + 01073 NStr::SizetToString(m_Ids.size()) + " ids)"; 01074 } 01075 01076 private: 01077 TIds m_Ids; 01078 }; 01079 } 01080 01081 BEGIN_LOCAL_NAMESPACE; 01082 01083 struct SSaveResultLevel 01084 { 01085 SSaveResultLevel(CReadDispatcherCommand& command) 01086 : m_Command(command), 01087 m_SavedLevel(command.GetResult().GetLevel()) 01088 { 01089 } 01090 01091 ~SSaveResultLevel(void) 01092 { 01093 m_Command.GetResult().SetLevel(m_SavedLevel); 01094 } 01095 01096 CReadDispatcherCommand& m_Command; 01097 int m_SavedLevel; 01098 }; 01099 01100 END_LOCAL_NAMESPACE; 01101 01102 01103 void CReadDispatcher::Process(CReadDispatcherCommand& command, 01104 const CReader* asking_reader) 01105 { 01106 CheckReaders(); 01107 01108 if ( command.IsDone() ) { 01109 return; 01110 } 01111 01112 SSaveResultLevel save_level(command); 01113 NON_CONST_ITERATE ( TReaders, rdr, m_Readers ) { 01114 if ( asking_reader ) { 01115 // skip all readers before the asking one 01116 if ( rdr->second == asking_reader ) { 01117 // found the asking reader, start processing next readers 01118 asking_reader = 0; 01119 } 01120 continue; 01121 } 01122 CReader& reader = *rdr->second; 01123 command.GetResult().SetLevel(rdr->first); 01124 int retry_count = 0; 01125 int max_retry_count = reader.GetRetryCount(); 01126 do { 01127 ++retry_count; 01128 try { 01129 CReaderRequestResult::CRecurse r(command.GetResult()); 01130 if ( !command.Execute(reader) ) { 01131 retry_count = kMax_Int; 01132 } 01133 LogStat(command, r); 01134 } 01135 catch ( CLoaderException& exc ) { 01136 if ( exc.GetErrCode() == exc.eRepeatAgain ) { 01137 // no actual error, just restart 01138 --retry_count; 01139 LOG_POST_X(10, Info<< 01140 "CReadDispatcher: connection reopened " 01141 "due to inactivity timeout"); 01142 } 01143 else if ( exc.GetErrCode() == exc.eNoConnection ) { 01144 LOG_POST_X(1, Warning<< 01145 "CReadDispatcher: Exception: "<<exc); 01146 retry_count = kMax_Int; 01147 } 01148 else { 01149 if ( retry_count >= max_retry_count && 01150 !reader.MayBeSkippedOnErrors() ) { 01151 throw; 01152 } 01153 LOG_POST_X(2, Warning<< 01154 "CReadDispatcher: Exception: "<<exc); 01155 } 01156 } 01157 catch ( CException& exc ) { 01158 // error in the command 01159 if ( retry_count >= max_retry_count && 01160 !reader.MayBeSkippedOnErrors() ) { 01161 throw; 01162 } 01163 LOG_POST_X(3, Warning << 01164 "CReadDispatcher: Exception: "<<exc); 01165 } 01166 catch ( exception& exc ) { 01167 // error in the command 01168 if ( retry_count >= max_retry_count && 01169 !reader.MayBeSkippedOnErrors() ) { 01170 throw; 01171 } 01172 LOG_POST_X(4, Warning << 01173 "CReadDispatcher: Exception: "<<exc.what()); 01174 } 01175 if ( command.IsDone() ) { 01176 return; 01177 } 01178 } while ( retry_count < max_retry_count ); 01179 if ( !reader.MayBeSkippedOnErrors() ) { 01180 NCBI_THROW(CLoaderException, eLoaderFailed, command.GetErrMsg()); 01181 } 01182 } 01183 01184 if ( command.MayBeSkipped() ) { 01185 return; 01186 } 01187 01188 NCBI_THROW(CLoaderException, eLoaderFailed, command.GetErrMsg()); 01189 } 01190 01191 01192 void CReadDispatcher::LoadStringSeq_ids(CReaderRequestResult& result, 01193 const string& seq_id) 01194 { 01195 CCommandLoadStringSeq_ids command(result, seq_id); 01196 Process(command); 01197 } 01198 01199 01200 void CReadDispatcher::LoadSeq_idSeq_ids(CReaderRequestResult& result, 01201 const CSeq_id_Handle& seq_id) 01202 { 01203 CCommandLoadSeq_idSeq_ids command(result, seq_id); 01204 Process(command); 01205 } 01206 01207 01208 void CReadDispatcher::LoadSeq_idGi(CReaderRequestResult& result, 01209 const CSeq_id_Handle& seq_id) 01210 { 01211 CCommandLoadSeq_idGi command(result, seq_id); 01212 Process(command); 01213 } 01214 01215 01216 void CReadDispatcher::LoadSeq_idAccVer(CReaderRequestResult& result, 01217 const CSeq_id_Handle& seq_id) 01218 { 01219 CCommandLoadSeq_idAccVer command(result, seq_id); 01220 Process(command); 01221 } 01222 01223 01224 void CReadDispatcher::LoadSeq_idLabel(CReaderRequestResult& result, 01225 const CSeq_id_Handle& seq_id) 01226 { 01227 CCommandLoadSeq_idLabel command(result, seq_id); 01228 Process(command); 01229 } 01230 01231 01232 void CReadDispatcher::LoadSeq_idTaxId(CReaderRequestResult& result, 01233 const CSeq_id_Handle& seq_id) 01234 { 01235 CCommandLoadSeq_idTaxId command(result, seq_id); 01236 Process(command); 01237 } 01238 01239 01240 void CReadDispatcher::LoadAccVers(CReaderRequestResult& result, 01241 const TIds ids, TLoaded& loaded, TIds& ret) 01242 { 01243 CCommandLoadAccVers command(result, ids, loaded, ret); 01244 Process(command); 01245 } 01246 01247 01248 void CReadDispatcher::LoadGis(CReaderRequestResult& result, 01249 const TIds ids, TLoaded& loaded, TGis& ret) 01250 { 01251 CCommandLoadGis command(result, ids, loaded, ret); 01252 Process(command); 01253 } 01254 01255 01256 void CReadDispatcher::LoadLabels(CReaderRequestResult& result, 01257 const TIds ids, TLoaded& loaded, TLabels& ret) 01258 { 01259 CCommandLoadLabels command(result, ids, loaded, ret); 01260 Process(command); 01261 } 01262 01263 01264 void CReadDispatcher::LoadTaxIds(CReaderRequestResult& result, 01265 const TIds ids, TLoaded& loaded, TTaxIds& ret) 01266 { 01267 CCommandLoadTaxIds command(result, ids, loaded, ret); 01268 Process(command); 01269 } 01270 01271 01272 void CReadDispatcher::LoadSeq_idBlob_ids(CReaderRequestResult& result, 01273 const CSeq_id_Handle& seq_id, 01274 const SAnnotSelector* sel) 01275 { 01276 CCommandLoadSeq_idBlob_ids command(result, seq_id, sel); 01277 Process(command); 01278 } 01279 01280 01281 void CReadDispatcher::LoadBlobVersion(CReaderRequestResult& result, 01282 const TBlobId& blob_id, 01283 const CReader* asking_reader) 01284 { 01285 CCommandLoadBlobVersion command(result, blob_id); 01286 Process(command, asking_reader); 01287 } 01288 01289 void CReadDispatcher::LoadBlobs(CReaderRequestResult& result, 01290 const CSeq_id_Handle& seq_id, 01291 TContentsMask mask, 01292 const SAnnotSelector* sel) 01293 { 01294 CCommandLoadSeq_idBlobs command(result, seq_id, mask, sel); 01295 Process(command); 01296 } 01297 01298 01299 void CReadDispatcher::LoadBlobs(CReaderRequestResult& result, 01300 CLoadLockBlob_ids blobs, 01301 TContentsMask mask, 01302 const SAnnotSelector* sel) 01303 { 01304 CCommandLoadBlobs command(result, blobs, mask, sel); 01305 Process(command); 01306 } 01307 01308 01309 void CReadDispatcher::LoadBlob(CReaderRequestResult& result, 01310 const CBlob_id& blob_id) 01311 { 01312 CCommandLoadBlob command(result, blob_id); 01313 Process(command); 01314 } 01315 01316 01317 void CReadDispatcher::LoadBlob(CReaderRequestResult& result, 01318 const CBlob_id& blob_id, 01319 const CBlob_Info& blob_info) 01320 { 01321 CCommandLoadBlob command(result, blob_id, &blob_info); 01322 Process(command); 01323 } 01324 01325 01326 void CReadDispatcher::LoadChunk(CReaderRequestResult& result, 01327 const TBlobId& blob_id, TChunkId chunk_id) 01328 { 01329 CCommandLoadChunk command(result, blob_id, chunk_id); 01330 Process(command); 01331 } 01332 01333 01334 void CReadDispatcher::LoadChunks(CReaderRequestResult& result, 01335 const TBlobId& blob_id, 01336 const TChunkIds& chunk_ids) 01337 { 01338 CCommandLoadChunks command(result, blob_id, chunk_ids); 01339 Process(command); 01340 } 01341 01342 01343 void CReadDispatcher::LoadBlobSet(CReaderRequestResult& result, 01344 const TIds& seq_ids) 01345 { 01346 CCommandLoadBlobSet command(result, seq_ids); 01347 Process(command); 01348 } 01349 01350 01351 void CReadDispatcher::SetAndSaveBlobState(CReaderRequestResult& result, 01352 const TBlobId& blob_id, 01353 TBlobState state) const 01354 { 01355 CLoadLockBlob blob(result, blob_id); 01356 SetAndSaveBlobState(result, blob_id, blob, state); 01357 } 01358 01359 01360 void CReadDispatcher::SetAndSaveBlobState(CReaderRequestResult& /*result*/, 01361 const TBlobId& /*blob_id*/, 01362 CLoadLockBlob& blob, 01363 TBlobState state) const 01364 { 01365 if ( (blob.GetBlobState() & state) == state ) { 01366 return; 01367 } 01368 blob.SetBlobState(state); 01369 } 01370 01371 01372 void CReadDispatcher::SetAndSaveBlobVersion(CReaderRequestResult& result, 01373 const TBlobId& blob_id, 01374 TBlobVersion version) const 01375 { 01376 CLoadLockBlob blob(result, blob_id); 01377 SetAndSaveBlobVersion(result, blob_id, blob, version); 01378 } 01379 01380 01381 void CReadDispatcher::SetAndSaveBlobVersion(CReaderRequestResult& result, 01382 const TBlobId& blob_id, 01383 CLoadLockBlob& blob, 01384 TBlobVersion version) const 01385 { 01386 if ( blob.IsSetBlobVersion() && blob.GetBlobVersion() == version ) { 01387 return; 01388 } 01389 blob.SetBlobVersion(version); 01390 CWriter *writer = GetWriter(result, CWriter::eIdWriter); 01391 if( writer ) { 01392 writer->SaveBlobVersion(result, blob_id, version); 01393 } 01394 } 01395 01396 01397 void CReadDispatcher::LogStat(CReadDispatcherCommand& command, 01398 CStopWatch& sw) 01399 { 01400 CReaderRequestResult& result = command.GetResult(); 01401 double time = result.GetCurrentRequestTime(sw.Elapsed()); 01402 CGBRequestStatistics& stat = sx_Statistics[command.GetStatistics()]; 01403 stat.AddTime(time); 01404 if ( CollectStatistics() >= 2 ) { 01405 string descr = command.GetStatisticsDescription(); 01406 const CSeq_id_Handle& idh = result.GetRequestedId(); 01407 if ( idh ) { 01408 descr = descr + " for " + idh.AsString(); 01409 } 01410 LOG_POST_X(8, setw(result.GetRecursionLevel()) << "" << 01411 "Dispatcher: read " << 01412 descr << " in " << 01413 setiosflags(ios::fixed) << 01414 setprecision(3) << (time*1000) << " ms"); 01415 } 01416 } 01417 01418 01419 void CReadDispatcher::LogStat(CReadDispatcherCommand& command, 01420 CStopWatch& sw, 01421 double size) 01422 { 01423 CReaderRequestResult& result = command.GetResult(); 01424 double time = result.GetCurrentRequestTime(sw.Elapsed()); 01425 CGBRequestStatistics& stat = sx_Statistics[command.GetStatistics()]; 01426 stat.AddTimeSize(time, size); 01427 if ( CollectStatistics() >= 2 ) { 01428 string descr = command.GetStatisticsDescription(); 01429 const CSeq_id_Handle& idh = result.GetRequestedId(); 01430 if ( idh ) { 01431 descr = descr + " for " + idh.AsString(); 01432 } 01433 LOG_POST_X(9, setw(result.GetRecursionLevel()) << "" << 01434 descr << " in " << 01435 setiosflags(ios::fixed) << 01436 setprecision(3) << 01437 (time*1000) << " ms (" << 01438 setprecision(2) << 01439 (size/1024.0) << " kB " << 01440 setprecision(2) << 01441 (size/time/1024) << " kB/s)"); 01442 } 01443 } 01444 01445 01446 END_SCOPE(objects) 01447 END_NCBI_SCOPE
1.7.5.1
Modified on Wed May 23 12:59:23 2012 by modify_doxy.py rev. 337098