Import BSDDB 4.7.25 (as of svn r89086)

This commit is contained in:
Zachary Ware
2017-09-04 13:40:25 -05:00
parent 4b29e0458f
commit 8f590873d0
4781 changed files with 2241032 additions and 6 deletions

View File

@@ -0,0 +1,6 @@
This sample application is a GUI application used to
demonstrate Berkeley DB running on Windows CE.
If you are not developing for Windows CE, this is probably not where you
want to be looking.

View File

@@ -0,0 +1,546 @@
#include "TpcbExample.h"
#define HISTORY_LEN 100
#define RECLEN 100
#define BEGID 1000000
struct Defrec {
u_int32_t id;
u_int32_t balance;
u_int8_t pad[RECLEN - sizeof(u_int32_t) - sizeof(u_int32_t)];
};
struct Histrec {
u_int32_t aid;
u_int32_t bid;
u_int32_t tid;
u_int32_t amount;
u_int8_t pad[RECLEN - 4 * sizeof(u_int32_t)];
};
const char *progname = "wce_tpcb";
TpcbExample::TpcbExample()
: dbenv(0), accounts(ACCOUNTS), branches(BRANCHES),
tellers(TELLERS), history(HISTORY), fast_mode(1), verbose(0),
cachesize(0)
{
rand_seed = GetTickCount();
setHomeDir(TESTDIR);
}
int TpcbExample::createEnv(int flags)
{
int ret;
u_int32_t local_flags;
// If the env object already exists, close and re-open
// don't just return immediately, since advanced options
// may have been altered (cachesize, NOSYNC..)
if (dbenv != NULL)
closeEnv();
srand(rand_seed);
if ((ret = db_env_create(&dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"%s: db_env_create: %s\n", progname, db_strerror(ret));
return (1);
}
dbenv->set_errcall(dbenv, &tpcb_errcallback);
dbenv->set_errpfx(dbenv, "TpcbExample");
dbenv->set_cachesize(dbenv, 0, cachesize == 0 ?
1 * 1024 * 1024 : (u_int32_t)cachesize, 0);
if (fast_mode)
dbenv->set_flags(dbenv, DB_TXN_NOSYNC, 1);
local_flags = DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG |
DB_INIT_MPOOL | DB_INIT_TXN;
dbenv->open(dbenv, homeDirName, local_flags, 0);
return (0);
}
void TpcbExample::closeEnv()
{
if (dbenv != NULL) {
dbenv->close(dbenv, 0);
dbenv = 0;
}
}
//
// Initialize the database to the specified number of accounts, branches,
// history records, and tellers.
//
int
TpcbExample::populate()
{
DB *dbp;
int err;
u_int32_t balance, idnum;
u_int32_t end_anum, end_bnum, end_tnum;
u_int32_t start_anum, start_bnum, start_tnum;
idnum = BEGID;
balance = 500000;
if ((err = db_create(&dbp, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of accounts db failed.");
return (1);
}
dbp->set_h_nelem(dbp, (unsigned int)accounts);
if ((err = dbp->open(dbp, NULL, "account", NULL, DB_HASH,
DB_CREATE, 0644)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Account file create failed. error: %s.", db_strerror(err));
return (1);
}
start_anum = idnum;
if ((err =
populateTable(dbp, idnum, balance, accounts, "account")) != 0)
return (1);
idnum += accounts;
end_anum = idnum - 1;
if ((err = dbp->close(dbp, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Account file close failed. error: %s.", db_strerror(err));
return (1);
}
if ((err = db_create(&dbp, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of branches db failed.");
return (1);
}
//
// Since the number of branches is very small, we want to use very
// small pages and only 1 key per page. This is the poor-man's way
// of getting key locking instead of page locking.
//
dbp->set_h_ffactor(dbp, 1);
dbp->set_h_nelem(dbp, (unsigned int)branches);
dbp->set_pagesize(dbp, 512);
if ((err = dbp->open(dbp, NULL, "branch", NULL, DB_HASH,
DB_CREATE, 0644)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Branch file create failed. error: %s.", db_strerror(err));
return (1);
}
start_bnum = idnum;
if ((err = populateTable(dbp, idnum, balance, branches, "branch")) != 0)
return (1);
idnum += branches;
end_bnum = idnum - 1;
if ((err = dbp->close(dbp, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Close of branch file failed. error: %s.",
db_strerror(err));
return (1);
}
if ((err = db_create(&dbp, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of teller db failed.");
return (1);
}
//
// In the case of tellers, we also want small pages, but we'll let
// the fill factor dynamically adjust itself.
//
dbp->set_h_ffactor(dbp, 0);
dbp->set_h_nelem(dbp, (unsigned int)tellers);
dbp->set_pagesize(dbp, 512);
if ((err = dbp->open(dbp, NULL, "teller", NULL, DB_HASH,
DB_CREATE, 0644)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Teller file create failed. error: %s.", db_strerror(err));
return (1);
}
start_tnum = idnum;
if ((err = populateTable(dbp, idnum, balance, tellers, "teller")) != 0)
return (1);
idnum += tellers;
end_tnum = idnum - 1;
if ((err = dbp->close(dbp, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Close of teller file failed. error: %s.",
db_strerror(err));
return (1);
}
if ((err = db_create(&dbp, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of history db failed.");
return (1);
}
dbp->set_re_len(dbp, HISTORY_LEN);
if ((err = dbp->open(dbp, NULL, "history", NULL, DB_RECNO,
DB_CREATE, 0644)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Create of history file failed. error: %s.",
db_strerror(err));
return (1);
}
populateHistory(dbp, history, accounts, branches, tellers);
if ((err = dbp->close(dbp, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Close of history file failed. error: %s.",
db_strerror(err));
return (1);
}
_snprintf(msgString, ERR_STRING_MAX, "Populated OK.");
return (0);
}
int
TpcbExample::populateTable(DB *dbp,
u_int32_t start_id, u_int32_t balance,
int nrecs, const char *msg)
{
DBT kdbt, ddbt;
Defrec drec;
memset(&drec.pad[0], 1, sizeof(drec.pad));
memset(&kdbt, 0, sizeof(kdbt));
memset(&ddbt, 0, sizeof(ddbt));
kdbt.data = &drec.id;
kdbt.size = sizeof(u_int32_t);
ddbt.data = &drec;
ddbt.size = sizeof(drec);
for (int i = 0; i < nrecs; i++) {
drec.id = start_id + (u_int32_t)i;
drec.balance = balance;
int err;
if ((err =
dbp->put(dbp, NULL, &kdbt, &ddbt, DB_NOOVERWRITE)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Failure initializing %s file: %s. Likely re-initializing.",
msg, db_strerror(err));
return (1);
}
}
return (0);
}
int
TpcbExample::populateHistory(DB *dbp, int nrecs, u_int32_t accounts,
u_int32_t branches, u_int32_t tellers)
{
DBT kdbt, ddbt;
Histrec hrec;
memset(&hrec.pad[0], 1, sizeof(hrec.pad));
hrec.amount = 10;
db_recno_t key;
memset(&kdbt, 0, sizeof(kdbt));
memset(&ddbt, 0, sizeof(ddbt));
kdbt.data = &key;
kdbt.size = sizeof(u_int32_t);
ddbt.data = &hrec;
ddbt.size = sizeof(hrec);
for (int i = 1; i <= nrecs; i++) {
hrec.aid = randomId(ACCOUNT, accounts, branches, tellers);
hrec.bid = randomId(BRANCH, accounts, branches, tellers);
hrec.tid = randomId(TELLER, accounts, branches, tellers);
int err;
key = (db_recno_t)i;
if ((err = dbp->put(dbp, NULL, &kdbt, &ddbt, DB_APPEND)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Failure initializing history file: %s.",
db_strerror(err));
return (1);
}
}
return (0);
}
int
TpcbExample::run(int n)
{
DB *adb, *bdb, *hdb, *tdb;
int failed, ret, txns;
DWORD start_time, end_time;
double elapsed_secs;
//
// Open the database files.
//
int err;
if ((err = db_create(&adb, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of account db failed. Error: %s",
db_strerror(err));
return (1);
}
if ((err = adb->open(adb, NULL, "account", NULL, DB_UNKNOWN,
DB_AUTO_COMMIT, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Open of account file failed. Error: %s", db_strerror(err));
return (1);
}
if ((err = db_create(&bdb, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of branch db failed. Error: %s",
db_strerror(err));
return (1);
}
if ((err = bdb->open(bdb, NULL, "branch", NULL, DB_UNKNOWN,
DB_AUTO_COMMIT, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Open of branch file failed. Error: %s", db_strerror(err));
return (1);
}
if ((err = db_create(&tdb, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of teller db failed. Error: %s",
db_strerror(err));
return (1);
}
if ((err = tdb->open(tdb, NULL, "teller", NULL, DB_UNKNOWN,
DB_AUTO_COMMIT, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Open of teller file failed. Error: %s", db_strerror(err));
return (1);
}
if ((err = db_create(&hdb, dbenv, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"db_create of teller db failed. Error: %s",
db_strerror(err));
return (1);
}
if ((err = hdb->open(hdb, NULL, "history", NULL, DB_UNKNOWN,
DB_AUTO_COMMIT, 0)) != 0) {
_snprintf(msgString, ERR_STRING_MAX,
"Open of history file failed. Error: %s", db_strerror(err));
return (1);
}
start_time = GetTickCount();
for (txns = n, failed = 0; n-- > 0;)
if ((ret = txn(adb, bdb, tdb, hdb,
accounts, branches, tellers)) != 0)
++failed;
end_time = GetTickCount();
if (end_time == start_time)
++end_time;
#define MILLISECS_PER_SEC 1000
elapsed_secs = (double)((end_time - start_time))/MILLISECS_PER_SEC;
_snprintf(msgString, ERR_STRING_MAX,
"%s: %d txns: %d failed, %.2f TPS\n", progname, txns, failed,
(txns - failed) / elapsed_secs);
(void)adb->close(adb, 0);
(void)bdb->close(bdb, 0);
(void)tdb->close(tdb, 0);
(void)hdb->close(hdb, 0);
return (0);
}
//
// XXX Figure out the appropriate way to pick out IDs.
//
int
TpcbExample::txn(DB *adb, DB *bdb, DB *tdb, DB *hdb,
int accounts, int branches, int tellers)
{
DBC *acurs, *bcurs, *tcurs;
DB_TXN *t;
DBT d_dbt, d_histdbt, k_dbt, k_histdbt;
db_recno_t key;
Defrec rec;
Histrec hrec;
int account, branch, teller, ret;
memset(&d_dbt, 0, sizeof(d_dbt));
memset(&d_histdbt, 0, sizeof(d_histdbt));
memset(&k_dbt, 0, sizeof(k_dbt));
memset(&k_histdbt, 0, sizeof(k_histdbt));
k_histdbt.data = &key;
k_histdbt.size = sizeof(key);
// !!!
// This is sample code -- we could move a lot of this into the driver
// to make it faster.
//
account = randomId(ACCOUNT, accounts, branches, tellers);
branch = randomId(BRANCH, accounts, branches, tellers);
teller = randomId(TELLER, accounts, branches, tellers);
k_dbt.size = sizeof(int);
d_dbt.flags |= DB_DBT_USERMEM;
d_dbt.data = &rec;
d_dbt.ulen = sizeof(rec);
hrec.aid = account;
hrec.bid = branch;
hrec.tid = teller;
hrec.amount = 10;
// Request 0 bytes since we're just positioning.
d_histdbt.flags |= DB_DBT_PARTIAL;
// START PER-TRANSACTION TIMING.
//
// Technically, TPCB requires a limit on response time, you only get
// to count transactions that complete within 2 seconds. That's not
// an issue for this sample application -- regardless, here's where
// the transaction begins.
if (dbenv->txn_begin(dbenv, NULL, &t, 0) != 0)
goto err;
if (adb->cursor(adb, t, &acurs, 0) != 0 ||
bdb->cursor(bdb, t, &bcurs, 0) != 0 ||
tdb->cursor(tdb, t, &tcurs, 0) != 0)
goto err;
// Account record
k_dbt.data = &account;
if (acurs->get(acurs, &k_dbt, &d_dbt, DB_SET) != 0)
goto err;
rec.balance += 10;
if (acurs->put(acurs, &k_dbt, &d_dbt, DB_CURRENT) != 0)
goto err;
// Branch record
k_dbt.data = &branch;
if (bcurs->get(bcurs, &k_dbt, &d_dbt, DB_SET) != 0)
goto err;
rec.balance += 10;
if (bcurs->put(bcurs, &k_dbt, &d_dbt, DB_CURRENT) != 0)
goto err;
// Teller record
k_dbt.data = &teller;
if (tcurs->get(tcurs, &k_dbt, &d_dbt, DB_SET) != 0)
goto err;
rec.balance += 10;
if (tcurs->put(tcurs, &k_dbt, &d_dbt, DB_CURRENT) != 0)
goto err;
// History record
d_histdbt.flags = 0;
d_histdbt.data = &hrec;
d_histdbt.ulen = sizeof(hrec);
if (hdb->put(hdb, t, &k_histdbt, &d_histdbt, DB_APPEND) != 0)
goto err;
if (acurs->close(acurs) != 0 || bcurs->close(bcurs) != 0
|| tcurs->close(tcurs) != 0)
goto err;
ret = t->commit(t, 0);
t = NULL;
if (ret != 0)
goto err;
// END PER-TRANSACTION TIMING.
return (0);
err:
if (acurs != NULL)
(void)acurs->close(acurs);
if (bcurs != NULL)
(void)bcurs->close(bcurs);
if (tcurs != NULL)
(void)tcurs->close(tcurs);
if (t != NULL)
(void)t->abort(t);
return (-1);
}
// Utility functions
u_int32_t
TpcbExample::randomInt(u_int32_t lo, u_int32_t hi)
{
u_int32_t ret;
int t;
t = rand();
ret = (u_int32_t)(((double)t / ((double)(RAND_MAX) + 1)) *
(hi - lo + 1));
ret += lo;
return (ret);
}
u_int32_t
TpcbExample::randomId(FTYPE type, u_int32_t accounts,
u_int32_t branches, u_int32_t tellers)
{
u_int32_t min, max, num;
max = min = BEGID;
num = accounts;
switch (type) {
case TELLER:
min += branches;
num = tellers;
// Fallthrough
case BRANCH:
if (type == BRANCH)
num = branches;
min += accounts;
// Fallthrough
case ACCOUNT:
max = min + num - 1;
}
return (randomInt(min, max));
}
char *
TpcbExample::getHomeDir(char *path, int max)
{
memcpy(path, homeDirName, min(max, MAX_PATH));
return path;
}
wchar_t *
TpcbExample::getHomeDirW(wchar_t *path, int max)
{
memcpy(path, wHomeDirName, min(max, MAX_PATH)*sizeof(wchar_t));
return path;
}
void
TpcbExample::setHomeDir(char *path)
{
int path_len;
path_len = strlen(path);
strncpy(homeDirName, path, MAX_PATH);
MultiByteToWideChar(CP_ACP, 0, path, path_len, wHomeDirName, MAX_PATH);
wHomeDirName[path_len] = L'\0';
}
void
TpcbExample::setHomeDirW(wchar_t *path)
{
int path_len;
path_len = wcslen(path);
wcsncpy(wHomeDirName, path, MAX_PATH);
WideCharToMultiByte(CP_ACP, 0, path, path_len, homeDirName,
MAX_PATH, 0, 0);
homeDirName[path_len] = '\0';
}

View File

@@ -0,0 +1,63 @@
#ifndef _TPCBEXAMPLE_H_INCLUDE__
#define _TPCBEXAMPLE_H_INCLUDE__
#include <windows.h>
#include "db.h"
#define ACCOUNTS 1000
#define BRANCHES 10
#define TELLERS 100
#define HISTORY 10000
#define TRANSACTIONS 1000
#define TESTDIR "TESTDIR"
typedef enum { ACCOUNT, BRANCH, TELLER } FTYPE;
extern "C" {
void tpcb_errcallback(const DB_ENV *, const char *, const char *);
}
class TpcbExample
{
public:
int createEnv(int);
void closeEnv();
int populate();
int run(int);
int txn(DB *, DB *, DB *, DB *, int, int, int);
int populateHistory(DB *, int, u_int32_t, u_int32_t, u_int32_t);
int populateTable(DB *, u_int32_t, u_int32_t, int, const char *);
TpcbExample();
char *getHomeDir(char *, int);
wchar_t *getHomeDirW(wchar_t *, int);
void setHomeDir(char *);
void setHomeDirW(wchar_t *);
#define ERR_STRING_MAX 1024
char msgString[ERR_STRING_MAX];
int accounts;
int branches;
int history;
int tellers;
// options configured through the advanced dialog.
int fast_mode;
int verbose;
int cachesize;
int rand_seed;
private:
DB_ENV *dbenv;
char homeDirName[MAX_PATH];
wchar_t wHomeDirName[MAX_PATH];
u_int32_t randomId(FTYPE, u_int32_t, u_int32_t, u_int32_t);
u_int32_t randomInt(u_int32_t, u_int32_t);
// no need for copy and assignment
TpcbExample(const TpcbExample &);
void operator = (const TpcbExample &);
};
#endif

View File

@@ -0,0 +1,478 @@
// TpcbUI.cpp : Defines the entry point for the application.
//
#include <windows.h>
#include "resource.h"
#include "TpcbExample.h"
#include <commctrl.h>
#define MAX_LOADSTRING 100
// Global Variables:
HINSTANCE hInst; // The current instance
HWND hWndDlgMain; // Handle to the main dialog window.
HWND hWndFrame; // Handle to the main window.
TpcbExample *tpcb;
// Forward declarations of functions included in this code module:
ATOM MyRegisterClass (HINSTANCE, LPTSTR);
BOOL InitInstance (HINSTANCE, int);
LRESULT CALLBACK WndProc (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK MainDialog (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK InitDialog (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK AdvancedDialog (HWND, UINT, WPARAM, LPARAM);
LRESULT CALLBACK RunDialog (HWND, UINT, WPARAM, LPARAM);
BOOL GetHomeDirectory(HWND, BOOL);
BOOL RecursiveDirRemove(wchar_t *);
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
MSG msg;
HACCEL hAccelTable;
hWndDlgMain = NULL;
// Initialize the tpcb object.
tpcb = new TpcbExample();
// Perform application initialization:
if (!InitInstance (hInstance, nCmdShow))
{
return FALSE;
}
hAccelTable = LoadAccelerators(hInstance, (LPCTSTR)IDC_WCE_TPCB);
// Main message loop:
while (GetMessage(&msg, NULL, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return msg.wParam;
}
//
// FUNCTION: MyRegisterClass()
//
// PURPOSE: Registers the window class.
//
// COMMENTS:
//
// It is important to call this function so that the application
// will get 'well formed' small icons associated with it.
//
ATOM MyRegisterClass(HINSTANCE hInstance, LPTSTR szWindowClass)
{
WNDCLASS wc;
wc.style = CS_HREDRAW | CS_VREDRAW;
wc.lpfnWndProc = (WNDPROC) WndProc;
wc.cbClsExtra = 0;
wc.cbWndExtra = 0;
wc.hInstance = hInstance;
wc.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_WCE_TPCB));
wc.hCursor = 0;
wc.hbrBackground = (HBRUSH) GetStockObject(WHITE_BRUSH);
wc.lpszMenuName = 0;
wc.lpszClassName = szWindowClass;
return RegisterClass(&wc);
}
//
// FUNCTION: InitInstance(HANDLE, int)
//
// PURPOSE: Saves instance handle and creates main window
//
// COMMENTS:
//
// In this function, we save the instance handle in a global variable and
// create and display the main program window.
//
BOOL InitInstance(HINSTANCE hInstance, int nCmdShow)
{
TCHAR szTitle[MAX_LOADSTRING]; // The title bar text
TCHAR szWindowClass[MAX_LOADSTRING]; // The window class name
hInst = hInstance; // Store instance handle in our global variable
// Initialize global strings
LoadString(hInstance, IDC_WCE_TPCB, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance, szWindowClass);
LoadString(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
hWndFrame = CreateWindow(szWindowClass, szTitle,
WS_VISIBLE | WS_MINIMIZEBOX, CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT, NULL, NULL, hInstance, NULL);
if (!hWndFrame)
{
return FALSE;
}
ShowWindow(hWndDlgMain, nCmdShow);
UpdateWindow(hWndDlgMain);
return TRUE;
}
//
// FUNCTION: WndProc(HWND, unsigned, WORD, LONG)
//
// PURPOSE: Processes messages for the main window.
//
// WM_COMMAND - process the application menu
// WM_DESTROY - post a quit message and return
//
//
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
HWND hDlg;
switch (message)
{
case WM_COMMAND:
DefWindowProc(hWnd, message, wParam, lParam);
break;
case WM_CREATE:
hDlg = CreateDialog(hInst,
MAKEINTRESOURCE(IDD_MAINDIALOG), hWnd,
(DLGPROC)MainDialog);
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}
// Message handler for the Main dialog box
LRESULT CALLBACK MainDialog(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
{
RECT rt;
HWND hCurrentRadioButton;
wchar_t wdirname[MAX_PATH], msg[1024], *title;
int ret, valid, ntxns, written;
switch (message)
{
case WM_INITDIALOG:
// maximize the dialog.
GetClientRect(GetParent(hDlg), &rt);
SetWindowPos(hDlg, HWND_TOP, 0, 0, rt.right, rt.bottom,
SWP_SHOWWINDOW);
CheckRadioButton(hDlg, IDC_MEDIUM_RADIO,
IDC_SMALL_RADIO, IDC_SMALL_RADIO);
SetDlgItemText(hDlg, IDC_HOME_EDIT,
tpcb->getHomeDirW(wdirname, MAX_PATH));
SetDlgItemInt(hDlg, IDC_TXN_EDIT, 1000, 0);
SetWindowText(hDlg, L"BDB TPCB Example app");
ShowWindow(hDlg, SW_SHOWNORMAL);
return TRUE;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_INIT_BUTTON ||
LOWORD(wParam) == IDC_RUN_BUTTON ) {
hCurrentRadioButton = GetDlgItem(hDlg,
IDC_SMALL_RADIO);
if(BST_CHECKED ==
SendMessage(hCurrentRadioButton,
BM_GETCHECK, NULL, NULL)) {
tpcb->accounts = 500;
tpcb->branches = 10;
tpcb->tellers = 50;
tpcb->history = 5000;
}
hCurrentRadioButton = GetDlgItem(hDlg,
IDC_MEDIUM_RADIO);
if(BST_CHECKED ==
SendMessage(hCurrentRadioButton,
BM_GETCHECK, NULL, NULL)) {
tpcb->accounts = 1000;
tpcb->branches = 10;
tpcb->tellers = 100;
tpcb->history = 10000;
}
hCurrentRadioButton = GetDlgItem(hDlg,
IDC_LARGE_RADIO);
if(BST_CHECKED ==
SendMessage(hCurrentRadioButton,
BM_GETCHECK, NULL, NULL)) {
tpcb->accounts = 100000;
tpcb->branches = 10;
tpcb->tellers = 100;
tpcb->history = 259200;
}
EnableWindow(GetDlgItem(hDlg, IDC_INIT_BUTTON),
FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_RUN_BUTTON),
FALSE);
EnableWindow(GetDlgItem(hDlg, IDC_ADV_BUTTON),
FALSE);
}
if (LOWORD(wParam) == IDC_ADV_BUTTON) {
CreateDialog(hInst,
MAKEINTRESOURCE(IDD_ADVANCEDDIALOG), hDlg,
(DLGPROC)AdvancedDialog);
} else if (LOWORD(wParam) == IDC_INIT_BUTTON) {
// Close the environment first.
// In case this is a re-initialization.
tpcb->closeEnv();
GetHomeDirectory(hDlg, TRUE);
tpcb->createEnv(0);
ret = tpcb->populate();
} else if (LOWORD(wParam) == IDC_RUN_BUTTON) {
GetHomeDirectory(hDlg, FALSE);
if (GetFileAttributes(
tpcb->getHomeDirW(wdirname, MAX_PATH)) !=
FILE_ATTRIBUTE_DIRECTORY) {
_snwprintf(msg, 1024,
L"Target directory: %s does not exist, or is not a directory.\nMake sure the "
L"directory name is correct, and that you ran the initialization phase.",
wdirname);
MessageBox(hDlg, msg, L"Error", MB_OK);
EnableWindow(GetDlgItem(hDlg,
IDC_INIT_BUTTON), TRUE);
EnableWindow(GetDlgItem(hDlg,
IDC_RUN_BUTTON), TRUE);
EnableWindow(GetDlgItem(hDlg,
IDC_ADV_BUTTON), TRUE);
return FALSE;
}
// TODO: Check for an empty directory?
ntxns = GetDlgItemInt(hDlg, IDC_TXN_EDIT,
&valid, FALSE);
if (valid == FALSE) {
MessageBox(hDlg,
L"Invalid number in transaction field.",
L"Error", MB_OK);
EnableWindow(GetDlgItem(hDlg,
IDC_INIT_BUTTON), TRUE);
EnableWindow(GetDlgItem(hDlg,
IDC_RUN_BUTTON), TRUE);
EnableWindow(GetDlgItem(hDlg,
IDC_ADV_BUTTON), TRUE);
return FALSE;
}
tpcb->createEnv(0);
ret = tpcb->run(ntxns);
} else if (LOWORD(wParam) == IDC_EXIT_BUTTON) {
tpcb->closeEnv();
EndDialog(hDlg, LOWORD(wParam));
DestroyWindow(hDlg);
DestroyWindow(hWndFrame);
return FALSE;
}
if (LOWORD(wParam) == IDC_INIT_BUTTON ||
LOWORD(wParam) == IDC_RUN_BUTTON ) {
if (ret == 0)
title = L"Results";
else
title = L"Error message";
written = MultiByteToWideChar(CP_ACP, NULL,
tpcb->msgString, strlen(tpcb->msgString),
msg, sizeof(msg)/sizeof(msg[0]));
msg[written] = L'\0';
MessageBox(hDlg, msg, title, MB_OK);
EnableWindow(GetDlgItem(hDlg, IDC_INIT_BUTTON), TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_RUN_BUTTON),
TRUE);
EnableWindow(GetDlgItem(hDlg, IDC_ADV_BUTTON),
TRUE);
}
break;
case WM_DESTROY:
// Same functionality as WM_COMMAND->IDC_EXIT_BUTTON
tpcb->closeEnv();
EndDialog(hDlg, LOWORD(wParam));
DestroyWindow(hDlg);
DestroyWindow(hWndFrame);
return FALSE;
default:
return DefWindowProc(hDlg, message, wParam, lParam);
}
return TRUE;
}
// Message handler for the Advanced dialog box
LRESULT CALLBACK AdvancedDialog(HWND hDlg, UINT message,
WPARAM wParam, LPARAM lParam)
{
RECT rt;
HWND hCurrentCheckBox;
int currentInt, valid;
switch (message)
{
case WM_INITDIALOG:
GetClientRect(GetParent(hDlg), &rt);
SetWindowPos(hDlg, HWND_TOP, 0, 0, rt.right, rt.bottom,
SWP_SHOWWINDOW);
if (tpcb->fast_mode == 0) {
hCurrentCheckBox =
GetDlgItem(hDlg, IDC_FASTMODE_CHECK);
SendMessage(hCurrentCheckBox, BM_SETCHECK,
BST_CHECKED, 0);
}
if (tpcb->verbose == 1) {
hCurrentCheckBox =
GetDlgItem(hDlg, IDC_VERBOSE_CHECK);
SendMessage(hCurrentCheckBox, BM_SETCHECK,
BST_CHECKED, 0);
}
if (tpcb->cachesize != 0) {
SetDlgItemInt(hDlg, IDC_CACHE_EDIT,
tpcb->cachesize/1024, FALSE);
}
break;
case WM_COMMAND:
if (LOWORD(wParam) == IDC_DONE_BUTTON) {
hCurrentCheckBox =
GetDlgItem(hDlg, IDC_FASTMODE_CHECK);
if(BST_CHECKED == SendMessage(hCurrentCheckBox,
BM_GETCHECK, NULL, NULL))
tpcb->fast_mode = 0;
else
tpcb->fast_mode = 1;
hCurrentCheckBox =
GetDlgItem(hDlg, IDC_VERBOSE_CHECK);
if(BST_CHECKED == SendMessage(hCurrentCheckBox,
BM_GETCHECK, NULL, NULL))
tpcb->verbose = 1;
else
tpcb->verbose = 0;
currentInt = GetDlgItemInt(hDlg,
IDC_RANDOM_EDIT, &valid, FALSE);
if (valid != FALSE)
tpcb->rand_seed = currentInt;
currentInt = GetDlgItemInt(hDlg,
IDC_CACHE_EDIT, &valid, FALSE);
if (valid != FALSE) {
if (currentInt < 20) {
MessageBox(hDlg,
L"Min cache size is 20kb.",
L"Error", MB_OK);
return FALSE;
}
tpcb->cachesize = currentInt*1024;
}
EndDialog(hDlg, LOWORD(wParam));
DestroyWindow(hDlg);
}
break;
default:
return DefWindowProc(hDlg, message, wParam, lParam);
}
return TRUE;
}
// Utility function to retrieve the directory name
// from the control, and set it in the tpcb object.
// Optionally remove and create requested directory.
BOOL
GetHomeDirectory(HWND hDlg, BOOL init)
{
wchar_t wdirname[MAX_PATH];
DWORD attrs;
if (GetDlgItemText(hDlg, IDC_HOME_EDIT, wdirname, MAX_PATH) == 0)
tpcb->setHomeDir(TESTDIR);
else
tpcb->setHomeDirW(wdirname);
if (init == TRUE) {
// Ensure that wdirname holds the correct version:
tpcb->getHomeDirW(wdirname, MAX_PATH);
// If the directory exists, ensure that it is empty.
attrs = GetFileAttributes(wdirname);
if (attrs == FILE_ATTRIBUTE_DIRECTORY)
RecursiveDirRemove(wdirname);
else if (attrs == FILE_ATTRIBUTE_NORMAL)
DeleteFile(wdirname);
else if (attrs != 0xFFFFFFFF) {
// Not a directory or normal file, don't try to remove
// it, or create a new directory over the top.
return FALSE;
}
// Create the requested directory.
return CreateDirectory(wdirname, NULL);
}
return TRUE;
}
BOOL
RecursiveDirRemove(wchar_t *dirname)
{
HANDLE hFind; // file handle
WIN32_FIND_DATA findFileData;
wchar_t DirPath[MAX_PATH];
wchar_t FileName[MAX_PATH];
wcscpy(DirPath, dirname);
wcscat(DirPath, L"\\*"); // searching all files
wcscpy(FileName, dirname);
wcscat(FileName, L"\\");
MessageBox(hWndDlgMain, L"Cleaning directory.", L"Message", MB_OK);
// find the first file
if ((hFind = FindFirstFile(DirPath,&findFileData)) ==
INVALID_HANDLE_VALUE)
return FALSE;
wcscpy(DirPath,FileName);
MessageBox(hWndDlgMain, L"Found files in directory.",
L"Message", MB_OK);
bool bSearch = true;
do {
wcscpy(FileName + wcslen(DirPath), findFileData.cFileName);
if (findFileData.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY)
{
// we have found a directory, recurse
if (!RecursiveDirRemove(FileName))
break; // directory couldn't be deleted
} else {
if (findFileData.dwFileAttributes &
FILE_ATTRIBUTE_READONLY)
SetFileAttributes(findFileData.cFileName,
FILE_ATTRIBUTE_NORMAL);
if (!DeleteFile(FileName)) {
MessageBox(hWndDlgMain, L"Delete failed.",
L"Message", MB_OK);
break; // file couldn't be deleted
}
}
} while (FindNextFile(hFind,&findFileData));
FindClose(hFind); // closing file handle
return RemoveDirectory(dirname); // remove the empty directory
}
// Callback function used to receive error messages from DB
// Needs to have a C calling convention.
// Using this function, since the implementation is presenting
// the error to the user in a message box.
extern "C" {
void tpcb_errcallback(const DB_ENV *, const char *errpfx, const char *errstr)
{
wchar_t wstr[ERR_STRING_MAX];
memset(wstr, 0, sizeof(wstr));
MultiByteToWideChar(CP_ACP, 0, errstr, strlen(errstr),
wstr, ERR_STRING_MAX-1);
MessageBox(hWndDlgMain, wstr, L"Error Message", MB_OK);
exit(1);
}
}

View File

@@ -0,0 +1,38 @@
#ifndef __NEWRES_H__
#define __NEWRES_H__
#if !defined(UNDER_CE)
#define UNDER_CE _WIN32_WCE
#endif
#if defined(_WIN32_WCE)
#if !defined(WCEOLE_ENABLE_DIALOGEX)
#define DIALOGEX DIALOG DISCARDABLE
#endif
#include <commctrl.h>
#define SHMENUBAR RCDATA
#if defined(WIN32_PLATFORM_PSPC) && (_WIN32_WCE >= 300)
#include <aygshell.h>
#else
#define I_IMAGENONE (-2)
#define NOMENU 0xFFFF
#define IDS_SHNEW 1
#define IDM_SHAREDNEW 10
#define IDM_SHAREDNEWDEFAULT 11
#endif
#endif // _WIN32_WCE
#ifdef RC_INVOKED
#ifndef _INC_WINDOWS
#define _INC_WINDOWS
#include "winuser.h" // extract from windows header
#endif
#endif
#ifdef IDC_STATIC
#undef IDC_STATIC
#endif
#define IDC_STATIC (-1)
#endif //__NEWRES_H__

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.1 KiB

View File

@@ -0,0 +1,57 @@
//{{NO_DEPENDENCIES}}
// Microsoft eMbedded Visual C++ generated include file.
// Used by wce_tpcb.rc
//
#define IDS_APP_TITLE 1
#define IDS_HELLO 2
#define IDC_WCE_TPCB 3
#define IDI_WCE_TPCB 101
#define IDM_MENU 102
#define IDD_ABOUTBOX 103
#define IDD_MAINDIALOG 104
#define IDD_INITDIALOG 106
#define IDD_ADVANCEDIALOG 107
#define IDD_ADVANCEDDIALOG 107
#define IDD_RUNDIALOG 108
#define IDB_ORACLE_BITMAP 113
#define IDEXIT 1001
#define IDC_DIRENTRY 1002
#define IDC_HOMEDIR 1003
#define IDC_INITIALIZE 1004
#define IDC_RUN 1005
#define IDC_TXN_EDIT 1006
#define IDC_HISTORY_EDIT 1007
#define IDC_TELLER_EDIT 1008
#define IDC_ACCT_EDIT 1009
#define IDC_BRANCH_EDIT 1010
#define IDC_INITHOME 1011
#define IDC_HOME_EDIT 1020
#define IDC_FASTMODE_CHECK 1023
#define IDC_VERBOSE_CHECK 1024
#define IDC_RANDOM_STATIC 1025
#define IDC_RANDOM_EDIT 1026
#define IDC_CACHE_STATIC 1027
#define IDC_CACHE_EDIT 1028
#define IDC_DONE_BUTTON 1029
#define IDC_TXNS_STATIC 1030
#define IDC_TXNS_EDIT 1031
#define IDC_RUN_BUTTON 1032
#define IDC_INIT_BUTTON 1033
#define IDC_ADV_BUTTON 1034
#define IDC_EXIT_BUTTON 1037
#define IDC_MEDIUM_RADIO 1041
#define IDC_LARGE_RADIO 1042
#define IDC_SMALL_RADIO 1043
#define IDM_FILE_EXIT 40002
#define IDM_HELP_ABOUT 40003
// Next default values for new objects
//
#ifdef APSTUDIO_INVOKED
#ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 114
#define _APS_NEXT_COMMAND_VALUE 40004
#define _APS_NEXT_CONTROL_VALUE 1049
#define _APS_NEXT_SYMED_VALUE 101
#endif
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.1 KiB

View File

@@ -0,0 +1,176 @@
//Microsoft eMbedded Visual C++ generated resource script.
//
#include "resource.h"
#define APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 2 resource.
//
#include "newres.h"
/////////////////////////////////////////////////////////////////////////////
#undef APSTUDIO_READONLY_SYMBOLS
/////////////////////////////////////////////////////////////////////////////
// English (U.S.) resources
#if !defined(AFX_RESOURCE_DLL) || defined(AFX_TARG_ENU)
#ifdef _WIN32
LANGUAGE LANG_ENGLISH, SUBLANG_ENGLISH_US
#pragma code_page(1252)
#endif //_WIN32
/////////////////////////////////////////////////////////////////////////////
//
// Icon
//
// Icon with lowest ID value placed first to ensure application icon
// remains consistent on all systems.
IDI_WCE_TPCB ICON DISCARDABLE "wce_tpcb.ICO"
#ifdef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// TEXTINCLUDE
//
1 TEXTINCLUDE DISCARDABLE
BEGIN
"resource.h\0"
END
2 TEXTINCLUDE DISCARDABLE
BEGIN
"#include ""newres.h""\r\n"
"\0"
END
3 TEXTINCLUDE DISCARDABLE
BEGIN
"\r\n"
"\0"
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Dialog
//
IDD_MAINDIALOG DIALOG DISCARDABLE 0, 0, 138, 182
STYLE DS_MODALFRAME | WS_CAPTION | WS_SYSMENU
CAPTION "Berkeley DB TPCB"
FONT 8, "System"
BEGIN
PUSHBUTTON "Initialize",IDC_INIT_BUTTON,8,77,50,14
PUSHBUTTON "Advanced...",IDC_ADV_BUTTON,78,76,50,14
PUSHBUTTON "Run...",IDC_RUN_BUTTON,77,94,50,14
CONTROL "Medium",IDC_MEDIUM_RADIO,"Button",BS_AUTORADIOBUTTON,51,
45,40,10
CONTROL "Large",IDC_LARGE_RADIO,"Button",BS_AUTORADIOBUTTON,95,
45,32,10
CONTROL "Small",IDC_SMALL_RADIO,"Button",BS_AUTORADIOBUTTON,14,
45,32,10
LTEXT "Home Dir:",IDC_STATIC,7,62,32,8
EDITTEXT IDC_HOME_EDIT,39,59,89,14,ES_AUTOHSCROLL
GROUPBOX "Benchmark data volume",IDC_STATIC,7,35,123,22
LTEXT "# txns:",IDC_STATIC,8,96,25,8
EDITTEXT IDC_TXN_EDIT,33,94,40,14,ES_AUTOHSCROLL
GROUPBOX "",IDC_STATIC,7,88,123,23
PUSHBUTTON "Exit",IDC_EXIT_BUTTON,43,115,50,14
CONTROL 113,IDC_STATIC,"Static",SS_BITMAP,40,7,15,13
END
IDD_ADVANCEDDIALOG DIALOG DISCARDABLE 0, 0, 147, 162
STYLE DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "Advanced options"
FONT 8, "System"
BEGIN
CONTROL "Disable fast mode",IDC_FASTMODE_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,14,73,10
CONTROL "Enable verbose mode",IDC_VERBOSE_CHECK,"Button",
BS_AUTOCHECKBOX | WS_TABSTOP,7,27,85,10
LTEXT "Random seed:",IDC_RANDOM_STATIC,7,44,47,8
EDITTEXT IDC_RANDOM_EDIT,59,42,40,14,ES_AUTOHSCROLL
LTEXT "Cache size (kb):",IDC_CACHE_STATIC,7,67,52,8
EDITTEXT IDC_CACHE_EDIT,59,64,40,14,ES_AUTOHSCROLL
PUSHBUTTON "Done",IDC_DONE_BUTTON,7,90,50,14
END
/////////////////////////////////////////////////////////////////////////////
//
// DESIGNINFO
//
#ifdef APSTUDIO_INVOKED
GUIDELINES DESIGNINFO DISCARDABLE
BEGIN
IDD_MAINDIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 130
TOPMARGIN, 7
BOTTOMMARGIN, 175
END
IDD_ADVANCEDDIALOG, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 140
TOPMARGIN, 7
BOTTOMMARGIN, 155
END
END
#endif // APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Accelerator
//
IDC_WCE_TPCB ACCELERATORS DISCARDABLE
BEGIN
"/", IDM_HELP_ABOUT, ASCII, ALT, NOINVERT
VK_F4, IDM_FILE_EXIT, VIRTKEY, ALT, NOINVERT
END
/////////////////////////////////////////////////////////////////////////////
//
// Bitmap
//
IDB_ORACLE_BITMAP BITMAP DISCARDABLE "oracle_bdb.bmp"
/////////////////////////////////////////////////////////////////////////////
//
// String Table
//
STRINGTABLE DISCARDABLE
BEGIN
IDS_APP_TITLE "wce_tpcb"
IDC_WCE_TPCB "WCE_TPCB"
END
#endif // English (U.S.) resources
/////////////////////////////////////////////////////////////////////////////
#ifndef APSTUDIO_INVOKED
/////////////////////////////////////////////////////////////////////////////
//
// Generated from the TEXTINCLUDE 3 resource.
//
/////////////////////////////////////////////////////////////////////////////
#endif // not APSTUDIO_INVOKED