1/*- 2 * See the file LICENSE for redistribution information. 3 * 4 * Copyright (c) 1997,2008 Oracle. All rights reserved. 5 * 6 * $Id: MpoolExample.cpp,v 12.8 2008/01/08 20:58:26 bostic Exp $ 7 */ 8 9#include <sys/types.h> 10 11#include <errno.h> 12#include <fcntl.h> 13#include <iostream> 14#include <fstream> 15#include <stdlib.h> 16#include <string.h> 17#include <time.h> 18 19#include <db_cxx.h> 20 21using std::cout; 22using std::cerr; 23using std::ios; 24using std::ofstream; 25 26#define MPOOL "mpool" 27 28int init(const char *, int, int); 29int run(DB_ENV *, int, int, int); 30 31static int usage(); 32 33const char *progname = "MpoolExample"; // Program name. 34 35class MpoolExample : public DbEnv 36{ 37public: 38 MpoolExample(); 39 int initdb(const char *home, int cachesize); 40 int run(int hits, int pagesize, int npages); 41 42private: 43 static const char FileName[]; 44 45 // no need for copy and assignment 46 MpoolExample(const MpoolExample &); 47 void operator = (const MpoolExample &); 48}; 49 50int main(int argc, char *argv[]) 51{ 52 int ret; 53 int cachesize = 20 * 1024; 54 int hits = 1000; 55 int npages = 50; 56 int pagesize = 1024; 57 58 for (int i = 1; i < argc; ++i) { 59 if (strcmp(argv[i], "-c") == 0) { 60 if ((cachesize = atoi(argv[++i])) < 20 * 1024) 61 usage(); 62 } 63 else if (strcmp(argv[i], "-h") == 0) { 64 if ((hits = atoi(argv[++i])) <= 0) 65 usage(); 66 } 67 else if (strcmp(argv[i], "-n") == 0) { 68 if ((npages = atoi(argv[++i])) <= 0) 69 usage(); 70 } 71 else if (strcmp(argv[i], "-p") == 0) { 72 if ((pagesize = atoi(argv[++i])) <= 0) 73 usage(); 74 } 75 else { 76 usage(); 77 } 78 } 79 80 // Initialize the file. 81 if ((ret = init(MPOOL, pagesize, npages)) != 0) 82 return (ret); 83 84 try { 85 MpoolExample app; 86 87 cout << progname 88 << ": cachesize: " << cachesize 89 << "; pagesize: " << pagesize 90 << "; N pages: " << npages << "\n"; 91 92 if ((ret = app.initdb(NULL, cachesize)) != 0) 93 return (ret); 94 if ((ret = app.run(hits, pagesize, npages)) != 0) 95 return (ret); 96 cout << "MpoolExample: completed\n"; 97 return (EXIT_SUCCESS); 98 } 99 catch (DbException &dbe) { 100 cerr << "MpoolExample: " << dbe.what() << "\n"; 101 return (EXIT_FAILURE); 102 } 103} 104 105// 106// init -- 107// Create a backing file. 108// 109int 110init(const char *file, int pagesize, int npages) 111{ 112 // Create a file with the right number of pages, and store a page 113 // number on each page. 114 ofstream of(file, ios::out | ios::binary); 115 116 if (of.fail()) { 117 cerr << "MpoolExample: " << file << ": open failed\n"; 118 return (EXIT_FAILURE); 119 } 120 char *p = new char[pagesize]; 121 memset(p, 0, pagesize); 122 123 // The pages are numbered from 0. 124 for (int cnt = 0; cnt <= npages; ++cnt) { 125 *(db_pgno_t *)p = cnt; 126 of.write(p, pagesize); 127 if (of.fail()) { 128 cerr << "MpoolExample: " << file << ": write failed\n"; 129 return (EXIT_FAILURE); 130 } 131 } 132 delete [] p; 133 return (EXIT_SUCCESS); 134} 135 136static int 137usage() 138{ 139 cerr << "usage: MpoolExample [-c cachesize] " 140 << "[-h hits] [-n npages] [-p pagesize]\n"; 141 return (EXIT_FAILURE); 142} 143 144// Note: by using DB_CXX_NO_EXCEPTIONS, we get explicit error returns 145// from various methods rather than exceptions so we can report more 146// information with each error. 147// 148MpoolExample::MpoolExample() 149: DbEnv(DB_CXX_NO_EXCEPTIONS) 150{ 151} 152 153int MpoolExample::initdb(const char *home, int cachesize) 154{ 155 set_error_stream(&cerr); 156 set_errpfx("MpoolExample"); 157 set_cachesize(0, cachesize, 0); 158 159 open(home, DB_CREATE | DB_INIT_MPOOL, 0); 160 return (EXIT_SUCCESS); 161} 162 163// 164// run -- 165// Get a set of pages. 166// 167int 168MpoolExample::run(int hits, int pagesize, int npages) 169{ 170 db_pgno_t pageno; 171 int cnt, ret; 172 void *p; 173 174 // Open the file in the environment. 175 DbMpoolFile *mfp; 176 177 if ((ret = memp_fcreate(&mfp, 0)) != 0) { 178 cerr << "MpoolExample: memp_fcreate failed: " 179 << strerror(ret) << "\n"; 180 return (EXIT_FAILURE); 181 } 182 mfp->open(MPOOL, 0, 0, pagesize); 183 184 cout << "retrieve " << hits << " random pages... "; 185 186 srand((unsigned int)time(NULL)); 187 for (cnt = 0; cnt < hits; ++cnt) { 188 pageno = (rand() % npages) + 1; 189 if ((ret = mfp->get(&pageno, NULL, 0, &p)) != 0) { 190 cerr << "MpoolExample: unable to retrieve page " 191 << (unsigned long)pageno << ": " 192 << strerror(ret) << "\n"; 193 return (EXIT_FAILURE); 194 } 195 if (*(db_pgno_t *)p != pageno) { 196 cerr << "MpoolExample: wrong page retrieved (" 197 << (unsigned long)pageno << " != " 198 << *(int *)p << ")\n"; 199 return (EXIT_FAILURE); 200 } 201 if ((ret = mfp->put(p, DB_PRIORITY_UNCHANGED, 0)) != 0) { 202 cerr << "MpoolExample: unable to return page " 203 << (unsigned long)pageno << ": " 204 << strerror(ret) << "\n"; 205 return (EXIT_FAILURE); 206 } 207 } 208 209 cout << "successful.\n"; 210 211 // Close the pool. 212 if ((ret = close(0)) != 0) { 213 cerr << "MpoolExample: " << strerror(ret) << "\n"; 214 return (EXIT_FAILURE); 215 } 216 return (EXIT_SUCCESS); 217} 218