diff options
author | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 |
---|---|---|
committer | Jesse Morgan <jesse@jesterpm.net> | 2016-12-17 21:28:53 -0800 |
commit | 54df2afaa61c6a03cbb4a33c9b90fa572b6d07b8 (patch) | |
tree | 18147b92b969d25ffbe61935fb63035cac820dd0 /db-4.8.30/test_stl/base/test.h |
Berkeley DB 4.8 with rust build script for linux.
Diffstat (limited to 'db-4.8.30/test_stl/base/test.h')
-rw-r--r-- | db-4.8.30/test_stl/base/test.h | 470 |
1 files changed, 470 insertions, 0 deletions
diff --git a/db-4.8.30/test_stl/base/test.h b/db-4.8.30/test_stl/base/test.h new file mode 100644 index 0000000..f5ad545 --- /dev/null +++ b/db-4.8.30/test_stl/base/test.h @@ -0,0 +1,470 @@ +/*- + * See the file LICENSE for redistribution information. + * + * Copyright (c) 2009 Oracle. All rights reserved. + * + * $Id$ + */ + +#ifndef _DB_STL_TEST_H__ +#define _DB_STL_TEST_H__ + +#include <time.h> + +#include <utility> +#include <functional> +#include <algorithm> +#include <iostream> +#include <vector> +#include <list> +#include <queue> +#include <stack> +#include <fstream> +#include <map> +#include <set> +#include <string> + +#include "db_config.h" +#include "db_int.h" + +#define DB_STL_HAVE_DB_TIMESPEC 1 +#include "dbstl_map.h" +#include "dbstl_set.h" +#include "dbstl_vector.h" + +#include "ptype.h" + +using namespace std; +using namespace dbstl; + +///////////////////////////////////////////////////////////////////////// +///////////////////////// Macro and typedef definitions /////////// + +#define check_expr(expression) do { \ + if (!(expression)) { \ + FailedAssertionException ex(__FILE__, __LINE__, #expression);\ + throw ex; } } while (0) + +#define TEST_PRIMITIVE +#ifndef TEST_PRIMITIVE +typedef ptype<int> ptint; +typedef db_vector<ptint> intvec_t; +typedef db_vector<ptint> ptint_vector; +typedef db_map<ptint, ptint> dm_int_t; +typedef db_multimap<ptint, ptint> dmm_int_t; +typedef db_set<ptint> dms_int_t; +typedef db_multiset<ptint> dmms_int_t; +#define TOINT +#else +#define ptint int +#define TOINT (int) +typedef db_vector<ptint, ElementHolder<ptint> > intvec_t; +typedef db_vector<ptint, ElementHolder<ptint> > ptint_vector; +typedef db_map<ptint, ptint, ElementHolder<ptint> > dm_int_t; +typedef db_multimap<ptint, ptint, ElementHolder<ptint> > dmm_int_t; +typedef db_set<ptint, ElementHolder<ptint> > dms_int_t; +typedef db_multiset<ptint, ElementHolder<ptint> > dmms_int_t; +#endif + +#define DELDB(pdb) if (pdb){delete pdb; pdb = NULL;} +#define print_mm(dmm1, dmmi) \ +for (dmmi = dmm1.begin(); dmmi != dmm1.end(); dmmi++) \ + cout<<dmmi->first<<'\t'<<dmmi->second; + +// Portable thread functions, supporting Win32 and pthread libraries +// These functions are used by the multi-threaded test. +#if defined(DB_WIN32) || defined(WIN32) + +extern "C" { +extern int getopt(int, char * const *, const char *); +extern char *optarg; +extern int optind; +} + +typedef HANDLE os_pid_t; +typedef HANDLE os_thread_t; + +#define os_thread_create(thrp, attr, func, arg) \ + (((*(thrp) = CreateThread(NULL, 0, \ + (LPTHREAD_START_ROUTINE)(func), (arg), 0, NULL)) == NULL) ? -1 : 0) +#define os_thread_join(thr, statusp) \ + ((WaitForSingleObject((thr), INFINITE) == WAIT_OBJECT_0) && \ + GetExitCodeThread((thr), (LPDWORD)(statusp)) ? 0 : -1) +#define os_thread_self() GetCurrentThreadId() +#else /* !DB_WIN32 */ + +#include <sys/wait.h> +#include <pthread.h> + +typedef pid_t os_pid_t; +typedef pthread_t os_thread_t; + +#define os_thread_create(thrp, attr, func, arg) \ + pthread_create((thrp), (attr), (func), (arg)) +#define os_thread_join(thr, statusp) pthread_join((thr), (statusp)) +#define os_thread_self() pthread_self() +#endif /* !DB_WIN32 */ + +//////////////////////////////////////////////////////////////////////////// +///////////////////// Global variable declarations //////////////////////// +/*extern DbEnv *penv; +extern Db *db, *db2, *db3, *dmdb1, *dmdb2, *dmmdb1, *dmmdb2, *dmsdb1, + *dmsdb2, *dmmsdb1, *dmmsdb2, *dbstrv; +*/ +extern int g_StopInsert; +extern ofstream fout; +extern size_t g_count[256]; +extern char *optarg; +extern int g_test_start_txn; +extern DbEnv *g_env; +extern int optind; +/////////////////////////////////////////////////////////////////////// +//////////////////////// Function Declarations //////////////////// +// XXX!!! Function templates can't be declared here otherwise the declarations +// here will be deemed as the definition, so at link time these symbols are +// not resolved. So like class templates, function templates can't be separated +// as declarations and definitions, only definitions and only be built into one +// object file otherwise there will be "multiple symbol definitions". OTOH, compilers +// can avoid the multiple definitions if we are building a class template instantiation +// in multiple object files, so class tempaltes are recommended to use rather than +// function templates. Only use function templates if it is a simple one and used +// only in one code file. +// +size_t g_sum(size_t s, size_t e); +bool is_odd(ptint s); +ptint addup(const ptint&i, const ptint&j); +ptint randint(); +int randpos(int p); +bool is2digits(ptint i); +int rmdir_rcsv(const char *dir, bool keep_this_dir); +bool strlt(const string&, const string&); +bool strlt0(const char *s1, const char *s2); +bool streq0(const char *s1, const char *s2); +bool streq(const string&, const string&); + +int get_dest_secdb_callback(Db *secondary, const Dbt *key, + const Dbt *data, Dbt *result); +void copy_array(TCHAR**arr, TCHAR***dest); +void using_charstr(TCHAR*str); +void usage(); +int test_assoc(void* param1); +int test_vector(void* param1); + +class RGBB; +class SMSMsg2; +void SMSMsgRestore(SMSMsg2& dest, const void *srcdata); +u_int32_t SMSMsgSize(const SMSMsg2& elem); +void SMSMsgCopy(void *dest, const SMSMsg2&elem); +typedef bool (*ptintless_ft)(const ptint& a, const ptint& b); +bool ptintless(const ptint& a, const ptint& b); +u_int32_t rgblen(const RGBB * seq); +void rgbcpy(RGBB *seq, const RGBB *, size_t); + + +///////////////////////////////////////////////////////////////////////////////// +////////////////////////// Utility class definitions /////////////////////////// + +class BaseMsg +{ +public: + time_t when; + int to; + int from; + + BaseMsg() + { + to = from = 0; + when = 0; + } + + BaseMsg(const BaseMsg& msg) + { + to = msg.to; + from = msg.from; + when = msg.when; + } + + bool operator==(const BaseMsg& msg2) const + { + return when == msg2.when && to == msg2.to && from == msg2.from; + } + + bool operator<(const BaseMsg& msg2) const + { + return to < msg2.to; + } +}; + +// used to test arbitary obj storage(not in one chunk) +class SMSMsg2 : public BaseMsg +{ +public: + typedef SMSMsg2 self; + SMSMsg2(time_t tm, const char *msgp, int t) + { + memset(this, 0, sizeof(*this)); + when = tm; + szmsg = strlen(msgp) + 1; + msg = (char *)DbstlMalloc(szmsg); + strncpy(msg, msgp, szmsg); + to = t; + + mysize = sizeof(*this); //+ szmsg; + } + + SMSMsg2() + { + memset(this, 0, sizeof(SMSMsg2)); + } + + SMSMsg2(const self& obj) : BaseMsg(obj) + { + mysize = obj.mysize; + szmsg = obj.szmsg; + if (szmsg > 0 && obj.msg != NULL) { + msg = (char *)DbstlMalloc(szmsg); + strncpy(msg, obj.msg, szmsg); + } else + msg = NULL; + } + + ~SMSMsg2() + { + if (msg) + free(msg); + } + + const self& operator = (const self &obj) + { + + this->from = obj.from; + to = obj.to; + when = obj.when; + mysize = obj.mysize; + szmsg = obj.szmsg; + if (szmsg > 0 && obj.msg != NULL) { + msg = (char *)DbstlReAlloc(msg, szmsg); + strncpy(msg, obj.msg, szmsg); + } + return obj; + } + + bool operator == (const self&obj) const + { + return BaseMsg::operator==(obj) && strcmp(obj.msg, msg) == 0; + } + + const static size_t BUFLEN = 256; + size_t mysize; + size_t szmsg; + char *msg; + +};//SMSMsg2 + +// SMS message class +class SMSMsg : public BaseMsg +{ + + +public: + + size_t mysize; + size_t szmsg; + char msg[1]; + static SMSMsg* make_sms_msg(time_t t, const char*msg, int dest) + { + size_t mlen = 0, totalsz = 0; + + SMSMsg *p = (SMSMsg *)DbstlMalloc(totalsz = (sizeof(SMSMsg) + (mlen = strlen(msg) + 4))); + memset(p, 0, totalsz); + // adding sizeof(p->to) to avoid memory alignment issues + p->mysize = sizeof(SMSMsg) + mlen; + p->when = t; + p->szmsg = mlen - 3; + p->to = dest; + p->from = 0; + strcpy(&(p->msg[0]), msg); + + return p; + } + + SMSMsg() + { + + } +protected: + SMSMsg(time_t t, const char*msg1, int dest) + { + size_t mlen = 0; + + when = t; + szmsg = strlen(msg1) + 1; + mlen = strlen(msg1); + strncpy((char*)&(this->msg[0]), msg1, mlen); + *(int*)(((char*)&(this->msg[0])) + mlen + 1) = dest; + } + +};// SMSMsg + +class RGBB +{ +public: + typedef unsigned char color_t; + + color_t r_, g_, b_, bright_; + + RGBB() + { + memset(this, 0, sizeof(RGBB));// complete 0 means invalid + } + + RGBB(color_t r, color_t g, color_t b, color_t brightness) + { + r_ = r; + g_ = g; + b_ = b; + bright_ = brightness; + } + +};// RGBB + +template <Typename T> +class separator +{ +public: + T mid; + bool operator()(const T& ele) + { + return ele < mid; + } +}; + + +class square +{ +public: + void operator()(ptint s) + { + cout<<s*s<<'\t'; + } +}; + + +class rand_str_dbt +{ +public: + static const size_t BUFLEN = 2048; + static bool init; + static char buf[BUFLEN]; + + rand_str_dbt() + { + int len = BUFLEN, i; + + if (!init) { + init = true; + + for (i = 0; i < len - 1; i++) { + buf[i] = 'a' + rand() % 26; + } + buf[i] = '\0'; + } + } + // dbt is of DB_DBT_USERMEM, mem allocated by DbstlMalloc + void operator()(Dbt&dbt, string&str, size_t shortest = 30, size_t longest = 150) + { + int rd = rand(); + + if (rd < 0) + rd = -rd; + str.clear(); + + check_expr(shortest > 0 && longest < BUFLEN); + check_expr(dbt.get_flags() & DB_DBT_USERMEM);// USER PROVIDE MEM + size_t len = (u_int32_t)(rd % longest); + if (len < shortest) + len = shortest; + else if (len >= BUFLEN) + len = BUFLEN - 1; + // start must be less than BUFLEN - len, otherwise we have no + // len bytes to offer + size_t start = rand() % (BUFLEN - len); + + char c = buf[start + len]; + + buf[start + len] = '\0'; + str = buf + start; + if (dbt.get_ulen() < (len + 1)) { + free(dbt.get_data()); + dbt.set_data(DbstlMalloc(len + 1)); + check_expr(dbt.get_data() != NULL); + } + memcpy(dbt.get_data(), (void*)(buf + start), len + 1); + dbt.set_size(u_int32_t(len + 1));// store the '\0' at the end + buf[start + len] = c; + } +}; // rand_str_dbt + +class rand_str_dbt; +struct TestParam{ + int flags, setflags, TEST_AUTOCOMMIT, dboflags, EXPLICIT_TXN; + DBTYPE dbtype; + DbEnv *dbenv; +}; + +class test_block +{ +private: + db_timespec tp; +public: + string blkname; + + void begin(const char* name) + { + + blkname = name; + cout<<endl<<"============= start of test "<< + name<<" =============="; + __os_gettime(NULL, &tp, 1); + } + void end() + { + db_timespec tp2; + __os_gettime(NULL, &tp2, 1); + + cout<<"\n============ end of test "<<blkname<<" , time spent: " + <<tp2.tv_sec - tp.tv_sec + (tp2.tv_nsec - + tp.tv_nsec) / 1000000000.0<<" secs ============="; + } +}; + +// a mobile phone SMS structure for test. will add more members in future +class sms_t +{ +public: + size_t sz; + time_t when; + int from; + int to; + char msg[512]; + + const sms_t& operator=(const sms_t&me) + { + memcpy(this, &me, sizeof(*this)); + return me; + } + + bool operator==(const sms_t& me) const + { + return memcmp(this, &me, sizeof(me)) == 0; + } + bool operator!=(const sms_t& me) + { + return memcmp(this, &me, sizeof(me)) != 0; + } +}; + +enum wt_job {wt_read, wt_insert, wt_update, wt_delete}; +enum ContainerType {ct_vector, ct_map, ct_multimap, ct_set, ct_multiset, ct_none}; + +#endif // ! _DB_STL_TEST_H__ |