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