1 #ifndef BDB_UTIL_HPP__
2 #define BDB_UTIL_HPP__
3
4 /* $Id: bdb_util.hpp 163327 2009-06-15 15:40:12Z ivanovp $
5 * ===========================================================================
6 *
7 * PUBLIC DOMAIN NOTICE
8 * National Center for Biotechnology Information
9 *
10 * This software/database is a "United States Government Work" under the
11 * terms of the United States Copyright Act. It was written as part of
12 * the author's official duties as a United States Government employee and
13 * thus cannot be copyrighted. This software/database is freely available
14 * to the public for use. The National Library of Medicine and the U.S.
15 * Government have not placed any restriction on its use or reproduction.
16 *
17 * Although all reasonable efforts have been taken to ensure the accuracy
18 * and reliability of the software and data, the NLM and the U.S.
19 * Government do not and cannot warrant the performance or results that
20 * may be obtained by using this software or data. The NLM and the U.S.
21 * Government disclaim all warranties, express or implied, including
22 * warranties of performance, merchantability or fitness for any particular
23 * purpose.
24 *
25 * Please cite the author in any work or product based on this material.
26 *
27 * ===========================================================================
28 *
29 * Author: Anatoliy Kuznetsov
30 *
31 * File Description: BDB library utilities.
32 *
33 *
34 */
35
36 #include <corelib/ncbireg.hpp>
37
38 #include <db/bdb/bdb_file.hpp>
39 #include <db/bdb/bdb_cursor.hpp>
40 #include <db/bdb/bdb_trans.hpp>
41
42 BEGIN_NCBI_SCOPE
43
44 /** @addtogroup BDB_Util
45 *
46 * @{
47 */
48
49
50 /// Template algorithm function to iterate the BDB File.
51 /// Func() is called for every dbf record.
52 template<class FL, class Func>
BDB_iterate_file(FL & dbf,Func & func)53 void BDB_iterate_file(FL& dbf, Func& func)
54 {
55 CBDB_FileCursor cur(dbf);
56
57 cur.SetCondition(CBDB_FileCursor::eFirst);
58 while (cur.Fetch() == eBDB_Ok) {
59 func(dbf);
60 }
61 }
62
63 /// Iterate file following the sequence of ids
64 /// BDB file should have an integer key
65 template<class FL, class IT, class Func>
BDB_iterate_file(FL & dbf,IT start,IT finish,Func & func)66 void BDB_iterate_file(FL& dbf, IT start, IT finish, Func& func)
67 {
68 CBDB_BufferManager& kbuf = *dbf.GetKeyBuffer();
69 _ASSERT(kbuf.FieldCount() == 1);
70 CBDB_Field& fld = kbuf.GetField(0);
71
72 for( ;start != finish; ++start) {
73 unsigned id = *start;
74 fld.SetInt((int)id);
75 if (dbf.Fetch() == eBDB_Ok) {
76 func(dbf);
77 }
78 } // for
79 }
80
81
82 /// Delete file records based on sequence of ids
83 ///
84 /// Records are getting deleted in batches (one transaction per batch)
85 /// We need batches not to overflow transaction log and not to lock
86 /// the file for a long time (to allow concurrent access)
87 ///
88 template<class IT, class Lock>
BDB_batch_delete_recs(CBDB_File & dbf,IT start,IT finish,unsigned batch_size,Lock * locker)89 void BDB_batch_delete_recs(CBDB_File& dbf,
90 IT start, IT finish,
91 unsigned batch_size,
92 Lock* locker)
93 {
94 if (batch_size == 0)
95 ++batch_size;
96 vector<unsigned> batch(batch_size);
97 CBDB_BufferManager& kbuf = *dbf.GetKeyBuffer();
98 _ASSERT(kbuf.FieldCount() == 1);
99 CBDB_Field& fld = kbuf.GetField(0);
100
101 while (start != finish) {
102 batch.resize(0);
103 for (unsigned i = 0;
104 i < batch_size && start != finish;
105 ++i, ++start) {
106
107 unsigned id = (unsigned) *start;
108 batch.push_back(id);
109 }
110 // delete the batch
111
112 if (batch.size() == 0)
113 continue;
114
115 if (locker) locker->Lock();
116 try {
117 CBDB_Transaction trans(*dbf.GetEnv(),
118 CBDB_Transaction::eTransASync);
119 dbf.SetTransaction(&trans);
120
121 ITERATE(vector<unsigned>, it, batch) {
122 unsigned id = *it;
123 fld.SetInt((int)id);
124 dbf.Delete(CBDB_RawFile::eIgnoreError);
125 }
126
127 trans.Commit();
128 } catch (...) {
129 if (locker) locker->Unlock();
130 throw;
131 }
132
133 if (locker) locker->Unlock();
134
135 } // while
136 }
137
138
139 class CBoyerMooreMatcher;
140
141
142 /// Find index of field containing the specified value
143 /// Search condition is specified by CBoyerMooreMatcher
144 /// By default search is performed in string fields, but if
145 /// tmp_str_buffer is specified function will try to convert
146 /// non-strings(int, float) and search in there.
147 ///
148 /// @param dbf
149 /// Database to search in. Should be positioned on some
150 /// record by Fetch or another method
151 /// @param matcher
152 /// Search condition substring matcher
153 /// @param tmp_str_buffer
154 /// Temporary string used for search in non-text fields
155 /// @return
156 /// 0 if value not found
157 NCBI_BDB_EXPORT
158 CBDB_File::TUnifiedFieldIndex
159 BDB_find_field(const CBDB_File& dbf,
160 const CBoyerMooreMatcher& matcher,
161 string* tmp_str_buffer = 0);
162
163 /// Return record id (integer key)
164 ///
165 /// @return
166 /// record integer key or 0 if it cannot be retrived
167 int NCBI_BDB_EXPORT BDB_get_rowid(const CBDB_File& dbf);
168
169 /* @} */
170
171
172 /// Create and configure BDB environment using CNcbiRegistry
173 /// as a parameter container
174 ///
175 NCBI_BDB_EXPORT
176 CBDB_Env* BDB_CreateEnv(const CNcbiRegistry& reg,
177 const string& section_name);
178
179
180 END_NCBI_SCOPE
181
182 #endif
183