00001 #ifndef BDB_FILE_HPP__
00002 #define BDB_FILE_HPP__
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
00031
00032
00033
00034
00035
00036
00037
00038 #include <corelib/ncbistre.hpp>
00039 #include <util/itransaction.hpp>
00040 #include <util/compress/compress.hpp>
00041 #include <db/bdb/bdb_types.hpp>
00042 #include <stdio.h>
00043
00044
00045 BEGIN_NCBI_SCOPE
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057 enum EBDB_ErrCode {
00058 eBDB_Ok,
00059 eBDB_NotFound,
00060 eBDB_KeyDup,
00061 eBDB_KeyEmpty,
00062 eBDB_MultiRowEnd
00063 };
00064
00065
00066 class CBDB_Env;
00067 class CBDB_Transaction;
00068
00069
00070
00071
00072 class CBDB_RawFile : public ITransactional
00073 {
00074 public:
00075 static const char kDefaultDatabase[];
00076
00077
00078 enum EOpenMode {
00079 eReadWrite,
00080 eReadOnly,
00081 eCreate,
00082 eReadWriteCreate
00083 };
00084
00085
00086 enum EDBType {
00087 eBtree,
00088 eQueue,
00089 eHash
00090 };
00091
00092
00093
00094
00095 enum EReallocMode {
00096 eReallocAllowed,
00097 eReallocForbidden
00098 };
00099
00100
00101 enum EDuplicateKeys {
00102 eDuplicatesDisable,
00103 eDuplicatesEnable
00104 };
00105
00106 enum EIgnoreError {
00107 eIgnoreError,
00108 eThrowOnError
00109 };
00110
00111
00112 enum ECompact {
00113
00114
00115 eCompactNoFree,
00116
00117
00118 eCompactFreeExisting,
00119
00120
00121 eCompactFreeAll
00122 };
00123
00124
00125 typedef CSimpleBuffer TBuffer;
00126
00127 public:
00128 CBDB_RawFile(EDuplicateKeys dup_keys = eDuplicatesDisable,
00129 EDBType db_type = eBtree);
00130 virtual ~CBDB_RawFile();
00131
00132
00133
00134 void SetEnv(CBDB_Env& env);
00135
00136
00137
00138 CBDB_Env* GetEnv() { return m_Env; }
00139
00140
00141 void Open(const string& filename,
00142 EOpenMode open_mode,
00143 bool support_dirty_read = false,
00144 unsigned rec_len = 0);
00145
00146
00147 void Open(const string& filename,
00148 const string& database,
00149 EOpenMode open_mode,
00150 bool support_dirty_read = false,
00151 unsigned rec_len = 0);
00152
00153
00154 void Attach(CBDB_RawFile& bdb_file);
00155
00156 void Close();
00157
00158 void Reopen(EOpenMode open_mode,
00159 bool support_dirty_read = false,
00160 unsigned rec_len = 0);
00161
00162
00163 void Remove(const string& filename, const string& database = kEmptyStr);
00164
00165 unsigned int Truncate();
00166
00167
00168 unsigned int SafeTruncate();
00169
00170 void Rename(const string& fname,
00171 const string& old_name,
00172 const string& new_name);
00173
00174
00175
00176 void Compact(ECompact compact_type = eCompactNoFree,
00177 int target_fill_pct = 0);
00178
00179
00180
00181
00182 typedef bool (*FContinueCompact)(void);
00183 void CompactEx(FContinueCompact compact_callback,
00184 ECompact compact_type = eCompactNoFree,
00185 int target_fill_pct = 0);
00186
00187
00188 void SetPageSize(unsigned int page_size);
00189
00190
00191 unsigned int GetPageSize();
00192
00193
00194 void SetCacheSize(unsigned int cache_size);
00195
00196
00197 void RevSplitOff();
00198
00199
00200 void DisableCmpOverride() { m_CmpOverride = false; }
00201
00202
00203
00204
00205 enum ECachePriority {
00206 eCache_Lowest,
00207 eCache_Low,
00208 eCache_Default,
00209 eCache_High,
00210 eCache_Highest
00211 };
00212 void SetCachePriority(ECachePriority priority);
00213
00214 const string& FileName() const;
00215 const string& Database() const;
00216
00217
00218
00219 virtual void SetCmp(DB*) = 0;
00220
00221
00222
00223 virtual void SetHash(DB*);
00224
00225
00226 bool IsOpen() const;
00227
00228
00229 bool IsAttached() const;
00230
00231
00232
00233 bool IsByteSwapped() const { return m_ByteSwapped; }
00234
00235
00236 bool DuplicatesAllowed() const { return m_DuplicateKeys == eDuplicatesEnable; }
00237
00238
00239 EDuplicateKeys GetDupKeysMode() const { return m_DuplicateKeys; }
00240
00241
00242 const string& GetFileName() const { return m_FileName; }
00243
00244
00245 EOpenMode GetOpenMode() const { return m_OpenMode; }
00246
00247
00248 void Sync();
00249
00250
00251
00252 unsigned CountRecs(bool bFast = false);
00253
00254
00255 void PrintStat(CNcbiOstream & out);
00256
00257
00258
00259 virtual void SetTransaction(ITransaction* trans);
00260 virtual void RemoveTransaction(ITransaction* trans);
00261 virtual ITransaction* GetTransaction();
00262
00263
00264 CBDB_Transaction* GetBDBTransaction() { return m_Trans; }
00265
00266
00267
00268 unsigned GetRecLen() const;
00269
00270
00271 void SetHashFillFactor(unsigned h_ffactor);
00272
00273
00274 void SetHashNelem(unsigned h_nelem);
00275
00276
00277
00278 void DisableHashOverride() { m_CmpOverride = false; }
00279
00280
00281 void SetBtreeMinKeysPerPage(unsigned int keys_per_page);
00282 unsigned int GetBtreeMinKeysPerPage();
00283
00284
00285
00286
00287
00288
00289
00290 void SetCompressor(ICompression* compressor,
00291 EOwnership own = eTakeOwnership);
00292
00293 private:
00294
00295 CBDB_RawFile(const CBDB_RawFile&);
00296 CBDB_RawFile& operator= (const CBDB_RawFile&);
00297
00298 protected:
00299 void x_Open(const char* filename, const char* database,
00300 EOpenMode open_mode,
00301 bool support_dirty_read,
00302 unsigned rec_len);
00303 void x_Create(const char* filename, const char* database);
00304
00305 void x_Close(EIgnoreError close_mode);
00306
00307
00308
00309
00310
00311 void x_CreateDB(unsigned rec_len);
00312
00313
00314
00315 void x_SetTransaction(CBDB_Transaction* trans);
00316
00317 void x_RemoveTransaction(CBDB_Transaction* trans);
00318
00319
00320
00321
00322
00323
00324 DB_TXN* GetTxn();
00325
00326
00327 DBC* CreateCursor(CBDB_Transaction* trans = 0,
00328 unsigned int flags = 0) const;
00329
00330
00331
00332
00333
00334
00335 int x_DB_Fetch(DBT *key,
00336 DBT *data,
00337 unsigned flags);
00338
00339
00340
00341
00342
00343
00344 int x_DBC_Fetch(DBC* dbc,
00345 DBT *key,
00346 DBT *data,
00347 unsigned flags);
00348
00349
00350
00351
00352 int x_DB_Put(DBT *key,
00353 DBT *data,
00354 unsigned flags);
00355
00356
00357
00358
00359 int x_DB_CPut(DBC* dbc,
00360 DBT *key,
00361 DBT *data,
00362 unsigned flags);
00363
00364
00365 int x_FetchBufferDecompress(DBT *data, void* usr_data);
00366
00367
00368
00369 virtual void x_SetByteSwapped(bool bswp);
00370
00371
00372 protected:
00373 EDBType m_DB_Type;
00374 DB* m_DB;
00375 DBT* m_DBT_Key;
00376 DBT* m_DBT_Data;
00377 CBDB_Env* m_Env;
00378 CBDB_Transaction* m_Trans;
00379 int m_TransAssociation;
00380 unsigned m_RecLen;
00381 unsigned m_H_ffactor;
00382 unsigned m_H_nelem;
00383 unsigned m_BT_minkey;
00384
00385 AutoPtr<ICompression> m_Compressor;
00386 TBuffer m_CompressBuffer;
00387
00388 private:
00389 bool m_DB_Attached;
00390 bool m_ByteSwapped;
00391 bool m_RevSplitOff;
00392 bool m_CmpOverride;
00393 string m_FileName;
00394 string m_Database;
00395 unsigned m_PageSize;
00396 unsigned m_CacheSize;
00397 EDuplicateKeys m_DuplicateKeys;
00398 EOpenMode m_OpenMode;
00399
00400 static const int kOpenFileMask;
00401
00402 friend class CBDB_FileCursor;
00403 };
00404
00405
00406
00407
00408
00409 class CBDB_MultiRowBuffer
00410 {
00411 public:
00412 CBDB_MultiRowBuffer(size_t buf_size);
00413 ~CBDB_MultiRowBuffer();
00414
00415
00416 const void* GetLastDataPtr() const { return m_LastData; }
00417
00418 size_t GetLastDataLen() const { return m_LastDataLen; }
00419 protected:
00420 void InitDBT();
00421 void MultipleInit();
00422 private:
00423 CBDB_MultiRowBuffer(const CBDB_MultiRowBuffer&);
00424 CBDB_MultiRowBuffer& operator=(const CBDB_MultiRowBuffer&);
00425 protected:
00426 DBT* m_Data_DBT;
00427 void* m_Buf;
00428 size_t m_BufSize;
00429 void* m_BufPtr;
00430 void* m_LastKey;
00431 void* m_LastData;
00432 size_t m_LastKeyLen;
00433 size_t m_LastDataLen;
00434
00435 friend class CBDB_File;
00436 };
00437
00438
00439
00440
00441
00442
00443
00444 class CBDB_File : public CBDB_RawFile
00445 {
00446 public:
00447 CBDB_File(EDuplicateKeys dup_keys = eDuplicatesDisable,
00448 EDBType db_type = eBtree);
00449
00450
00451 void Open(const string& filename,
00452 EOpenMode open_mode,
00453 bool support_dirty_read = false,
00454 unsigned rec_len = 0);
00455
00456
00457
00458 void Open(const string& filename,
00459 const string& database,
00460 EOpenMode open_mode,
00461 bool support_dirty_read = false,
00462 unsigned rec_len = 0);
00463
00464 void Reopen(EOpenMode open_mode, bool support_dirty_read = false);
00465
00466
00467
00468 void Attach(CBDB_File& db_file);
00469
00470
00471 EBDB_ErrCode Fetch() { return x_Fetch(0); }
00472
00473
00474
00475
00476 EBDB_ErrCode FetchForUpdate();
00477
00478 enum EAfterWrite {
00479 eKeepData,
00480 eDiscardData
00481 };
00482
00483
00484 EBDB_ErrCode Insert(EAfterWrite write_flag = eDiscardData);
00485
00486
00487
00488
00489
00490 unsigned Append(EAfterWrite write_flag = eDiscardData);
00491
00492
00493 EBDB_ErrCode Delete(EIgnoreError on_error=eThrowOnError);
00494
00495
00496
00497 EBDB_ErrCode UpdateInsert(EAfterWrite write_flag = eDiscardData);
00498
00499
00500 void BindKey (const char* field_name,
00501 CBDB_Field* key_field,
00502 size_t buf_size = 0);
00503
00504 void BindData(const char* field_name,
00505 CBDB_Field* data_field,
00506 size_t buf_size = 0,
00507 ENullable is_null = eNullable);
00508
00509
00510 void DuplicateStructure(const CBDB_File& dbf);
00511
00512
00513 const CBDB_BufferManager* GetKeyBuffer() const { return m_KeyBuf.get(); }
00514
00515
00516 const CBDB_BufferManager* GetDataBuffer() const { return m_DataBuf.get(); }
00517
00518
00519 CBDB_BufferManager* GetKeyBuffer() { return m_KeyBuf.get(); }
00520
00521
00522 CBDB_BufferManager* GetDataBuffer() { return m_DataBuf.get(); }
00523
00524
00525
00526 void SetFieldCompareLimit(unsigned int n_fields);
00527
00528
00529
00530 DBT* CloneDBT_Key();
00531
00532
00533 static void DestroyDBT_Clone(DBT* dbt);
00534
00535
00536 void SetLegacyStringsCheck(bool value);
00537
00538
00539
00540
00541
00542 typedef int TUnifiedFieldIndex;
00543
00544
00545
00546
00547
00548
00549
00550 TUnifiedFieldIndex GetFieldIdx(const string& name) const;
00551
00552
00553
00554
00555
00556 const CBDB_Field& GetField(TUnifiedFieldIndex idx) const;
00557 CBDB_Field& GetField(TUnifiedFieldIndex idx);
00558
00559
00560 void SetFieldOwnership(bool own_fields);
00561
00562
00563 bool IsOwnFields() const { return m_OwnFields; }
00564
00565
00566
00567 void CopyFrom(const CBDB_File& dbf);
00568
00569
00570 void Verify(const char* filename, const char* database, FILE* backup);
00571
00572
00573
00574 void EnablePrefixCompression() { m_PrefixCompress = true; }
00575
00576 protected:
00577
00578 void Discard();
00579
00580
00581
00582 virtual void SetCmp(DB*);
00583
00584
00585 EBDB_ErrCode ReadCursor(DBC* dbc, unsigned int bdb_flag);
00586
00587
00588 EBDB_ErrCode ReadCursor(DBC* dbc, unsigned int bdb_flag,
00589 void** buf,
00590 size_t buf_size,
00591 EReallocMode allow_realloc);
00592
00593 EBDB_ErrCode ReadCursor(DBC* dbc, unsigned int bdb_flag,
00594 TBuffer* buf);
00595
00596
00597
00598
00599
00600
00601
00602
00603 EBDB_ErrCode ReadCursor(DBC* dbc,
00604 unsigned int bdb_flag,
00605 CBDB_MultiRowBuffer* multirow_buf,
00606 bool multirow_only);
00607
00608
00609
00610 EBDB_ErrCode WriteCursor(DBC* dbc, unsigned int bdb_flag,
00611 EAfterWrite write_flag);
00612
00613
00614 EBDB_ErrCode WriteCursor(const void* data,
00615 size_t size,
00616 DBC* dbc, unsigned int bdb_flag,
00617 EAfterWrite write_flag);
00618
00619
00620 EBDB_ErrCode DeleteCursor(DBC* dbc, EIgnoreError);
00621
00622
00623
00624 void CheckNullDataConstraint() const;
00625
00626
00627
00628
00629
00630 void DisableDataBufProcessing() { m_DataBufDisabled = true; }
00631
00632
00633
00634 void DisableNull() { m_DisabledNull = true; }
00635
00636
00637
00638 void DisableDataPacking();
00639
00640
00641 EBDB_ErrCode x_Fetch(unsigned int flags);
00642
00643 virtual void x_SetByteSwapped(bool bswp);
00644
00645 private:
00646
00647 CBDB_File(const CBDB_File&);
00648 CBDB_File& operator= (const CBDB_File&);
00649
00650
00651 void x_StartRead();
00652
00653 void x_EndRead();
00654
00655 EBDB_ErrCode x_Write(unsigned int flags, EAfterWrite write_flag,
00656 DBC * dbc = 0);
00657
00658 void x_CheckConstructBuffers();
00659
00660 void x_ConstructKeyBuf();
00661 void x_ConstructDataBuf();
00662
00663 private:
00664 auto_ptr<CBDB_BufferManager> m_KeyBuf;
00665 auto_ptr<CBDB_BufferManager> m_DataBuf;
00666 bool m_BufsAttached;
00667 bool m_BufsCreated;
00668 bool m_DataBufDisabled;
00669 bool m_LegacyString;
00670 bool m_OwnFields;
00671 bool m_DisabledNull;
00672 bool m_PrefixCompress;
00673
00674 friend class CBDB_FileCursor;
00675 };
00676
00677
00678
00679
00680
00681
00682
00683 class CBDB_IdFile : public CBDB_File
00684 {
00685 public:
00686 CBDB_FieldInt4 IdKey;
00687
00688 public:
00689 CBDB_IdFile();
00690 virtual void SetCmp(DB* db);
00691 };
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705
00706 inline
00707 CBDB_File::TUnifiedFieldIndex BDB_GetUFieldIdx(int fidx, bool key)
00708 {
00709 _ASSERT(fidx >= 0);
00710 ++fidx;
00711 return key ? (-fidx) : (fidx);
00712 }
00713
00714
00715
00716
00717
00718
00719
00720 inline
00721 void CBDB_RawFile::Open(
00722 const string& filename, EOpenMode open_mode,
00723 bool support_dirty_read,
00724 unsigned rec_len)
00725 {
00726 Open(filename, kEmptyStr, open_mode, support_dirty_read, rec_len);
00727 }
00728
00729 inline
00730 unsigned CBDB_RawFile::GetRecLen() const
00731 {
00732 _ASSERT(m_DB_Type == eQueue);
00733 return m_RecLen;
00734 }
00735
00736 inline
00737 const string& CBDB_RawFile::FileName() const
00738 {
00739 return m_FileName;
00740 }
00741
00742
00743 inline
00744 const string& CBDB_RawFile::Database() const
00745 {
00746 return m_Database;
00747 }
00748
00749
00750 inline
00751 bool CBDB_RawFile::IsOpen() const
00752 {
00753 return !m_FileName.empty();
00754 }
00755
00756 inline
00757 bool CBDB_RawFile::IsAttached() const
00758 {
00759 return m_DB_Attached;
00760 }
00761
00762
00763
00764
00765
00766
00767
00768
00769
00770 inline
00771 void CBDB_File::Open(
00772 const string& filename, EOpenMode open_mode,
00773 bool support_dirty_read, unsigned rec_len)
00774 {
00775 Open(filename, "", open_mode, support_dirty_read, rec_len);
00776 }
00777
00778
00779 inline
00780 void CBDB_File::CheckNullDataConstraint() const
00781 {
00782 if ( !m_DisabledNull && m_DataBuf.get() )
00783 m_DataBuf->CheckNullConstraint();
00784 }
00785
00786 inline
00787 void CBDB_File::SetFieldCompareLimit(unsigned int n_fields)
00788 {
00789 m_KeyBuf->SetFieldCompareLimit(n_fields);
00790 }
00791
00792
00793 END_NCBI_SCOPE
00794
00795 #endif
00796
00797