⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 xvltest.cc

📁 harvest是一个下载html网页得机器人
💻 CC
字号:
/************************************************************************************************* * Test cases of Villa for C++ *                                                      Copyright (C) 2000-2003 Mikio Hirabayashi * This file is part of QDBM, Quick Database Manager. * QDBM is free software; you can redistribute it and/or modify it under the terms of the GNU * Lesser General Public License as published by the Free Software Foundation; either version * 2.1 of the License or any later version.  QDBM is distributed in the hope that it will be * useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more * details. * You should have received a copy of the GNU Lesser General Public License along with QDBM; if * not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA * 02111-1307 USA. *************************************************************************************************/#include <xvilla.h>#include <cstdlib>#include <cstdio>#include <cstring>#include <ctime>#include <iostream>#include <iomanip>extern "C" {#include <pthread.h>#include <unistd.h>#include <sys/types.h>}using namespace std;using namespace qdbm;/* global constants */const int RECBUFSIZ = 32;const int LRECMAX = 25;const int NIDXMAX = 64;const int LCNUM = 32;const int NCNUM = 32;/* struct for argument of threads */struct Mission {  Villa* villa;  int rnum;  int id;  bool printer;};/* global variables */const char* progname;/* function prototypes */int main(int argc, char** argv);void myterminate();void myunexpected();void usage();int runwrite(int argc, char** argv);int runread(int argc, char** argv);int runmulti(int argc, char** argv);int runmisc(int argc, char** argv);void pxdperror(const char* name, DBM_error &e);int myrand(void);int dowrite(const char* name, int rnum);int doread(const char* name);int domulti(const char* name, int rnum, int tnum);void* mtwriter(void* arg);int domisc(const char* name);/* main routine */int main(int argc, char** argv){  int rv;  progname = argv[0];  set_terminate(myterminate);  set_unexpected(myunexpected);  if(argc < 2) usage();  rv = 0;  if(!strcmp(argv[1], "write")){    rv = runwrite(argc, argv);  } else if(!strcmp(argv[1], "read")){    rv = runread(argc, argv);  } else if(!strcmp(argv[1], "multi")){    rv = runmulti(argc, argv);  } else if(!strcmp(argv[1], "misc")){    rv = runmisc(argc, argv);  } else {    usage();  }  return rv;}/* for debug */void myterminate(){  cout << progname << ": terminate" << endl;  exit(1);}/* for debug */void myunexpected(){  cout << progname << ": unexpected" << endl;  exit(1);}/* print the usage and exit */void usage(){  cerr << progname << ": test cases for Villa for C++" << endl;  cerr << endl;  cerr << "usage:" << endl;  cerr << "  " << progname << " write name rnum" << endl;  cerr << "  " << progname << " read name" << endl;  cerr << "  " << progname << " multi name rnum tnum" << endl;  cerr << "  " << progname << " misc name" << endl;  exit(1);}/* parse arguments of write command */int runwrite(int argc, char** argv){  char *name, *rstr;  int i, rnum, rv;  name = 0;  rstr = 0;  for(i = 2; i < argc; i++){    if(argv[i][0] == '-'){      usage();    } else if(!name){      name = argv[i];    } else if(!rstr){      rstr = argv[i];    } else {      usage();    }  }  if(!name || !rstr) usage();  rnum = atoi(rstr);  if(rnum < 1) usage();  rv = dowrite(name, rnum);  return rv;}/* parse arguments of read command */int runread(int argc, char** argv){  char* name;  int i, rv;  name = 0;  for(i = 2; i < argc; i++){    if(argv[i][0] == '-'){      usage();    } else if(!name){      name = argv[i];    } else {      usage();    }  }  if(!name) usage();  rv = doread(name);  return rv;}/* parse arguments of multi command */int runmulti(int argc, char** argv){  char *name, *rstr, *tstr;  int i, rnum, tnum, rv;  name = 0;  rstr = 0;  tstr = 0;  for(i = 2; i < argc; i++){    if(argv[i][0] == '-'){      usage();    } else if(!name){      name = argv[i];    } else if(!rstr){      rstr = argv[i];    } else if(!tstr){      tstr = argv[i];    } else {      usage();    }  }  if(!name || !rstr || !tstr) usage();  rnum = atoi(rstr);  tnum = atoi(tstr);  if(rnum < 1 || tnum < 1) usage();  rv = domulti(name, rnum, tnum);  return rv;}/* parse arguments of misc command */int runmisc(int argc, char** argv){  char* name;  int i, rv;  name = 0;  for(i = 2; i < argc; i++){    if(argv[i][0] == '-'){      usage();    } else if(!name){      name = argv[i];    } else {      usage();    }  }  if(!name) usage();  rv = domisc(name);  return rv;}/* print an error message */void pxdperror(const char* name, DBM_error &e){  cerr << progname << ": " << name << ": " << e << endl;}/* pseudo random number generator */int myrand(void){  static int cnt = 0;  if(cnt == 0) std::srand(std::time(NULL));  return (std::rand() * std::rand() + (std::rand() >> (sizeof(int) * 4)) + (cnt++)) & 0x7FFFFFFF;}/* do writing test */int dowrite(const char* name, int rnum){  int i, len;  char buf[RECBUFSIZ];  cout << "<Writing Test>" << endl;  cout << "  name=" << name << "  rnum=" << rnum << endl;  cout << endl;  Villa* villa = 0;  bool err = false;  try {    // open the database    villa = new Villa(name, Villa::OWRITER | Villa::OCREAT | Villa::OTRUNC);    // roop for storing    for(i = 1; i <= rnum; i++){      // set a buffer for a key and a value      len = sprintf(buf, "%08d", i);      // store a record into the database      villa->put(buf, len, buf, len);      // print progression      if(rnum > 250 && i % (rnum / 250) == 0){        cout << '.';        cout.flush();        if(i == rnum || i % (rnum / 10) == 0){          cout << " (" << setw(8) << setfill('0') << i << ")" << endl;          cout.flush();        }      }    }    // close the database    villa->close();    cout << "ok" << endl << endl;  } catch(Villa_error& e){    err = true;    // report an error    pxdperror(name, e);  }  // destroy instance  if(villa) delete villa;  return err ? 1 : 0;}/* do reading test */int doread(const char* name){  int i, rnum, len;  char buf[RECBUFSIZ], *val;  cout << "<Reading Test>" << endl;  cout << "  name=" << name << endl;  cout << endl;  Villa* villa = 0;  bool err = false;  try {    // open the database    villa = new Villa(name);    // get the number of records    rnum = villa->rnum();    // roop for retrieving    for(i = 1; i <= rnum; i++){      // set a buffer for a key      len = sprintf(buf, "%08d", i);      // retrieve a record from the database      val = villa->get(buf, len);      free(val);      // print progression      if(rnum > 250 && i % (rnum / 250) == 0){        cout << '.';        cout.flush();        if(i == rnum || i % (rnum / 10) == 0){          cout << " (" << setw(8) << setfill('0') << i << ")" << endl;          cout.flush();        }      }    }    // close the database    villa->close();    cout << "ok" << endl << endl;  } catch(Villa_error& e){    err = true;    // report an error    pxdperror(name, e);  }  // destroy instance  if(villa) delete villa;  return err ? 1 : 0;}/* do multi thread test */int domulti(const char* name, int rnum, int tnum){  Villa* villa;  pthread_t* tids;  bool* tsts;  Mission* mss;  Villa_error* ep;  int i, len, size, vnum;  bool err;  char buf[RECBUFSIZ], *val;  cout << "<Multi-thread Test>" << endl;  cout << "  name=" << name << "  rnum=" << rnum << "  tnum=" << tnum << endl;  cout << endl;  // open the database  villa = 0;  try {    cout << "Creating a database ... ";    villa = new Villa(name, Villa::OWRITER | Villa::OCREAT | Villa::OTRUNC);    villa->settuning(LRECMAX, NIDXMAX, LCNUM, NCNUM);    cout << "ok" << endl;  } catch(Villa_error& e){    if(villa) delete villa;    pxdperror(name, e);    return 1;  }  // prepare threads  tids = new pthread_t[tnum];  tsts = new bool[tnum];  mss = new Mission[tnum];  err = false;  // roop for each threads  cout << "Writing" << endl;  for(i = 0; i < tnum; i++){    mss[i].villa = villa;    mss[i].rnum = rnum;    mss[i].id = i;    mss[i].printer = (i == tnum / 2);    if(pthread_create(tids + i, 0, mtwriter, (void*)(mss + i)) == 0){      tsts[i] = true;    } else {      tsts[i] = false;      err = true;      cerr << progname << ": " << name << ": " << "pthread error" << endl;    }  }  // join every threads  for(i = 0; i < tnum; i++){    if(tsts[i]){      if(pthread_join(tids[i], (void**)&ep) != 0){        err = true;        cerr << progname << ": " << name << ": " << "pthread error" << endl;      }    }    if(ep){      err = true;      pxdperror(name, *ep);      delete ep;    }  }  delete[] mss;  delete[] tsts;  delete[] tids;  if(!err) cout << "ok" << endl;  cout.flush();  // check every record  cout << "Validation checking ... ";  try {    for(i = 1; i <= rnum; i++){      len = sprintf(buf, "%08d", i);      val = villa->get(buf, len, &size);      free(val);      if(size != 1){        cerr << progname << ": " << name << ": " << "size error: " << size << endl;        err = true;      }      vnum = villa->vnum(buf, len);      if(vnum != tnum){        cerr << progname << ": " << name << ": " << "vnum error: " << vnum << endl;        err = true;      }    }  } catch(Villa_error& e){    pxdperror(name, e);    err = true;  }  if(!err) cout << "ok" << endl;  // close the database  cout << "Closing the database ... ";  try {    villa->close();  } catch(Villa_error& e){    pxdperror(name, e);    delete villa;    return 1;  }  cout << "ok" << endl;  if(!err) cout << "all ok" << endl << endl;  delete villa;  return err ? 1 : 0;}/* writer with each thread */void* mtwriter(void* arg){  Mission* mp = (Mission*)arg;  Villa* villa = mp->villa;  int rnum = mp->rnum;  int id = mp->id;  bool printer = mp->printer;  char buf[RECBUFSIZ];  void* mc;  int i, len;  // roop for storing  for(i = 1; i <= rnum; i++){    len = sprintf(buf, "%08d", i);    // store a record    bool tran = false;    try {      if(myrand() % (mp->rnum / 7 + 1) == 0){        villa->tranbegin();        tran = true;      }      villa->put(buf, len, id % 2 ? "*" : "=", 1, Villa::DDUP);    } catch(Villa_error& e){      if(tran) villa->tranabort();      return new Villa_error(e);    }    if(tran) villa->trancommit();    // print progression    if(printer && rnum > 250 && i % (rnum / 250) == 0){      cout << '.';      cout.flush();      if(i == rnum || i % (rnum / 10) == 0){        cout << " (" << setw(8) << setfill('0') << i << ")" << endl;        cout.flush();      }    }    // malloc reentrant check    if((mc = (char*)malloc(1)) != 0){      free(mc);    } else {      return new Villa_error(Villa::EALLOC);    }  }  return 0;}/* do combination test */int domisc(const char* name){  bool err;  int i, len;  char buf[RECBUFSIZ];  cout << "<Miscellaneous Test>" << endl;  cout << "  name=" << name << endl;  cout << endl;  err = false;  ADBM* adbm = 0;  try {    // open the database    cout << "Creating a database ... ";    adbm = new Villa(name, Villa::OWRITER | Villa::OCREAT | Villa::OTRUNC);    cout << "ok" << endl;    // write with datadase abstraction    cout << "Writing with database abstraction ... ";    for(i = 1; i <= 100; i++){      len = sprintf(buf, "%08d", i);      Datum key(buf, len);      Datum val(buf, len);      adbm->storerec(key, val, true);    }    cout << "ok" << endl;    // read with datadase abstraction    cout << "Reading with database abstraction ... ";    for(i = 1; i <= 100; i++){      len = sprintf(buf, "%08d", i);      Datum key(buf, len);      const Datum& val = adbm->fetchrec(key);      len = val.size();      if(len != 8) throw DBM_error("size error");    }    cout << "ok" << endl;    // traversal access with database abstraction    cout << "Traversal access with database abstraction ... ";    i = 0;    try {      for(adbm->firstkey(); true; adbm->nextkey()){        i++;      }    } catch(DBM_error& e){      if(adbm->error()) throw;    }    if(i != 100) throw DBM_error("iteration error");    cout << "ok" << endl;    // close the database    cout << "Closing the database ... ";    adbm->close();    cout << "ok" << endl;  } catch(DBM_error& e){    err = true;    pxdperror(name, e);  }  if(adbm) delete adbm;  if(err) return 1;  Villa* villa = 0;  try {    // open the database    cout << "Opening the database ... ";    villa = new Villa(name);    cout << "ok" << endl;    // traversal access    cout << "Traversal access ... ";    try {      villa->curfirst();      for(i = 0; true; i++){        villa->curnext();      }      if(i != 100) throw Villa_error();    } catch(Villa_error& e){      if(e != Villa::ENOITEM) throw;    }    cout << "ok" << endl;    // checking information    cout << "Checking information" << endl;    cout << "  - fsiz ... " << villa->fsiz() << endl;    cout << "  - lnum ... " << villa->lnum() << endl;    cout << "  - nnum ... " << villa->nnum() << endl;    cout << "  - rnum ... " << villa->rnum() << endl;    cout << "  - writable ... " << villa->writable() << endl;    cout << "  - fatalerror ... " << villa->fatalerror() << endl;    cout << "  - inode ... " << villa->inode() << endl;    cout << "ok" << endl;    // close the database    cout << "Closing the database ... ";    villa->close();    cout << "ok" << endl;  } catch(Villa_error& e){    err = true;    pxdperror(name, e);  }  if(villa) delete villa;  if(err) return 1;  villa = 0;  try {    // open the database    cout << "Opening the database ... ";    villa = new Villa(name, Villa::OWRITER);    cout << "ok" << endl;    // sync the database    cout << "Syncing the database ... ";    villa->sync();    cout << "ok" << endl;    // optimize the database    cout << "Optimizing the database ... ";    villa->optimize();    cout << "ok" << endl;    // close the database    cout << "Closing the database ... ";    villa->close();    cout << "ok" << endl;  } catch(Villa_error& e){    err = true;    pxdperror(name, e);  }  if(villa) delete villa;  if(err) return 1;  cout << "all ok" << endl << endl;  return 0;}/* END OF FILE */

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -