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
00031
00032
00033 #include <ncbi_pch.hpp>
00034 #include <corelib/ncbiapp.hpp>
00035 #include <corelib/ncbiargs.hpp>
00036 #include <corelib/ncbifile.hpp>
00037 #include <corelib/ncbitime.hpp>
00038 #include <stdio.h>
00039
00040 #include <db/bdb/bdb_expt.hpp>
00041 #include <db/bdb/bdb_types.hpp>
00042 #include <db/bdb/bdb_file.hpp>
00043 #include <db/bdb/bdb_env.hpp>
00044 #include <db/bdb/bdb_cursor.hpp>
00045 #include <db/bdb/bdb_blob.hpp>
00046 #include <db/bdb/bdb_map.hpp>
00047 #include <db/bdb/bdb_blobcache.hpp>
00048 #include <db/bdb/bdb_filedump.hpp>
00049 #include <db/bdb/bdb_trans.hpp>
00050 #include <db/bdb/bdb_query.hpp>
00051 #include <db/bdb/bdb_util.hpp>
00052 #include <db/bdb/bdb_split_blob.hpp>
00053
00054 #include <util/line_reader.hpp>
00055
00056 #include <common/test_assert.h>
00057
00058 USING_NCBI_SCOPE;
00059
00060
00061
00062
00063
00064
00065
00066
00067
00068
00069 struct TestRec
00070 {
00071 unsigned count;
00072 unsigned blob_size;
00073 };
00074
00075
00076
00077
00078
00079
00080
00081 class CBDB_SplitTest : public CNcbiApplication
00082 {
00083 public:
00084 typedef CBDB_BlobSplitStore<bm::bvector<> > TBlobSplitStore;
00085
00086 public:
00087 void Init(void);
00088 int Run(void);
00089
00090 void LoadTestSet(const string& file_name);
00091
00092 void ReadTestSet(vector<TestRec> & test_set, const string& file_name);
00093 void LoadSplitStore(vector<TestRec>& test_set,
00094 TBlobSplitStore& split_store);
00095
00096 };
00097
00098
00099 void
00100 CBDB_SplitTest::LoadSplitStore(vector<TestRec>& test_set,
00101 TBlobSplitStore& split_store)
00102 {
00103 unsigned blob_id = 1;
00104 unsigned round = 0;
00105 CBDB_RawFile::TBuffer buffer;
00106
00107 for (size_t i = 0; i < test_set.size(); ++i) {
00108 TestRec& r = test_set[i];
00109 buffer.resize(r.blob_size);
00110 cout << "\nsize=" << r.blob_size << " count=" << r.count << endl;
00111 CStopWatch sw(CStopWatch::eStart);
00112 for (;r.count;r.count--) {
00113 split_store.UpdateInsert(blob_id,
00114 buffer.data(),
00115 buffer.size());
00116 ++blob_id;
00117 if ((r.count % 10000) == 0) {
00118 cerr << ".";
00119 }
00120 }
00121 cerr << "Elapsed = " << sw.Elapsed() << endl;
00122 }
00123 }
00124
00125 void CBDB_SplitTest::LoadTestSet(const string& file_name)
00126 {
00127 CBDB_Env env;
00128 env.SetLogInMemory(true);
00129 env.SetLogBSize(50 * 1024 * 1024);
00130 env.SetCacheSize(400 * 1024 * 1024);
00131 env.OpenWithTrans("e:\\db_split", CBDB_Env::eThreaded);
00132
00133 vector<TestRec> test_set;
00134 ReadTestSet(test_set, file_name);
00135 vector<TestRec> test_set2(test_set);
00136
00137 if (test_set.size() == 0) {
00138 cout << "Empty test load." << endl;
00139 return;
00140 }
00141 cout << "Loaded " << test_set.size() << " records." << endl;
00142
00143 {{
00144 TBlobSplitStore split_store_hash(new CBDB_BlobDeMux);
00145 split_store_hash.Open("split_hash",
00146 CBDB_RawFile::eCreate,
00147 CBDB_RawFile::eHash);
00148 split_store_hash.SetEnv(env);
00149
00150
00151 CStopWatch sw(CStopWatch::eStart);
00152 cout << "Loading hash store." << endl;
00153 LoadSplitStore(test_set, split_store_hash);
00154 cout << "Ok. elapsed=" << sw.Elapsed() << endl << endl;
00155 }}
00156
00157 {{
00158 TBlobSplitStore split_store_btree(new CBDB_BlobDeMux);
00159 split_store_btree.Open("split_btree",
00160 CBDB_RawFile::eCreate,
00161 CBDB_RawFile::eBtree);
00162 split_store_btree.SetVolumeCacheSize(100 * 1024 * 1024);
00163
00164 CStopWatch sw(CStopWatch::eStart);
00165 cout << "Loading btree store." << endl;
00166 LoadSplitStore(test_set2, split_store_btree);
00167 cout << "Ok. elapsed=" << sw.Elapsed() << endl << endl;
00168 }}
00169
00170 }
00171
00172 void CBDB_SplitTest::ReadTestSet(vector<TestRec>& test_set,
00173 const string& file_name)
00174 {
00175 cout << "Loading " << file_name << " ... " << endl;
00176 test_set.resize(0);
00177 CNcbiIfstream is(file_name.c_str());
00178 if (!is.good()) {
00179 return;
00180 }
00181 CStreamLineReader lr(is);
00182 for(++lr; !lr.AtEOF(); ++lr) {
00183 CTempString st = *lr;
00184 string count_str, size_str;
00185 string s = NStr::TruncateSpaces(st);
00186 NStr::SplitInTwo(s, " \t", count_str, size_str);
00187 TestRec rec;
00188 rec.count = NStr::StringToUInt(count_str,
00189 NStr::fAllowLeadingSpaces |
00190 NStr::fAllowTrailingSpaces |
00191 NStr::fConvErr_NoThrow);
00192 rec.blob_size = NStr::StringToUInt(size_str,
00193 NStr::fAllowLeadingSpaces |
00194 NStr::fAllowTrailingSpaces |
00195 NStr::fConvErr_NoThrow);
00196 if (rec.count && rec.blob_size) {
00197 test_set.push_back(rec);
00198 } else {
00199 cout << "Blank record: " << st << endl;
00200 }
00201 }
00202 cout << "ok " << endl;
00203
00204 }
00205
00206
00207
00208 void CBDB_SplitTest::Init(void)
00209 {
00210 SetDiagTrace(eDT_Enable);
00211
00212 SetDiagPostLevel(eDiag_Warning);
00213 SetDiagPostFlag(eDPF_File);
00214 SetDiagPostFlag(eDPF_Line);
00215 SetDiagPostFlag(eDPF_Trace);
00216
00217
00218 auto_ptr<CArgDescriptions> d(new CArgDescriptions);
00219 d->SetUsageContext("test_bdb_split",
00220 "test BDB split storage");
00221 SetupArgDescriptions(d.release());
00222 }
00223
00224
00225
00226 int CBDB_SplitTest::Run(void)
00227 {
00228
00229
00230
00231 cout << "Run BDB split storage test" << endl << endl;
00232
00233 char* buf_small = new char[256];
00234 char* buf_large = new char[1024*1024];
00235 char* buf_read = new char[2*1024*1024];
00236 void* buf = buf_read;
00237
00238 ::strcpy(buf_small, "test small 1");
00239 ::strcpy(buf_large, "test large 1");
00240
00241 try
00242 {
00243 {{
00244 TBlobSplitStore split_store(new CBDB_BlobDeMux(1024*1024));
00245
00246 split_store.Open("split", CBDB_RawFile::eCreate);
00247
00248 split_store.Insert(2, buf_large, 1024 * 1024);
00249 split_store.Insert(1, buf_small, 256);
00250
00251 ::strcpy(buf_small, "test small 2");
00252 ::strcpy(buf_large, "test large 2");
00253
00254 split_store.UpdateInsert(3, buf_small, 256);
00255 split_store.UpdateInsert(4, buf_large, 1024 * 1024);
00256
00257 split_store.FreeUnusedMem();
00258
00259 TBlobSplitStore::TBitVector bv;
00260 split_store.GetIdVector(&bv);
00261
00262 split_store.Save();
00263 }}
00264
00265 {{
00266 TBlobSplitStore split_store(new CBDB_BlobDeMux(1024*1024));
00267
00268 split_store.Open("split", CBDB_RawFile::eReadOnly);
00269 EBDB_ErrCode err;
00270 err =
00271 split_store.Fetch(1, &buf,
00272 2*1024*1024, CBDB_RawFile::eReallocForbidden, 0);
00273 assert(err == eBDB_Ok);
00274 int res = strcmp(buf_read, "test small 1");
00275 assert(res == 0);
00276 err =
00277 split_store.Fetch(4, &buf,
00278 2*1024*1024, CBDB_RawFile::eReallocForbidden, 0);
00279 assert(err == eBDB_Ok);
00280 res = strcmp(buf_read, "test large 2");
00281 assert(res == 0);
00282
00283 CBDB_RawFile::TBuffer chbuf(10);
00284 err = split_store.ReadRealloc(4, chbuf);
00285 assert(err == eBDB_Ok);
00286 assert(chbuf.size() > 12);
00287 res = strcmp((const char*)&chbuf[0], "test large 2");
00288 assert(res == 0);
00289
00290
00291 }}
00292
00293 }
00294 catch (CBDB_ErrnoException& ex)
00295 {
00296 cout << "Error! DBD errno exception:" << ex.what();
00297 return 1;
00298 }
00299 catch (CBDB_LibException& ex)
00300 {
00301 cout << "Error! DBD library exception:" << ex.what();
00302 return 1;
00303 }
00304
00305 cout << endl;
00306 cout << "TEST execution completed successfully!" << endl << endl;
00307 return 0;
00308 }
00309
00310
00311
00312
00313
00314
00315 int main(int argc, const char* argv[])
00316 {
00317
00318 return CBDB_SplitTest().AppMain(argc, argv, 0, eDS_Default, 0);
00319 }
00320
00321
00322
00323