00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030 #include <ncbi_pch.hpp>
00031 #include <objtools/data_loaders/genbank/cache/reader_cache.hpp>
00032 #include <objtools/data_loaders/genbank/cache/reader_cache_entry.hpp>
00033 #include <objtools/data_loaders/genbank/cache/reader_cache_params.h>
00034 #include <objtools/data_loaders/genbank/readers.hpp>
00035 #include <objtools/data_loaders/genbank/dispatcher.hpp>
00036 #include <objtools/data_loaders/genbank/request_result.hpp>
00037 #include <objtools/data_loaders/genbank/gbloader.hpp>
00038
00039 #include <corelib/ncbitime.hpp>
00040 #include <corelib/rwstream.hpp>
00041 #include <corelib/plugin_manager_store.hpp>
00042
00043 #include <util/cache/icache.hpp>
00044
00045 #include <objmgr/objmgr_exception.hpp>
00046 #include <objmgr/impl/tse_split_info.hpp>
00047 #include <objmgr/impl/tse_chunk_info.hpp>
00048 #include <objmgr/annot_selector.hpp>
00049
00050 #include <serial/objistrasnb.hpp>
00051 #include <serial/serial.hpp>
00052 #include <objects/seqloc/Seq_id.hpp>
00053
00054 #define FIX_BAD_ID2S_REPLY_DATA 1
00055
00056 BEGIN_NCBI_SCOPE
00057 BEGIN_SCOPE(objects)
00058
00059 const int SCacheInfo::IDS_MAGIC = 0x32fd0105;
00060
00061 string SCacheInfo::GetBlobKey(const CBlob_id& blob_id)
00062 {
00063 CNcbiOstrstream oss;
00064 oss << blob_id.GetSat();
00065 if ( blob_id.GetSubSat() != 0 ) {
00066 oss << '.' << blob_id.GetSubSat();
00067 }
00068 oss << '-' << blob_id.GetSatKey();
00069 return CNcbiOstrstreamToString(oss);
00070 }
00071
00072
00073 string SCacheInfo::GetIdKey(int gi)
00074 {
00075 return NStr::IntToString(gi);
00076 }
00077
00078
00079 string SCacheInfo::GetIdKey(const CSeq_id& id)
00080 {
00081 return id.IsGi()? GetIdKey(id.GetGi()): id.AsFastaString();
00082 }
00083
00084
00085 string SCacheInfo::GetIdKey(const CSeq_id_Handle& id)
00086 {
00087 return id.IsGi()? GetIdKey(id.GetGi()): id.AsString();
00088 }
00089
00090
00091 static const size_t kHashLimit = 100;
00092
00093
00094 void SCacheInfo::GetBlob_idsSubkey(const SAnnotSelector* sel,
00095 string& subkey,
00096 string& true_subkey)
00097 {
00098 if ( !sel ) {
00099 subkey = "blobs";
00100 return;
00101 }
00102 const SAnnotSelector::TNamedAnnotAccessions& accs =
00103 sel->GetNamedAnnotAccessions();
00104 if ( accs.empty() ) {
00105 subkey = "blobs";
00106 return;
00107 }
00108
00109 CNcbiOstrstream str;
00110 str << "blobs";
00111 size_t total_size = 0;
00112 ITERATE ( SAnnotSelector::TNamedAnnotAccessions, it, accs ) {
00113 total_size += 1+it->size();
00114 }
00115 bool add_hash = total_size > kHashLimit;
00116 if ( add_hash ) {
00117 size_t hash = 5381;
00118 ITERATE ( SAnnotSelector::TNamedAnnotAccessions, it, accs ) {
00119 hash = hash*17 + it->size();
00120 ITERATE ( string, i, *it ) {
00121 hash = hash*17 + (*i & 0xff);
00122 }
00123 }
00124 str << ";#" << hex << hash << dec;
00125 }
00126 ITERATE ( SAnnotSelector::TNamedAnnotAccessions, it,
00127 sel->GetNamedAnnotAccessions() ) {
00128 str << ';';
00129 str << *it;
00130 }
00131 if ( add_hash ) {
00132 true_subkey = CNcbiOstrstreamToString(str);
00133 subkey = true_subkey.substr(0, kHashLimit);
00134 }
00135 else {
00136 subkey = CNcbiOstrstreamToString(str);
00137 }
00138 }
00139
00140
00141 const char* SCacheInfo::GetGiSubkey(void)
00142 {
00143 return "gi4";
00144 }
00145
00146
00147 const char* SCacheInfo::GetAccVerSubkey(void)
00148 {
00149 return "accver";
00150 }
00151
00152
00153 const char* SCacheInfo::GetLabelSubkey(void)
00154 {
00155 return "label";
00156 }
00157
00158
00159 const char* SCacheInfo::GetSeq_idsSubkey(void)
00160 {
00161 return "ids4";
00162 }
00163
00164
00165 const char* SCacheInfo::GetBlobVersionSubkey(void)
00166 {
00167 return "ver4";
00168 }
00169
00170
00171 string SCacheInfo::GetBlobSubkey(int chunk_id)
00172 {
00173 if ( chunk_id == kMain_ChunkId )
00174 return kEmptyStr;
00175 else
00176 return NStr::IntToString(chunk_id);
00177 }
00178
00179
00180
00181
00182
00183
00184 CCacheHolder::CCacheHolder(void)
00185 : m_BlobCache(0), m_IdCache(0)
00186 {
00187 }
00188
00189
00190 CCacheHolder::~CCacheHolder(void)
00191 {
00192 SetIdCache(0);
00193 SetBlobCache(0);
00194 }
00195
00196
00197 void CCacheHolder::SetIdCache(ICache* id_cache)
00198 {
00199 m_IdCache = id_cache;
00200 }
00201
00202
00203 void CCacheHolder::SetBlobCache(ICache* blob_cache)
00204 {
00205 m_BlobCache = blob_cache;
00206 }
00207
00208
00209
00210
00211
00212 CCacheReader::CCacheReader(void)
00213 {
00214 SetMaximumConnections(1);
00215 }
00216
00217
00218 void CCacheReader::x_AddConnectionSlot(TConn )
00219 {
00220 }
00221
00222
00223 void CCacheReader::x_RemoveConnectionSlot(TConn )
00224 {
00225 SetIdCache(0);
00226 SetBlobCache(0);
00227 }
00228
00229
00230 void CCacheReader::x_DisconnectAtSlot(TConn )
00231 {
00232 }
00233
00234
00235 void CCacheReader::x_ConnectAtSlot(TConn )
00236 {
00237 }
00238
00239
00240 int CCacheReader::GetRetryCount(void) const
00241 {
00242 return 2;
00243 }
00244
00245
00246 bool CCacheReader::MayBeSkippedOnErrors(void) const
00247 {
00248 return true;
00249 }
00250
00251
00252 int CCacheReader::GetMaximumConnectionsLimit(void) const
00253 {
00254 return 1;
00255 }
00256
00257
00258
00259
00260
00261 namespace {
00262 class CParseBuffer {
00263 public:
00264 CParseBuffer(ICache* cache,
00265 const string& key, int version, const string& subkey);
00266
00267 bool Found(void) const
00268 {
00269 return m_Descr.blob_found;
00270 }
00271 bool Done(void) const
00272 {
00273 if ( m_Ptr ) {
00274 return m_Size == 0;
00275 }
00276 else {
00277 return x_Eof();
00278 }
00279 }
00280
00281 Uint4 ParseUint4(void)
00282 {
00283 const char* ptr = x_NextBytes(4);
00284 return ((ptr[0]&0xff)<<24)|((ptr[1]&0xff)<<16)|
00285 ((ptr[2]&0xff)<<8)|(ptr[3]&0xff);
00286 }
00287 Int4 ParseInt4(void)
00288 {
00289 return ParseUint4();
00290 }
00291 string ParseString(void);
00292 string FullString(void);
00293
00294 protected:
00295 bool x_Eof(void) const;
00296 const char* x_NextBytes(size_t size);
00297
00298 private:
00299 CParseBuffer(const CParseBuffer&);
00300 void operator=(const CParseBuffer&);
00301
00302 char m_Buffer[4096];
00303 ICache::SBlobAccessDescr m_Descr;
00304 const char* m_Ptr;
00305 size_t m_Size;
00306 };
00307
00308 CParseBuffer::CParseBuffer(ICache* cache,
00309 const string& key,
00310 int version,
00311 const string& subkey)
00312 : m_Descr(m_Buffer, sizeof(m_Buffer)), m_Ptr(0), m_Size(0)
00313 {
00314 cache->GetBlobAccess(key, version, subkey, &m_Descr);
00315 if ( !m_Descr.reader.get() ) {
00316 m_Ptr = m_Descr.buf;
00317 m_Size = m_Descr.blob_size;
00318 }
00319 }
00320
00321 string CParseBuffer::ParseString(void)
00322 {
00323 string ret;
00324 size_t size = ParseUint4();
00325 if ( m_Ptr ) {
00326 ret.assign(x_NextBytes(size), size);
00327 }
00328 else {
00329 ret.reserve(size);
00330 while ( size ) {
00331 size_t count = min(size, sizeof(m_Buffer));
00332 ret.assign(x_NextBytes(count), count);
00333 size -= count;
00334 }
00335 }
00336 return ret;
00337 }
00338
00339 string CParseBuffer::FullString(void)
00340 {
00341 string ret;
00342 if ( m_Ptr ) {
00343 ret.assign(m_Ptr, m_Size);
00344 m_Ptr += m_Size;
00345 m_Size = 0;
00346 }
00347 else {
00348 for ( ;; ) {
00349 size_t count = 0;
00350 if ( m_Descr.reader->Read(m_Buffer, sizeof(m_Buffer), &count) != eRW_Success ) {
00351 break;
00352 }
00353 ret.append(m_Buffer, count);
00354 }
00355 }
00356 return ret;
00357 }
00358
00359 const char* CParseBuffer::x_NextBytes(size_t size)
00360 {
00361 const char* ret = m_Ptr;
00362 if ( ret ) {
00363 if ( m_Size >= size ) {
00364 m_Ptr = ret + size;
00365 m_Size -= size;
00366 return ret;
00367 }
00368 }
00369 else if ( size <= sizeof(m_Buffer) ) {
00370 char* buf = m_Buffer;
00371 while ( size ) {
00372 size_t count = 0;
00373 if ( m_Descr.reader->Read(buf, size, &count) != eRW_Success ) {
00374 break;
00375 }
00376 buf += count;
00377 size -= count;
00378 }
00379 if ( size == 0 ) {
00380 return m_Buffer;
00381 }
00382 }
00383 NCBI_THROW(CLoaderException, eLoaderFailed,
00384 "parse buffer overflow");
00385 }
00386
00387 bool CParseBuffer::x_Eof(void) const
00388 {
00389 char buffer[1];
00390 size_t count;
00391 return m_Descr.reader->Read(buffer, 1, &count) == eRW_Eof;
00392 }
00393 }
00394
00395
00396
00397 bool CCacheReader::LoadStringSeq_ids(CReaderRequestResult& result,
00398 const string& seq_id)
00399 {
00400 if ( !m_IdCache ) {
00401 return false;
00402 }
00403
00404 CLoadLockSeq_ids ids(result, seq_id);
00405 return ReadSeq_ids(result, seq_id, ids);
00406 }
00407
00408
00409 bool CCacheReader::LoadSeq_idSeq_ids(CReaderRequestResult& result,
00410 const CSeq_id_Handle& seq_id)
00411 {
00412 if ( !m_IdCache ) {
00413 return false;
00414 }
00415
00416 CLoadLockSeq_ids ids(result, seq_id);
00417 return ReadSeq_ids(result, GetIdKey(seq_id), ids);
00418 }
00419
00420
00421 bool CCacheReader::LoadSeq_idGi(CReaderRequestResult& result,
00422 const CSeq_id_Handle& seq_id)
00423 {
00424 if ( !m_IdCache ) {
00425 return false;
00426 }
00427
00428 CLoadLockSeq_ids ids(result, seq_id);
00429 if ( !ids->IsLoadedGi() ) {
00430 CParseBuffer str(m_IdCache, GetIdKey(seq_id), 0, GetGiSubkey());
00431 if ( str.Found() ) {
00432 int gi = str.ParseInt4();
00433 if ( str.Done() ) {
00434 ids->SetLoadedGi(gi);
00435 return true;
00436 }
00437 }
00438 }
00439 return false;
00440 }
00441
00442
00443 bool CCacheReader::LoadSeq_idAccVer(CReaderRequestResult& result,
00444 const CSeq_id_Handle& seq_id)
00445 {
00446 if ( !m_IdCache ) {
00447 return false;
00448 }
00449
00450 CLoadLockSeq_ids ids(result, seq_id);
00451 if ( !ids->IsLoadedAccVer() ) {
00452 CParseBuffer str(m_IdCache, GetIdKey(seq_id), 0, GetAccVerSubkey());
00453 if ( str.Found() ) {
00454 string data = str.FullString();
00455 CSeq_id_Handle acch;
00456 if ( !data.empty() ) {
00457 CSeq_id id(data);
00458 acch = CSeq_id_Handle::GetHandle(id);
00459 }
00460 ids->SetLoadedAccVer(acch);
00461 return true;
00462 }
00463 }
00464 return false;
00465 }
00466
00467
00468 bool CCacheReader::LoadSeq_idLabel(CReaderRequestResult& result,
00469 const CSeq_id_Handle& seq_id)
00470 {
00471 if ( !m_IdCache ) {
00472 return false;
00473 }
00474
00475 CLoadLockSeq_ids ids(result, seq_id);
00476 if ( !ids->IsLoadedLabel() ) {
00477 CParseBuffer str(m_IdCache, GetIdKey(seq_id), 0, GetLabelSubkey());
00478 if ( str.Found() ) {
00479 ids->SetLoadedLabel(str.FullString());
00480 return true;
00481 }
00482 }
00483 return false;
00484 }
00485
00486
00487 bool CCacheReader::ReadSeq_ids(CReaderRequestResult& result,
00488 const string& key,
00489 CLoadLockSeq_ids& ids)
00490 {
00491 if ( !m_IdCache ) {
00492 return false;
00493 }
00494
00495 if ( ids.IsLoaded() ) {
00496 return true;
00497 }
00498
00499 CLoadInfoSeq_ids::TSeq_ids seq_ids;
00500 {{
00501 CConn conn(result, this);
00502 auto_ptr<IReader> reader
00503 (m_IdCache->GetReadStream(key, 0, GetSeq_idsSubkey()));
00504 if ( !reader.get() ) {
00505 conn.Release();
00506 return false;
00507 }
00508 CRStream r_stream(reader.get());
00509 CObjectIStreamAsnBinary obj_stream(r_stream);
00510 size_t count = static_cast<CObjectIStream&>(obj_stream).ReadUint4();
00511 for ( size_t i = 0; i < count; ++i ) {
00512 CSeq_id id;
00513 obj_stream >> id;
00514 seq_ids.push_back(CSeq_id_Handle::GetHandle(id));
00515 }
00516 conn.Release();
00517 }}
00518 ids->m_Seq_ids.swap(seq_ids);
00519 ids.SetLoaded();
00520 return true;
00521 }
00522
00523
00524 bool CCacheReader::LoadSeq_idBlob_ids(CReaderRequestResult& result,
00525 const CSeq_id_Handle& seq_id,
00526 const SAnnotSelector* sel)
00527 {
00528 if ( !m_IdCache ) {
00529 return false;
00530 }
00531
00532 CLoadLockBlob_ids ids(result, seq_id, sel);
00533 if( ids.IsLoaded() ) {
00534 return true;
00535 }
00536
00537 string subkey, true_subkey;
00538 GetBlob_idsSubkey(sel, subkey, true_subkey);
00539 CParseBuffer str(m_IdCache, GetIdKey(seq_id), 0, subkey);
00540 if ( str.Found() ) {
00541 if ( str.ParseInt4() != IDS_MAGIC ) {
00542 return false;
00543 }
00544 ids->clear();
00545 ids->SetState(str.ParseUint4());
00546 size_t blob_count = str.ParseUint4();
00547 for ( size_t i = 0; i < blob_count; ++i ) {
00548 CBlob_id id;
00549 id.SetSat(str.ParseUint4());
00550 id.SetSubSat(str.ParseUint4());
00551 id.SetSatKey(str.ParseUint4());
00552 CBlob_Info info(str.ParseUint4());
00553 size_t name_count = str.ParseUint4();
00554 for ( size_t j = 0; j < name_count; ++j ) {
00555 info.AddNamedAnnotName(str.ParseString());
00556 }
00557 ids.AddBlob_id(id, info);
00558 }
00559 if ( !true_subkey.empty() && str.ParseString() != true_subkey ) {
00560 ids->clear();
00561 return false;
00562 }
00563 ids.SetLoaded();
00564 if ( !str.Done() ) {
00565 ids->clear();
00566 return false;
00567 }
00568 }
00569 return true;
00570 }
00571
00572
00573 bool CCacheReader::LoadBlobVersion(CReaderRequestResult& result,
00574 const TBlobId& blob_id)
00575 {
00576 if ( !m_IdCache ) {
00577 return false;
00578 }
00579
00580 CParseBuffer str(m_IdCache, GetBlobKey(blob_id), 0, GetBlobVersionSubkey());
00581 if ( str.Found() ) {
00582 int version = str.ParseInt4();
00583 if ( str.Done() ) {
00584 SetAndSaveBlobVersion(result, blob_id, version);
00585 return true;
00586 }
00587 }
00588 return false;
00589 }
00590
00591
00592 bool CCacheReader::LoadBlob(CReaderRequestResult& result,
00593 const TBlobId& blob_id)
00594 {
00595 return LoadChunk(result, blob_id, CProcessor::kMain_ChunkId);
00596 }
00597
00598
00599 bool CCacheReader::LoadChunk(CReaderRequestResult& result,
00600 const TBlobId& blob_id,
00601 TChunkId chunk_id)
00602 {
00603 if ( !m_BlobCache ) {
00604 return false;
00605 }
00606
00607 CLoadLockBlob blob(result, blob_id);
00608 if ( CProcessor::IsLoaded(blob_id, chunk_id, blob) ) {
00609 return true;
00610 }
00611
00612 string key = GetBlobKey(blob_id);
00613 string subkey = GetBlobSubkey(chunk_id);
00614 if ( !blob.IsSetBlobVersion() ) {
00615 {{
00616 CConn conn(result, this);
00617 if ( !m_BlobCache->HasBlobs(key, subkey) ) {
00618 conn.Release();
00619 return false;
00620 }
00621 }}
00622 m_Dispatcher->LoadBlobVersion(result, blob_id);
00623 if ( !blob.IsSetBlobVersion() ) {
00624 return false;
00625 }
00626 }
00627 TBlobVersion version = blob.GetBlobVersion();
00628
00629 CConn conn(result, this);
00630 auto_ptr<IReader> reader(m_BlobCache->GetReadStream(key, version, subkey));
00631 if ( !reader.get() ) {
00632 conn.Release();
00633 return false;
00634 }
00635
00636 CRStream stream(reader.get());
00637 int processor_type = ReadInt(stream);
00638 const CProcessor& processor =
00639 m_Dispatcher->GetProcessor(CProcessor::EType(processor_type));
00640 if ( processor_type != processor.GetType() ) {
00641 NCBI_THROW_FMT(CLoaderException, eLoaderFailed,
00642 "CCacheReader::LoadChunk: "
00643 "invalid processor type: "<<processor_type);
00644 }
00645 int processor_magic = ReadInt(stream);
00646 if ( processor_magic != int(processor.GetMagic()) ) {
00647 NCBI_THROW_FMT(CLoaderException, eLoaderFailed,
00648 "CCacheReader::LoadChunk: "
00649 "invalid processor magic number: "<<processor_magic);
00650 }
00651 processor.ProcessStream(result, blob_id, chunk_id, stream);
00652 conn.Release();
00653 return true;
00654 }
00655
00656
00657 struct SPluginParams
00658 {
00659 typedef SCacheInfo::TParams TParams;
00660
00661 struct SDefaultValue {
00662 const char* name;
00663 const char* value;
00664 };
00665
00666
00667 static
00668 TParams* FindSubNode(TParams* params, const string& name)
00669 {
00670 if ( params ) {
00671 for ( TParams::TNodeList_I it = params->SubNodeBegin();
00672 it != params->SubNodeEnd(); ++it ) {
00673 if ( NStr::CompareNocase((*it)->GetKey(), name) == 0 ) {
00674 return static_cast<TParams*>(*it);
00675 }
00676 }
00677 }
00678 return 0;
00679 }
00680
00681
00682 static
00683 const TParams* FindSubNode(const TParams* params,
00684 const string& name)
00685 {
00686 if ( params ) {
00687 for ( TParams::TNodeList_CI it = params->SubNodeBegin();
00688 it != params->SubNodeEnd(); ++it ) {
00689 if ( NStr::CompareNocase((*it)->GetKey(), name) == 0 ) {
00690 return static_cast<const TParams*>(*it);
00691 }
00692 }
00693 }
00694 return 0;
00695 }
00696
00697
00698 static
00699 TParams* SetSubNode(TParams* params,
00700 const string& name,
00701 const char* default_value = "")
00702 {
00703 _ASSERT(!name.empty());
00704 TParams* node = FindSubNode(params, name);
00705 if ( !node ) {
00706 node = params->AddNode(TParams::TValueType(name, default_value));
00707 }
00708 return node;
00709 }
00710
00711
00712 static
00713 TParams* SetSubSection(TParams* params, const string& name)
00714 {
00715 return SetSubNode(params, name, "");
00716 }
00717
00718
00719 static
00720 const string& SetDefaultValue(TParams* params,
00721 const string& name,
00722 const char* value)
00723 {
00724 return SetSubNode(params, name, value)->GetValue().value;
00725 }
00726
00727
00728 static
00729 const string& SetDefaultValue(TParams* params, const SDefaultValue& value)
00730 {
00731 return SetDefaultValue(params, value.name, value.value);
00732 }
00733
00734
00735 static
00736 void SetDefaultValues(TParams* params, const SDefaultValue* values)
00737 {
00738 for ( ; values->name; ++values ) {
00739 SetDefaultValue(params, *values);
00740 }
00741 }
00742
00743 };
00744
00745
00746 static
00747 bool IsDisabledCache(const SCacheInfo::TParams* params)
00748 {
00749 const SCacheInfo::TParams* driver =
00750 SPluginParams::FindSubNode(params,
00751 NCBI_GBLOADER_READER_CACHE_PARAM_DRIVER);
00752 if ( driver ) {
00753 if ( driver->GetValue().value.empty() ) {
00754
00755 return true;
00756 }
00757 }
00758 return false;
00759 }
00760
00761
00762 static
00763 SCacheInfo::TParams* GetDriverParams(SCacheInfo::TParams* params)
00764 {
00765 const string& driver_name =
00766 SPluginParams::SetDefaultValue(params,
00767 NCBI_GBLOADER_READER_CACHE_PARAM_DRIVER,
00768 "bdb");
00769 return SPluginParams::SetSubSection(params, driver_name);
00770 }
00771
00772
00773 static
00774 SCacheInfo::TParams*
00775 GetCacheParamsCopy(const SCacheInfo::TParams* src_params,
00776 const char* section_name)
00777 {
00778 const SCacheInfo::TParams* src_section =
00779 SPluginParams::FindSubNode(src_params, section_name);
00780 if ( IsDisabledCache(src_section) ) {
00781
00782 return 0;
00783 }
00784 if ( src_section ) {
00785
00786 return new SCacheInfo::TParams(*src_section);
00787 }
00788 else {
00789
00790 return new SCacheInfo::TParams();
00791 }
00792 }
00793
00794 static const SPluginParams::SDefaultValue s_DefaultParams[] = {
00795 { "path", ".genbank_cache" },
00796 { "keep_versions", "all" },
00797 { "write_sync", "no" },
00798 { "mem_size", "20M" },
00799 { "log_file_max", "20M" },
00800 { "purge_batch_sleep", "500" },
00801 { "purge_thread_delay", "3600" },
00802 { "purge_clean_log", "16" },
00803 { 0, 0 }
00804 };
00805 static const SPluginParams::SDefaultValue s_DefaultIdParams[] = {
00806 { "name", "ids" },
00807 { "timeout", "172800" },
00808 { "timestamp", "subkey check_expiration" },
00809 { "page_size", "small" },
00810 { 0, 0}
00811 };
00812 static const SPluginParams::SDefaultValue s_DefaultBlobParams[] = {
00813 { "name", "blobs" },
00814 { "timeout", "432000" },
00815 { "timestamp", "onread expire_not_used" },
00816 { 0, 0 }
00817 };
00818 static const SPluginParams::SDefaultValue s_DefaultReaderParams[] = {
00819 { "purge_thread", "yes" },
00820 { 0, 0 }
00821 };
00822 static const SPluginParams::SDefaultValue s_DefaultWriterParams[] = {
00823 { "purge_thread", "no" },
00824 { 0, 0 }
00825 };
00826
00827 SCacheInfo::TParams*
00828 GetCacheParams(const SCacheInfo::TParams* src_params,
00829 SCacheInfo::EReaderOrWriter reader_or_writer,
00830 SCacheInfo::EIdOrBlob id_or_blob)
00831 {
00832 const char* section_name;
00833 if ( id_or_blob == SCacheInfo::eIdCache ) {
00834 section_name = NCBI_GBLOADER_READER_CACHE_PARAM_ID_SECTION;
00835 }
00836 else {
00837 section_name = NCBI_GBLOADER_READER_CACHE_PARAM_BLOB_SECTION;
00838 }
00839 auto_ptr<SCacheInfo::TParams> section
00840 (GetCacheParamsCopy(src_params, section_name));
00841 if ( !section.get() ) {
00842
00843 return 0;
00844 }
00845
00846 SCacheInfo::TParams* driver_params = GetDriverParams(section.get());
00847 SPluginParams::SetDefaultValues(driver_params, s_DefaultParams);
00848 if ( id_or_blob == SCacheInfo::eIdCache ) {
00849 SPluginParams::SetDefaultValues(driver_params, s_DefaultIdParams);
00850 }
00851 else {
00852 SPluginParams::SetDefaultValues(driver_params, s_DefaultBlobParams);
00853 }
00854 if ( reader_or_writer == SCacheInfo::eCacheReader ) {
00855 SPluginParams::SetDefaultValues(driver_params, s_DefaultReaderParams);
00856 }
00857 else {
00858 SPluginParams::SetDefaultValues(driver_params, s_DefaultWriterParams);
00859 }
00860 return section.release();
00861 }
00862
00863
00864 ICache* SCacheInfo::CreateCache(const TParams* params,
00865 EReaderOrWriter reader_or_writer,
00866 EIdOrBlob id_or_blob)
00867 {
00868 auto_ptr<TParams> cache_params
00869 (GetCacheParams(params, reader_or_writer, id_or_blob));
00870 if ( !cache_params.get() ) {
00871 return 0;
00872 }
00873 typedef CPluginManager<ICache> TCacheManager;
00874 CRef<TCacheManager> manager(CPluginManagerGetter<ICache>::Get());
00875 _ASSERT(manager);
00876 return manager->CreateInstanceFromKey
00877 (cache_params.get(), NCBI_GBLOADER_READER_CACHE_PARAM_DRIVER);
00878 }
00879
00880
00881 void CCacheReader::InitializeCache(CReaderCacheManager& cache_manager,
00882 const TPluginManagerParamTree* params)
00883 {
00884 const TPluginManagerParamTree* reader_params = params ?
00885 params->FindNode(NCBI_GBLOADER_READER_CACHE_DRIVER_NAME) : 0;
00886 ICache* id_cache = 0;
00887 ICache* blob_cache = 0;
00888 auto_ptr<TParams> id_params
00889 (GetCacheParams(reader_params, eCacheReader, eIdCache));
00890 auto_ptr<TParams> blob_params
00891 (GetCacheParams(reader_params, eCacheReader, eBlobCache));
00892 _ASSERT(id_params.get());
00893 _ASSERT(blob_params.get());
00894 const TParams* share_id_param =
00895 id_params->FindNode(NCBI_GBLOADER_WRITER_CACHE_PARAM_SHARE);
00896 bool share_id = !share_id_param ||
00897 NStr::StringToBool(share_id_param->GetValue().value);
00898 const TParams* share_blob_param =
00899 blob_params->FindNode(NCBI_GBLOADER_WRITER_CACHE_PARAM_SHARE);
00900 bool share_blob = !share_blob_param ||
00901 NStr::StringToBool(share_blob_param->GetValue().value);
00902 if (share_id || share_blob) {
00903 if ( share_id ) {
00904 ICache* cache = cache_manager.
00905 FindCache(CReaderCacheManager::fCache_Id,
00906 id_params.get());
00907 if ( cache ) {
00908 _ASSERT(!id_cache);
00909 id_cache = cache;
00910 }
00911 }
00912 if ( share_blob ) {
00913 ICache* cache = cache_manager.
00914 FindCache(CReaderCacheManager::fCache_Blob,
00915 blob_params.get());
00916 if ( cache ) {
00917 _ASSERT(!blob_cache);
00918 blob_cache = cache;
00919 }
00920 }
00921 }
00922 if ( !id_cache ) {
00923 id_cache = CreateCache(reader_params, eCacheReader, eIdCache);
00924 if ( id_cache ) {
00925 cache_manager.RegisterCache(*id_cache,
00926 CReaderCacheManager::fCache_Id);
00927 }
00928 }
00929 if ( !blob_cache ) {
00930 blob_cache = CreateCache(reader_params, eCacheReader, eBlobCache);
00931 if ( blob_cache ) {
00932 cache_manager.RegisterCache(*blob_cache,
00933 CReaderCacheManager::fCache_Blob);
00934 }
00935 }
00936 SetIdCache(id_cache);
00937 SetBlobCache(blob_cache);
00938 }
00939
00940
00941 void CCacheReader::ResetCache(void)
00942 {
00943 SetIdCache(0);
00944 SetBlobCache(0);
00945 }
00946
00947
00948 END_SCOPE(objects)
00949
00950
00951
00952
00953
00954
00955 using namespace objects;
00956
00957 class CCacheReaderCF :
00958 public CSimpleClassFactoryImpl<CReader, CCacheReader>
00959 {
00960 typedef CSimpleClassFactoryImpl<CReader, CCacheReader> TParent;
00961 public:
00962 CCacheReaderCF()
00963 : TParent(NCBI_GBLOADER_READER_CACHE_DRIVER_NAME, 0)
00964 {
00965 }
00966 ~CCacheReaderCF()
00967 {
00968 }
00969
00970
00971 CReader*
00972 CreateInstance(const string& driver = kEmptyStr,
00973 CVersionInfo version = NCBI_INTERFACE_VERSION(CReader),
00974 const TPluginManagerParamTree* params = 0) const
00975 {
00976 if ( !driver.empty() && driver != m_DriverName ) {
00977 return 0;
00978 }
00979 if ( !version.Match(NCBI_INTERFACE_VERSION(CReader)) ) {
00980 return 0;
00981 }
00982 return new CCacheReader;
00983 }
00984 };
00985
00986
00987 void NCBI_EntryPoint_CacheReader(
00988 CPluginManager<CReader>::TDriverInfoList& info_list,
00989 CPluginManager<CReader>::EEntryPointRequest method)
00990 {
00991 CHostEntryPointImpl<CCacheReaderCF>::NCBI_EntryPointImpl(info_list,
00992 method);
00993 }
00994
00995
00996 void NCBI_EntryPoint_xreader_cache(
00997 CPluginManager<CReader>::TDriverInfoList& info_list,
00998 CPluginManager<CReader>::EEntryPointRequest method)
00999 {
01000 NCBI_EntryPoint_CacheReader(info_list, method);
01001 }
01002
01003
01004 void GenBankReaders_Register_Cache(void)
01005 {
01006 RegisterEntryPoint<CReader>(NCBI_EntryPoint_CacheReader);
01007 }
01008
01009
01010 END_NCBI_SCOPE
01011
01012