summaryrefslogtreecommitdiff
path: root/examples/c
diff options
context:
space:
mode:
authorLorry Tar Creator <lorry-tar-importer@baserock.org>2015-02-17 17:25:57 +0000
committer <>2015-03-17 16:26:24 +0000
commit780b92ada9afcf1d58085a83a0b9e6bc982203d1 (patch)
tree598f8b9fa431b228d29897e798de4ac0c1d3d970 /examples/c
parent7a2660ba9cc2dc03a69ddfcfd95369395cc87444 (diff)
downloadberkeleydb-master.tar.gz
Imported from /home/lorry/working-area/delta_berkeleydb/db-6.1.23.tar.gz.HEADdb-6.1.23master
Diffstat (limited to 'examples/c')
-rw-r--r--examples/c/csv/DbRecord.c2
-rw-r--r--examples/c/csv/README2
-rw-r--r--examples/c/csv/code.c13
-rw-r--r--examples/c/csv/csv.h2
-rw-r--r--examples/c/csv/csv_extern.h8
-rw-r--r--examples/c/csv/db.c12
-rw-r--r--examples/c/csv/load.c2
-rw-r--r--examples/c/csv/load_main.c18
-rw-r--r--examples/c/csv/query.c2
-rw-r--r--examples/c/csv/query_main.c2
-rw-r--r--examples/c/csv/util.c14
-rw-r--r--examples/c/ex_access.c2
-rw-r--r--examples/c/ex_apprec/ex_apprec.c2
-rw-r--r--examples/c/ex_apprec/ex_apprec.h2
-rw-r--r--examples/c/ex_apprec/ex_apprec.src2
-rw-r--r--examples/c/ex_apprec/ex_apprec_rec.c2
-rw-r--r--examples/c/ex_blob.c286
-rw-r--r--examples/c/ex_btrec.c2
-rw-r--r--examples/c/ex_bulk.c328
-rw-r--r--examples/c/ex_env.c28
-rw-r--r--examples/c/ex_heap.c10
-rw-r--r--examples/c/ex_lock.c2
-rw-r--r--examples/c/ex_mpool.c2
-rw-r--r--examples/c/ex_rep/base/rep_base.c4
-rw-r--r--examples/c/ex_rep/base/rep_base.h7
-rw-r--r--examples/c/ex_rep/base/rep_msg.c66
-rw-r--r--examples/c/ex_rep/base/rep_net.c52
-rw-r--r--examples/c/ex_rep/common/rep_common.c76
-rw-r--r--examples/c/ex_rep/common/rep_common.h30
-rw-r--r--examples/c/ex_rep/mgr/rep_mgr.c19
-rw-r--r--examples/c/ex_rep_chan/rep_chan.c2
-rw-r--r--examples/c/ex_rep_chan/rep_chan.h2
-rw-r--r--examples/c/ex_rep_chan/rep_chan_util.c14
-rw-r--r--examples/c/ex_rep_gsg/rep_mgr_gsg.c2
-rw-r--r--examples/c/ex_rep_gsg/simple_txn.c2
-rw-r--r--examples/c/ex_sequence.c2
-rw-r--r--examples/c/ex_stream.c2
-rw-r--r--examples/c/ex_thread.c2
-rw-r--r--examples/c/ex_tpcb.c2
-rw-r--r--examples/c/getting_started/example_database_load.c32
-rw-r--r--examples/c/getting_started/example_database_read.c17
-rw-r--r--examples/c/getting_started/gettingstarted_common.c12
-rw-r--r--examples/c/getting_started/gettingstarted_common.h4
-rw-r--r--examples/c/txn_guide/txn_guide.c2
-rw-r--r--examples/c/txn_guide/txn_guide_inmemory.c2
45 files changed, 851 insertions, 247 deletions
diff --git a/examples/c/csv/DbRecord.c b/examples/c/csv/DbRecord.c
index b25aeadc..d3c975b4 100644
--- a/examples/c/csv/DbRecord.c
+++ b/examples/c/csv/DbRecord.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/csv/README b/examples/c/csv/README
index 6d5eb878..1da48a36 100644
--- a/examples/c/csv/README
+++ b/examples/c/csv/README
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/csv/code.c b/examples/c/csv/code.c
index 24aaac81..85c6c792 100644
--- a/examples/c/csv/code.c
+++ b/examples/c/csv/code.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -26,7 +26,8 @@ int usage(void);
* Globals
*/
FILE *cfp; /* C source file */
-FILE *hfp; /* C source file */
+FILE *ffp; /* CSV file */
+FILE *hfp; /* C header file */
char *progname; /* Program name */
int verbose; /* Verbose flag */
@@ -45,6 +46,8 @@ main(int argc, char *argv[])
else
++progname;
+ ffp = NULL;
+
/* Initialize arguments. */
cfile = "csv_local.c"; /* Default header/source files */
hfile = "csv_local.h";
@@ -55,8 +58,8 @@ main(int argc, char *argv[])
case 'c':
cfile = optarg;
break;
- case 'f':
- if (freopen(optarg, "r", stdin) == NULL) {
+ case 'f': /* Required argument */
+ if ((ffp = freopen(optarg, "r", stdin)) == NULL) {
fprintf(stderr,
"%s: %s\n", optarg, strerror(errno));
return (EXIT_FAILURE);
@@ -75,7 +78,7 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- if (*argv != NULL)
+ if (*argv != NULL || ffp == NULL)
return (usage());
/* Load records from the input file. */
diff --git a/examples/c/csv/csv.h b/examples/c/csv/csv.h
index ac9fac2a..beb67cbc 100644
--- a/examples/c/csv/csv.h
+++ b/examples/c/csv/csv.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/csv/csv_extern.h b/examples/c/csv/csv_extern.h
index a541bb5c..59b468f0 100644
--- a/examples/c/csv/csv_extern.h
+++ b/examples/c/csv/csv_extern.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -17,9 +17,9 @@ extern void DbRecord_print(DbRecord *, FILE *);
extern int DbRecord_read(u_long, DbRecord *);
extern int DbRecord_search_field_name(char *, char *, OPERATOR);
extern int DbRecord_search_field_number(u_int, char *, OPERATOR);
-extern int compare_double(DB *, const DBT *, const DBT *);
-extern int compare_string(DB *, const DBT *, const DBT *);
-extern int compare_ulong(DB *, const DBT *, const DBT *);
+extern int compare_double(DB *, const DBT *, const DBT *, size_t *);
+extern int compare_string(DB *, const DBT *, const DBT *, size_t *);
+extern int compare_ulong(DB *, const DBT *, const DBT *, size_t *);
extern int csv_env_close(void);
extern int csv_env_open(const char *, int);
extern int csv_secondary_close(void);
diff --git a/examples/c/csv/db.c b/examples/c/csv/db.c
index dc72f0d8..e138d5b8 100644
--- a/examples/c/csv/db.c
+++ b/examples/c/csv/db.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -10,7 +10,7 @@
#include "csv_local.h"
#include "csv_extern.h"
-static int compare_uint32(DB *, const DBT *, const DBT *);
+static int compare_uint32(DB *, const DBT *, const DBT *, size_t *);
/*
* csv_env_init --
@@ -138,7 +138,7 @@ csv_secondary_open()
{
DB *sdb;
DbField *f;
- int ret, (*fcmp)(DB *, const DBT *, const DBT *);
+ int ret, (*fcmp)(DB *, const DBT *, const DBT *, size_t *);
/*
* Create secondary database handles.
@@ -232,11 +232,13 @@ csv_secondary_close()
* Compare two keys.
*/
static int
-compare_uint32(DB *db_arg, const DBT *a_arg, const DBT *b_arg)
+compare_uint32(DB *db_arg, const DBT *a_arg, const DBT *b_arg, size_t *locp)
{
u_int32_t a, b;
- db_arg = db_arg; /* Quiet compiler. */
+ /* Quiet compiler. */
+ db_arg = db_arg;
+ locp = NULL;
memcpy(&a, a_arg->data, sizeof(u_int32_t));
memcpy(&b, b_arg->data, sizeof(u_int32_t));
diff --git a/examples/c/csv/load.c b/examples/c/csv/load.c
index 74fadfe0..708fd0ea 100644
--- a/examples/c/csv/load.c
+++ b/examples/c/csv/load.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/csv/load_main.c b/examples/c/csv/load_main.c
index 1caeda00..5e42e406 100644
--- a/examples/c/csv/load_main.c
+++ b/examples/c/csv/load_main.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -15,11 +15,12 @@ static int usage(void);
/*
* Globals
*/
-DB_ENV *dbenv; /* Database environment */
-DB *db; /* Primary database */
+DB_ENV *dbenv; /* Database environment */
+DB *db; /* Primary database */
DB **secondary; /* Secondaries */
-int verbose; /* Program verbosity */
-char *progname; /* Program name */
+int verbose; /* Program verbosity */
+char *progname; /* Program name */
+FILE *ffp; /* CSV file */
int
main(int argc, char *argv[])
@@ -37,6 +38,7 @@ main(int argc, char *argv[])
else
++progname;
verbose = 0;
+ ffp = NULL;
/* Initialize arguments. */
home = NULL;
@@ -46,8 +48,8 @@ main(int argc, char *argv[])
/* Process arguments. */
while ((ch = getopt(argc, argv, "F:f:h:V:v")) != EOF)
switch (ch) {
- case 'f':
- if (freopen(optarg, "r", stdin) == NULL) {
+ case 'f': /* Required argument */
+ if ((ffp = freopen(optarg, "r", stdin)) == NULL) {
fprintf(stderr,
"%s: %s\n", optarg, db_strerror(errno));
return (EXIT_FAILURE);
@@ -76,7 +78,7 @@ main(int argc, char *argv[])
argc -= optind;
argv += optind;
- if (*argv != NULL)
+ if (*argv != NULL || ffp == NULL)
return (usage());
/*
diff --git a/examples/c/csv/query.c b/examples/c/csv/query.c
index f41dc560..e2c4e223 100644
--- a/examples/c/csv/query.c
+++ b/examples/c/csv/query.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/csv/query_main.c b/examples/c/csv/query_main.c
index ed22283e..eb156367 100644
--- a/examples/c/csv/query_main.c
+++ b/examples/c/csv/query_main.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/csv/util.c b/examples/c/csv/util.c
index c8cfa6c0..bcc280cc 100644
--- a/examples/c/csv/util.c
+++ b/examples/c/csv/util.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -156,11 +156,13 @@ secondary_callback(DB *db_arg, const DBT *key, const DBT *data, DBT *result)
* Compare two keys.
*/
int
-compare_double(DB *db_arg, const DBT *a_arg, const DBT *b_arg)
+compare_double(DB *db_arg, const DBT *a_arg, const DBT *b_arg, size_t *locp)
{
double a, b;
- db_arg = db_arg; /* Quiet compiler. */
+ /* Quiet compiler. */
+ db_arg = db_arg;
+ locp = NULL;
memcpy(&a, a_arg->data, sizeof(double));
memcpy(&b, b_arg->data, sizeof(double));
@@ -172,11 +174,13 @@ compare_double(DB *db_arg, const DBT *a_arg, const DBT *b_arg)
* Compare two keys.
*/
int
-compare_ulong(DB *db_arg, const DBT *a_arg, const DBT *b_arg)
+compare_ulong(DB *db_arg, const DBT *a_arg, const DBT *b_arg, size_t *locp)
{
u_long a, b;
- db_arg = db_arg; /* Quiet compiler. */
+ /* Quiet compiler. */
+ db_arg = db_arg;
+ locp = NULL;
memcpy(&a, a_arg->data, sizeof(u_long));
memcpy(&b, b_arg->data, sizeof(u_long));
diff --git a/examples/c/ex_access.c b/examples/c/ex_access.c
index 67d248fe..8f3b5896 100644
--- a/examples/c/ex_access.c
+++ b/examples/c/ex_access.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_apprec/ex_apprec.c b/examples/c/ex_apprec/ex_apprec.c
index 0c19341f..81089355 100644
--- a/examples/c/ex_apprec/ex_apprec.c
+++ b/examples/c/ex_apprec/ex_apprec.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_apprec/ex_apprec.h b/examples/c/ex_apprec/ex_apprec.h
index b7e0da03..3ac65401 100644
--- a/examples/c/ex_apprec/ex_apprec.h
+++ b/examples/c/ex_apprec/ex_apprec.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_apprec/ex_apprec.src b/examples/c/ex_apprec/ex_apprec.src
index 91618c00..6c6893d4 100644
--- a/examples/c/ex_apprec/ex_apprec.src
+++ b/examples/c/ex_apprec/ex_apprec.src
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2002, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2002, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_apprec/ex_apprec_rec.c b/examples/c/ex_apprec/ex_apprec_rec.c
index 70eab4a5..7ed786f4 100644
--- a/examples/c/ex_apprec/ex_apprec_rec.c
+++ b/examples/c/ex_apprec/ex_apprec_rec.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_blob.c b/examples/c/ex_blob.c
new file mode 100644
index 00000000..1c074f7a
--- /dev/null
+++ b/examples/c/ex_blob.c
@@ -0,0 +1,286 @@
+/*-
+ * See the file LICENSE for redistribution information.
+ *
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
+ *
+ * $Id$
+ */
+
+#include <sys/types.h>
+
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#define CMD_LEN 25
+#ifdef _WIN32
+extern int getopt(int, char * const *, const char *);
+#else
+#include <unistd.h>
+#endif
+
+#include <db.h>
+
+int db_setup __P((const char *, FILE *, const char *));
+int db_teardown __P((const char *, FILE *, const char *));
+static int usage __P((void));
+
+const char *progname = "ex_blob"; /* Program name. */
+
+/*
+ * An example of a program that stores data items in Berkeley DB blob
+ * files.
+ */
+int
+main(argc, argv)
+ int argc;
+ char *argv[];
+{
+ extern char *optarg;
+ extern int optind;
+ char *cmd;
+ const char *home;
+
+ int ch;
+ home = "EX_BLOBDIR";
+ while ((ch = getopt(argc, argv, "h:")) != EOF)
+ switch (ch) {
+ case 'h':
+ home = optarg;
+ break;
+ case '?':
+ default:
+ return (usage());
+ }
+ argc -= optind;
+ argv += optind;
+
+ if (argc != 0)
+ return (usage());
+
+ if ((cmd = malloc(strlen(home) + CMD_LEN)) == NULL)
+ return (EXIT_FAILURE);
+
+#ifdef _WIN32
+ sprintf(cmd, "rmdir %s /q/s", home);
+#else
+ sprintf(cmd, "rm -rf %s", home);
+#endif
+ system(cmd);
+ sprintf(cmd, "mkdir %s", home);
+ system(cmd);
+ free(cmd);
+
+ printf("Setup env\n");
+ if (db_setup(home, stderr, progname) != 0)
+ return (EXIT_FAILURE);
+
+ return (EXIT_SUCCESS);
+}
+
+int
+db_setup(home, errfp, progname)
+ const char *home, *progname;
+ FILE *errfp;
+{
+ DBC *dbc;
+ DB_ENV *dbenv;
+ DB *dbp;
+ DB_STREAM *dbs;
+ DB_TXN *txn;
+ DBT data, key;
+ int ret;
+ db_off_t size;
+ unsigned int i;
+
+ dbc = NULL;
+ dbenv = NULL;
+ dbp = NULL;
+ dbs = NULL;
+ txn = NULL;
+ memset (&data, 0, sizeof(DBT));
+
+ /*
+ * Create an environment object and initialize it for error
+ * reporting.
+ */
+ if ((ret = db_env_create(&dbenv, 0)) != 0) {
+ fprintf(errfp, "%s: %s\n", progname, db_strerror(ret));
+ return (1);
+ }
+ dbenv->set_errfile(dbenv, errfp);
+ dbenv->set_errpfx(dbenv, progname);
+
+ /*
+ * We want to specify the shared memory buffer pool cachesize.
+ */
+ if ((ret = dbenv->set_cachesize(dbenv, 0, 64 * 1024 *1024, 0)) != 0) {
+ dbenv->err(dbenv, ret, "set_cachesize");
+ goto err;
+ }
+
+ /* Enable blob files and set the size threshold. */
+ if ((ret = dbenv->set_blob_threshold(dbenv, 1000, 0)) != 0) {
+ dbenv->err(dbenv, ret, "set_blob_threshold");
+ goto err;
+ }
+
+ /* Open the environment with full transactional support. */
+ if ((ret = dbenv->open(dbenv, home,
+ DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL |
+ DB_INIT_TXN, 0644)) != 0) {
+ dbenv->err(dbenv, ret, "environment open: %s", home);
+ goto err;
+ }
+
+ /* Open a database in the environment. */
+ if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+ dbenv->err(dbenv, ret, "database create");
+ goto err;
+ }
+
+ /* Open a database with btree access method. */
+ if ((ret = dbp->open(dbp, NULL, "exblob_db1.db", NULL,
+ DB_BTREE, DB_CREATE|DB_AUTO_COMMIT,0644)) != 0) {
+ dbenv->err(dbenv, ret, "database open");
+ goto err;
+ }
+
+ /* Insert an item that will overflow. */
+ memset(&key, 0, sizeof(DBT));
+ memset(&data, 0, sizeof(DBT));
+ key.ulen = key.size = sizeof(int);
+ key.flags = DB_DBT_USERMEM;
+
+ data.size = data.ulen = 4000;
+ data.data = malloc(data.size);
+ for (i = 0; i < data.size; i++)
+ ((char *)data.data)[i] = 'a' + (i % 26);
+ data.flags = DB_DBT_USERMEM;
+
+#define COUNT 5000
+ for (i = 1; i < COUNT; i++) {
+ key.data = &i;
+ /* Use a mixture of blob and onpage items. */
+ if (i%23 == 0)
+ data.size = 20;
+ if ((ret = dbp->put(dbp, NULL, &key, &data, 0)) != 0) {
+ dbenv->err(dbenv, ret, "blob put");
+ goto err;
+ }
+ if (i%23 == 0)
+ data.size = data.ulen;
+ }
+
+ for (i = 1; i < COUNT; i += 2) {
+ key.data = &i;
+ memset(data.data, 0, data.size);
+ if ((ret = dbp->get(dbp, NULL, &key, &data, 0)) != 0) {
+ dbenv->err(dbenv, ret, "blob get");
+ goto err;
+ }
+ if (strncmp((char *)data.data, "abcdefghijklmno", 15) != 0)
+ printf("blob data mismatch\n");
+ }
+
+ /* Blobs can also be accessed using the DB_STREAM API. */
+ if ((ret = dbenv->txn_begin(dbenv, NULL, &txn, 0)) != 0){
+ dbenv->err(dbenv, ret, "txn");
+ goto err;
+ }
+
+ if ((ret = dbp->cursor(dbp, txn, &dbc, 0)) != 0) {
+ dbenv->err(dbenv, ret, "cursor");
+ goto err;
+ }
+
+ /*
+ * Set the cursor to a blob. Use DB_DBT_PARTIAL with
+ * dlen == 0 to avoid getting any blob data.
+ */
+ data.flags = DB_DBT_USERMEM | DB_DBT_PARTIAL;
+ data.dlen = 0;
+ if ((ret = dbc->get(dbc, &key, &data, DB_FIRST)) != 0) {
+ dbenv->err(dbenv, ret, "Not a blob");
+ goto err;
+ }
+ data.flags = DB_DBT_USERMEM;
+
+ /* Create a stream on the blob the cursor points to. */
+ if ((ret = dbc->db_stream(dbc, &dbs, DB_STREAM_WRITE)) != 0) {
+ dbenv->err(dbenv, 0, "Creating stream.");
+ goto err;
+ }
+ /* Get the size of the blob. */
+ if ((ret = dbs->size(dbs, &size, 0)) != 0) {
+ dbenv->err(dbenv, 0, "Stream size.");
+ goto err;
+ }
+ /* Read from the blob. */
+ if ((ret = dbs->read(dbs, &data, 0, (u_int32_t)size, 0)) != 0) {
+ dbenv->err(dbenv, 0, "Stream read.");
+ goto err;
+ }
+ /* Write data to the blob, increasing its size. */
+ if ((ret = dbs->write(dbs, &data, size/2, 0)) != 0) {
+ dbenv->err(dbenv, 0, "Stream write.");
+ goto err;
+ }
+ /* Close the stream. */
+ if ((ret = dbs->close(dbs, 0)) != 0) {
+ dbenv->err(dbenv, 0, "Stream close.");
+ goto err;
+ }
+ dbs = NULL;
+ dbc->close(dbc);
+ dbc = NULL;
+ txn->commit(txn, 0);
+ txn = NULL;
+ free(data.data);
+ data.data = NULL;
+
+ for (i = 3; i < COUNT; i += 2) {
+ key.data = &i;
+ if ((ret = dbp->del(dbp, NULL, &key, 0)) != 0) {
+ dbenv->err(dbenv, ret, "blob del");
+ goto err;
+ }
+ }
+
+ /* Close the database handle. */
+ if ((ret = dbp->close(dbp, 0)) != 0) {
+ fprintf(stderr, "database close: %s\n", db_strerror(ret));
+ return (1);
+ }
+
+ /* Close the environment handle. */
+ if ((ret = dbenv->close(dbenv, 0)) != 0) {
+ fprintf(stderr, "DB_ENV->close: %s\n", db_strerror(ret));
+ return (1);
+ }
+ return (0);
+
+err: if (data.data != NULL)
+ free(data.data);
+ if (dbs != NULL)
+ dbs->close(dbs, 0);
+ if (txn != NULL)
+ txn->abort(txn);
+ if (dbc != NULL)
+ dbc->close(dbc);
+ if (dbp != NULL)
+ dbp->close(dbp, 0);
+ if (dbenv != NULL)
+ dbenv->close(dbenv, 0);
+
+ return (ret);
+}
+
+static int
+usage()
+{
+ (void)fprintf(stderr,
+ "usage: %s [-h home] \n", progname);
+ return (EXIT_FAILURE);
+}
diff --git a/examples/c/ex_btrec.c b/examples/c/ex_btrec.c
index 85a910d9..817229b6 100644
--- a/examples/c/ex_btrec.c
+++ b/examples/c/ex_btrec.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id: ex_btrec.c,v 0f73af5ae3da 2010/05/10 05:38:40 alexander $
*/
diff --git a/examples/c/ex_bulk.c b/examples/c/ex_bulk.c
index bc3ec26e..5120fbec 100644
--- a/examples/c/ex_bulk.c
+++ b/examples/c/ex_bulk.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -16,6 +16,7 @@
#include <assert.h>
#include <stdlib.h>
#include <string.h>
+#include <time.h>
#define DATABASE "ex_bulk.db" /* Database name */
#define DATALEN 20 /* The length of data */
@@ -54,8 +55,9 @@ int bulk_delete(DB_ENV *, DB *, int, int, int *, int *, int);
int bulk_delete_sec(DB_ENV *, DB *, int, int, int *, int *, int);
int bulk_fill(DB_ENV *, DB *, int, int, int *, int *, int);
int bulk_get(DB_ENV *, DB *, int, int, int, int *, int);
-int compare_int(DB *, const DBT *, const DBT *);
-DB_ENV *db_init(char *, char *, u_int);
+int compare_int(DB *, const DBT *, const DBT *, size_t *);
+int db_init(DB_ENV *, DB **, DB**, int, int, int);
+DB_ENV *env_init(char *, char *, u_int);
int get_first_str(DB *, const DBT *, const DBT *, DBT *);
int get_string(const char *, char *, int);
int main(int, char *[]);
@@ -82,25 +84,27 @@ main(argc, argv)
struct timeval start_time, end_time;
double secs;
u_int cache, pagesize;
- int biter, ch, count, dups, init, iter, num;
- int ret, rflag, sflag, bulk, delete, pair, verbose;
+ int biter, ch, count, delete, dups, init, iter, num;
+ int pair, ret, rflag, sflag, verbose;
dbp = sdbp = NULL;
dbenv = NULL;
txnp = NULL;
iter = num = 1000000;
- dups = init = rflag = sflag = bulk = delete = verbose = 0;
+ delete = dups = init = rflag = sflag = verbose = 0;
pagesize = 65536;
cache = 1000 * pagesize;
- while ((ch = getopt(argc, argv, "c:d:i:n:p:vDIRSU")) != EOF)
+ while ((ch = getopt(argc, argv, "c:d:i:n:p:vDIRS")) != EOF)
switch (ch) {
case 'c':
cache = (u_int)atoi(optarg);
break;
case 'd':
dups = atoi(optarg);
+ if (dups < 0)
+ usage();
break;
case 'i':
iter = atoi(optarg);
@@ -126,9 +130,6 @@ main(argc, argv)
case 'S':
sflag = 1;
break;
- case 'U':
- bulk = 1;
- break;
case '?':
default:
usage();
@@ -142,78 +143,16 @@ main(argc, argv)
system("mkdir EX_BULK");
}
- if ((dbenv = db_init("EX_BULK", "ex_bulk", cache)) == NULL)
+ if ((dbenv = env_init("EX_BULK", "ex_bulk", cache)) == NULL)
return (-1);
if (init)
exit(0);
/* Create and initialize database object, open the database. */
- if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
- fprintf(stderr,
- "%s: db_create: %s\n", progname, db_strerror(ret));
- exit(EXIT_FAILURE);
- }
- dbp->set_errfile(dbp, stderr);
- dbp->set_errpfx(dbp, progname);
- if ((ret = dbp->set_bt_compare(dbp, compare_int)) != 0) {
- dbp->err(dbp, ret, "set_bt_compare");
- goto err;
- }
- if ((ret = dbp->set_pagesize(dbp, pagesize)) != 0) {
- dbp->err(dbp, ret, "set_pagesize");
- goto err;
- }
- if (dups && (ret = dbp->set_flags(dbp, DB_DUP)) != 0) {
- dbp->err(dbp, ret, "set_flags");
- goto err;
- }
-
- if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
- goto err;
-
- if ((ret = dbp->open(dbp, txnp, DATABASE, "primary", DB_BTREE,
- DB_CREATE , 0664)) != 0) {
- dbp->err(dbp, ret, "%s: open", DATABASE);
- if (txnp != NULL)
- (void)txnp->abort(txnp);
- goto err;
- }
-
- if (sflag) {
- /*
- * Open secondary database. The keys in secondary database
- * are the first charactor in str of struct data in data
- * field of primary database.
- */
- if ((ret = db_create(&sdbp, dbenv, 0)) != 0) {
- fprintf(stderr, "%s: db_create: %s\n",
- progname, db_strerror(ret));
- exit(EXIT_FAILURE);
- }
- if ((ret = sdbp->set_flags(sdbp, DB_DUPSORT)) != 0) {
- sdbp->err(sdbp, ret, "set_flags");
- goto err;
- }
- if ((ret = sdbp->open(sdbp, txnp, DATABASE, "secondary",
- DB_BTREE, DB_CREATE, 0664)) != 0) {
- sdbp->err(sdbp, ret, "%s: secondary open", DATABASE);
- if (txnp != NULL)
- (void)txnp->abort(txnp);
- goto err;
- }
- if ((ret = dbp->associate(dbp, txnp, sdbp, get_first_str,
- 0)) != 0) {
- dbp->err(dbp, ret, "%s: associate", DATABASE);
- if (txnp != NULL)
- (void)txnp->abort(txnp);
- goto err;
- }
- }
-
- if ((ret = txnp->commit(txnp, 0)) != 0)
- goto err;
- txnp = NULL;
+ if ((ret = db_init(dbenv, &dbp, &sdbp, dups, sflag, pagesize)) != 0)
+ return (-1);
+ srand((int)time(NULL));
if (rflag) {
/* Time the get loop. */
(void)gettimeofday(&start_time, NULL);
@@ -334,10 +273,9 @@ bulk_delete(dbenv, dbp, num, dups, countp, iterp, verbose)
j = rand() % num;
/*
- * Need to account for proper buffer size, the buffer must be at
- * least as large as the page size of the underlying database,
- * aligned for unsigned integer access, and be a multiple of 1024
- * bytes in size.
+ * The buffer must be at least as large as the page size of the
+ * underlying database and aligned for unsigned integer access.
+ * Its size must be a multiple of 1024 bytes.
*/
key.ulen = (u_int32_t)UPDATES_PER_BULK_PUT *
(sizeof(u_int32_t) + DATALEN) * 1024;
@@ -348,22 +286,23 @@ bulk_delete(dbenv, dbp, num, dups, countp, iterp, verbose)
memset(data_val, 0, DATALEN);
/*
- * If DB_MULTIPLE, delete all records with a specified set of keys
- * in a DBT. The DBT is constructed by DB_MULTIPLE_WRITE_NEXT. If
- * DB_MULTIPLE_KEY, delete a specific set of key/data pairs in the
- * DBT constructed by DB_MULTIPLE_KEY_WRITE_NEXT. Here, delete
- * keys before the random key, if there are duplicate records,
- * delete duplicate pairs with DB_MULTIPLE_KEY, unless, delete keys
- * with DB_MULTIPLE.
+ * Bulk delete all records of a specific set of keys which includes all
+ * non-negative integers smaller than the random key. The random key is
+ * a random non-negative integer smaller than "num".
+ * If DB_MULTIPLE, construct the key DBT by the DB_MULTIPLE_WRITE_NEXT
+ * with the specific set of keys. If DB_MULTIPLE_KEY, construct the key
+ * DBT by the DB_MULTIPLE_KEY_WRITE_NEXT with all key/data pairs of the
+ * specific set of keys.
*/
- flag |= (dups) ? DB_MULTIPLE : DB_MULTIPLE_KEY;
+ flag |= (dups) ? DB_MULTIPLE_KEY : DB_MULTIPLE;
DB_MULTIPLE_WRITE_INIT(ptrk, &key);
for (i = 0; i < j; i++) {
if (i % UPDATES_PER_BULK_PUT == 0) {
if (txnp != NULL) {
- if ((ret = txnp->commit(txnp, 0)) != 0)
- goto err;
+ ret = txnp->commit(txnp, 0);
txnp = NULL;
+ if (ret != 0)
+ goto err;
}
if ((ret =
dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
@@ -371,24 +310,24 @@ bulk_delete(dbenv, dbp, num, dups, countp, iterp, verbose)
}
if (dups) {
- DB_MULTIPLE_WRITE_NEXT(ptrk, &key, &i, sizeof(i));
- assert(ptrk != NULL);
- count++;
- if (verbose)
- printf("Delete key: %d\n", i);
- } else {
data_val->id = 0;
+ get_string(tstring, data_val->str, i);
do {
- get_string(tstring, data_val->str, i);
DB_MULTIPLE_KEY_WRITE_NEXT(ptrk, &key, &i,
sizeof(i), data_val, DATALEN);
assert(ptrk != NULL);
count++;
if (verbose)
printf(
-"Delete key: %d, \tdata: (id %d, str %s)\n",
+"Delete key: %d, \tdata: (id %d, str %s)\n",
i, data_val->id, data_val->str);
- } while (++data_val->id < dups);
+ } while (data_val->id++ < dups);
+ } else {
+ DB_MULTIPLE_WRITE_NEXT(ptrk, &key, &i, sizeof(i));
+ assert(ptrk != NULL);
+ count++;
+ if (verbose)
+ printf("Delete key: %d\n", i);
}
if ((i + 1) % UPDATES_PER_BULK_PUT == 0) {
@@ -452,10 +391,9 @@ bulk_delete_sec(dbenv, dbp, num, pair, countp, iterp, verbose)
rc = rand() % (STRLEN - 1);
/*
- * Need to account for proper buffer size, the buffer must be at
- * least as large as the page size of the underlying database,
- * aligned for unsigned integer access, and be a multiple of
- * 1024 bytes in size.
+ * The buffer must be at least as large as the page size of the
+ * underlying database and aligned for unsigned integer access.
+ * Its size must be a multiple of 1024 bytes.
*/
key.ulen = (u_int32_t)UPDATES_PER_BULK_PUT *
(sizeof(u_int32_t) + DATALEN) * 1024;
@@ -464,19 +402,23 @@ bulk_delete_sec(dbenv, dbp, num, pair, countp, iterp, verbose)
memset(key.data, 0, key.ulen);
/*
- * Bulk delete records from a random key, which is one of charaters
- * in tstring. If DB_MULTIPLE, delete all characters before the random
- * key in the tstring. If DB_MULTIPLE_KEY, get duplicate data to the
- * specified keys and delete key/data pairs.
+ * Bulk delete all records of a specific set of keys which includes all
+ * characters before the random key in the tstring. The random key is
+ * one of the characters in the tstring.
+ * If DB_MULTIPLE, construct the key DBT by the DB_MULTIPLE_WRITE_NEXT
+ * with the specific set of keys. If DB_MULTIPLE_KEY, construct the key
+ * DBT by the DB_MULTIPLE_KEY_WRITE_NEXT with all key/data pairs of the
+ * specific set of keys.
*/
flag |= (pair) ? DB_MULTIPLE_KEY : DB_MULTIPLE;
DB_MULTIPLE_WRITE_INIT(ptrk, &key);
for (i = 0; i <= rc; i++) {
if (i % UPDATES_PER_BULK_PUT == 0) {
if (txnp != NULL) {
- if ((ret = txnp->commit(txnp, 0)) != 0)
- goto err;
+ ret = txnp->commit(txnp, 0);
txnp = NULL;
+ if (ret != 0)
+ goto err;
}
if ((ret = dbenv->txn_begin(
dbenv, NULL, &txnp, 0)) != 0)
@@ -570,11 +512,10 @@ bulk_fill(dbenv, dbp, num, dups, countp, iterp, verbose)
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
- /*
- * Need to account for proper buffer size,
+ /*
* The buffer must be at least as large as the page size of
- * the underlying database, aligned for unsigned integer
- * access, and be a multiple of 1024 bytes in size.
+ * the underlying database and aligned for unsigned integer
+ * access. Its size must be a multiple of 1024 bytes.
*/
key.ulen = (u_int32_t) UPDATES_PER_BULK_PUT *
(sizeof(u_int32_t) + DATALEN) * 1024;
@@ -589,12 +530,11 @@ bulk_fill(dbenv, dbp, num, dups, countp, iterp, verbose)
memset(data.data, 0, data.ulen);
/*
- * We could bulk insert with either DB_MULTIPLE in two buffers or
- * DB_MULTIPLE_KEY in one buffer. With DB_MULTIPLE, all keys are
- * constructed in key DBT, all data is constructed in data DBT.
- * With DB_MULTIPLE_KEY, all key/data pairs are constructed in
- * the key DBT. Here, we use DB_MULTIPLE mode when there are
- * duplicate records.
+ * Bulk insert with either DB_MULTIPLE in two buffers or
+ * DB_MULTIPLE_KEY in a single buffer. With DB_MULTIPLE, all keys are
+ * constructed in the key DBT, and all data is constructed in the data
+ * DBT. With DB_MULTIPLE_KEY, all key/data pairs are constructed in the
+ * key Dbt. We use DB_MULTIPLE mode when there are duplicate records.
*/
flag |= (dups) ? DB_MULTIPLE : DB_MULTIPLE_KEY;
DB_MULTIPLE_WRITE_INIT(ptrk, &key);
@@ -603,17 +543,18 @@ bulk_fill(dbenv, dbp, num, dups, countp, iterp, verbose)
for (i = 0; i < num; i++) {
if (i % UPDATES_PER_BULK_PUT == 0) {
if (txnp != NULL) {
- if ((ret = txnp->commit(txnp, 0)) != 0)
- goto err;
+ ret = txnp->commit(txnp, 0);
txnp = NULL;
+ if (ret != 0)
+ goto err;
}
if ((ret =
dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
goto err;
}
data_val->id = 0;
+ get_string(tstring, data_val->str, i);
do {
- get_string(tstring, data_val->str, i);
if (dups) {
DB_MULTIPLE_WRITE_NEXT(ptrk, &key,
&i, sizeof(i));
@@ -622,7 +563,7 @@ bulk_fill(dbenv, dbp, num, dups, countp, iterp, verbose)
data_val, DATALEN);
assert(ptrd != NULL);
} else {
- DB_MULTIPLE_KEY_WRITE_NEXT(ptrk,
+ DB_MULTIPLE_KEY_WRITE_NEXT(ptrk,
&key, &i, sizeof(i), data_val, DATALEN);
assert(ptrk != NULL);
}
@@ -631,7 +572,7 @@ bulk_fill(dbenv, dbp, num, dups, countp, iterp, verbose)
"Insert key: %d, \t data: (id %d, str %s)\n",
i, data_val->id, data_val->str);
count++;
- } while (++data_val->id < dups);
+ } while (data_val->id++ < dups);
if ((i + 1) % UPDATES_PER_BULK_PUT == 0) {
switch (ret = dbp->put(dbp, txnp, &key, &data, flag)) {
case 0:
@@ -698,7 +639,6 @@ bulk_get(dbenv, dbp, num, dups, iter, countp, verbose)
/* Initialize key DBT and data DBT, malloc bulk buffer. */
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
- key.data = &j;
key.size = sizeof(j);
data.flags = DB_DBT_USERMEM;
data.data = malloc(DATALEN * 16 * 1024);
@@ -715,13 +655,18 @@ bulk_get(dbenv, dbp, num, dups, iter, countp, verbose)
goto err;
/*
- * Bulk retrieve from a random key. Use DB_MULTIPLE_INIT to
- * initialize variables for bulk retrieval. If there are
- * duplicate records, use DB_MULTIPLE_NEXT to iterate them
- * in the buffer. Unless, use DB_MULTIPLE_KEY_NEXT to iterate
- * records after the random key.
+ * Bulk retrieve by a random key which is a random
+ * non-negative integer smaller than "num".
+ * If there are duplicates in the database, retrieve
+ * with DB_MULTIPLE and use the DB_MULTIPLE_NEXT
+ * to iterate the data of the random key in the data
+ * DBT. Otherwise retrieve with DB_MULTIPLE_KEY and use
+ * the DB_MULTIPLE_KEY_NEXT to iterate the
+ * key/data pairs of the specific set of keys which
+ * includes all integers >= the random key and < "num".
*/
j = rand() % num;
+ key.data = &j;
if ((ret = dbcp->get(dbcp, &key, &data, flags)) != 0)
goto err;
DB_MULTIPLE_INIT(pointer, &data);
@@ -751,15 +696,23 @@ bulk_get(dbenv, dbp, num, dups, iter, countp, verbose)
}
}
- if ((ret = dbcp->close(dbcp)) != 0)
+ ret = dbcp->close(dbcp);
+ dbcp = NULL;
+ if (ret != 0)
goto err;
- if ((ret = txnp->commit(txnp, 0)) != 0)
+
+ ret = txnp->commit(txnp, 0);
+ txnp = NULL;
+ if (ret != 0)
goto err;
}
*countp = count;
-err:
+err: if (dbcp != NULL)
+ (void)dbcp->close(dbcp);
+ if (txnp != NULL)
+ (void)txnp->abort(txnp);
if (ret != 0)
dbp->err(dbp, ret, "get");
free(data.data);
@@ -767,13 +720,15 @@ err:
}
int
-compare_int(dbp, a, b)
+compare_int(dbp, a, b, locp)
DB *dbp;
const DBT *a, *b;
+ size_t *locp;
{
int ai, bi;
dbp = NULL;
+ locp = NULL;
/*
* Returns:
@@ -788,10 +743,102 @@ compare_int(dbp, a, b)
/*
* db_init --
+ * Open the database.
+ */
+int
+db_init(dbenv, dbpp, sdbpp, dups, sflag, pagesize)
+ DB_ENV *dbenv;
+ DB **dbpp, **sdbpp;
+ int dups, sflag, pagesize;
+{
+ DB *dbp, *sdbp;
+ DB_TXN *txnp;
+ int ret;
+
+ dbp = sdbp = NULL;
+ txnp = NULL;
+ ret = 0;
+
+ if ((ret = db_create(&dbp, dbenv, 0)) != 0) {
+ fprintf(stderr,
+ "%s: db_create: %s\n", progname, db_strerror(ret));
+ return (ret);
+ }
+ dbp->set_errfile(dbp, stderr);
+ dbp->set_errpfx(dbp, progname);
+ if ((ret = dbp->set_bt_compare(dbp, compare_int)) != 0) {
+ dbp->err(dbp, ret, "set_bt_compare");
+ goto err;
+ }
+ if ((ret = dbp->set_pagesize(dbp, pagesize)) != 0) {
+ dbp->err(dbp, ret, "set_pagesize");
+ goto err;
+ }
+ if (dups && (ret = dbp->set_flags(dbp, DB_DUP)) != 0) {
+ dbp->err(dbp, ret, "set_flags");
+ goto err;
+ }
+
+ if ((ret = dbenv->txn_begin(dbenv, NULL, &txnp, 0)) != 0)
+ goto err;
+
+ if ((ret = dbp->open(dbp, txnp, DATABASE, "primary", DB_BTREE,
+ DB_CREATE , 0664)) != 0) {
+ dbp->err(dbp, ret, "%s: open", DATABASE);
+ goto err;
+ }
+ *dbpp = dbp;
+
+ if (sflag) {
+ /*
+ * Open secondary database. The keys in secondary database
+ * are the first charactor in str of struct data in data
+ * field of primary database.
+ */
+ if ((ret = db_create(&sdbp, dbenv, 0)) != 0) {
+ fprintf(stderr, "%s: db_create: %s\n",
+ progname, db_strerror(ret));
+ goto err;
+ }
+ if ((ret = sdbp->set_flags(sdbp, DB_DUPSORT)) != 0) {
+ sdbp->err(sdbp, ret, "set_flags");
+ goto err;
+ }
+ if ((ret = sdbp->open(sdbp, txnp, DATABASE, "secondary",
+ DB_BTREE, DB_CREATE, 0664)) != 0) {
+ sdbp->err(sdbp, ret, "%s: secondary open", DATABASE);
+ goto err;
+ }
+ if ((ret = dbp->associate(dbp, txnp, sdbp, get_first_str,
+ 0)) != 0) {
+ dbp->err(dbp, ret, "%s: associate", DATABASE);
+ goto err;
+ }
+ }
+ *sdbpp = sdbp;
+
+ ret = txnp->commit(txnp, 0);
+ txnp = NULL;
+ if (ret != 0)
+ goto err;
+
+ return (0);
+
+err: if (txnp != NULL)
+ (void)txnp->abort(0);
+ if (sdbp != NULL)
+ (void)sdbp->close(sdbp, 0);
+ if (dbp != NULL)
+ (void)dbp->close(dbp, 0);
+ return (ret);
+}
+
+/*
+ * env_init --
* Initialize the environment.
*/
DB_ENV *
-db_init(home, prefix, cachesize)
+env_init(home, prefix, cachesize)
char *home, *prefix;
u_int cachesize;
{
@@ -804,8 +851,10 @@ db_init(home, prefix, cachesize)
}
dbenv->set_errfile(dbenv, stderr);
dbenv->set_errpfx(dbenv, prefix);
- (void)dbenv->set_cachesize(dbenv, 0,
- cachesize == 0 ? 50 * 1024 * 1024 : (u_int32_t)cachesize, 0);
+ if ((ret = dbenv->set_cachesize(dbenv, 0, cachesize, 0)) != 0) {
+ dbenv->err(dbenv, ret, "DB_ENV->set_cachesize");
+ return (NULL);
+ }
if ((ret = dbenv->open(dbenv, home, DB_CREATE | DB_INIT_MPOOL |
DB_INIT_TXN | DB_INIT_LOCK, 0)) != 0) {
@@ -857,11 +906,10 @@ usage()
-n number of keys [1000000] \n\
-p pagesize [65536] \n\
-v verbose output \n\
- -D perform bulk delete \n\
+ -D perform bulk delete \n\
-I just initialize the environment \n\
-R perform bulk read \n\
- -S perform bulk read in secondary database \n\
- -U perform bulk update \n",
+ -S perform bulk operation in secondary database \n",
progname);
exit(EXIT_FAILURE);
}
diff --git a/examples/c/ex_env.c b/examples/c/ex_env.c
index dfc436d6..80c66e89 100644
--- a/examples/c/ex_env.c
+++ b/examples/c/ex_env.c
@@ -1,13 +1,14 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1996, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1996, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
#include <sys/types.h>
+#include <errno.h>
#include <stddef.h>
#include <stdio.h>
#include <stdlib.h>
@@ -25,6 +26,8 @@ int db_teardown __P((const char *, const char *, FILE *, const char *));
static int usage __P((void));
const char *progname = "ex_env"; /* Program name. */
+int EnvFlags =
+ DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL | DB_INIT_TXN;
/*
* An example of a program creating/configuring a Berkeley DB environment.
@@ -37,15 +40,15 @@ main(argc, argv)
extern char *optarg;
extern int optind;
const char *data_dir, *home;
-
int ch;
+
/*
* All of the shared database files live in home, but
* data files will live in data_dir.
*/
home = "TESTDIR";
data_dir = "data";
- while ((ch = getopt(argc, argv, "h:d:")) != EOF)
+ while ((ch = getopt(argc, argv, "h:d:l")) != EOF)
switch (ch) {
case 'h':
home = optarg;
@@ -53,6 +56,9 @@ main(argc, argv)
case 'd':
data_dir = optarg;
break;
+ case 'l':
+ EnvFlags |= DB_LOCKDOWN;
+ break;
case '?':
default:
return (usage());
@@ -108,10 +114,12 @@ db_setup(home, data_dir, errfp, progname)
(void)dbenv->set_data_dir(dbenv, data_dir);
/* Open the environment with full transactional support. */
- if ((ret = dbenv->open(dbenv, home,
- DB_CREATE | DB_INIT_LOCK | DB_INIT_LOG | DB_INIT_MPOOL |
- DB_INIT_TXN, 0644)) != 0) {
+ if ((ret = dbenv->open(dbenv, home, EnvFlags, 0644)) != 0) {
dbenv->err(dbenv, ret, "environment open: %s", home);
+ if (ret == ENOENT) {
+ printf("Please check whether home dir \"%s\" existed.\n",
+ home);
+ }
dbenv->close(dbenv, 0);
return (1);
}
@@ -129,8 +137,12 @@ db_setup(home, data_dir, errfp, progname)
/* Open a database with DB_BTREE access method. */
if ((ret = dbp->open(dbp, NULL, "exenv_db1.db", NULL,
- DB_BTREE, DB_CREATE,0644)) != 0) {
+ DB_BTREE, DB_CREATE, 0644)) != 0) {
fprintf(stderr, "database open: %s\n", db_strerror(ret));
+ if (ret == ENOENT) {
+ printf("Please check whether data dir \"%s\" "
+ "exists under \"%s\".\n", data_dir, home);
+ }
return (1);
}
@@ -178,6 +190,6 @@ static int
usage()
{
(void)fprintf(stderr,
- "usage: %s [-h home] [-d data_dir]\n", progname);
+ "usage: %s [-l] [-h home] [-d data_dir]\n", progname);
return (EXIT_FAILURE);
}
diff --git a/examples/c/ex_heap.c b/examples/c/ex_heap.c
index 990c9365..474be909 100644
--- a/examples/c/ex_heap.c
+++ b/examples/c/ex_heap.c
@@ -1,7 +1,7 @@
/*
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*
@@ -24,7 +24,7 @@
#ifndef lint
static const char copyright[] =
- "Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.\n";
+ "Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved.\n";
#endif
#define BUFFER_LEN 30 /* Buffer size to hold data */
@@ -66,7 +66,7 @@ int gettimeofday(struct timeval *tv, struct timezone *tz)
#include <unistd.h>
#endif
-int compare_int(DB *, const DBT *, const DBT *);
+int compare_int(DB *, const DBT *, const DBT *, size_t *);
int delete_recs __P((DB *, DB_ENV *, int));
int file_size __P((DB *, DBTYPE, int *));
int generate_data __P((char [], int, int));
@@ -622,13 +622,15 @@ err:
}
int
-compare_int(dbp, a, b)
+compare_int(dbp, a, b, locp)
DB *dbp;
const DBT *a, *b;
+ size_t *locp;
{
int ai, bi;
dbp = NULL;
+ locp = NULL;
/*
* Returns:
diff --git a/examples/c/ex_lock.c b/examples/c/ex_lock.c
index 32e22b0e..259d5057 100644
--- a/examples/c/ex_lock.c
+++ b/examples/c/ex_lock.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_mpool.c b/examples/c/ex_mpool.c
index c7a24283..c13e8962 100644
--- a/examples/c/ex_mpool.c
+++ b/examples/c/ex_mpool.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_rep/base/rep_base.c b/examples/c/ex_rep/base/rep_base.c
index c9443e4d..56662220 100644
--- a/examples/c/ex_rep/base/rep_base.c
+++ b/examples/c/ex_rep/base/rep_base.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -169,6 +169,8 @@ main(argc, argv)
goto err;
}
+ machtab_destroy(machtab);
+
/* Finish checkpoint and log archive threads. */
if ((ret = finish_support_threads(&ckp_thr, &lga_thr)) != 0)
goto err;
diff --git a/examples/c/ex_rep/base/rep_base.h b/examples/c/ex_rep/base/rep_base.h
index 27901349..48d5d3ac 100644
--- a/examples/c/ex_rep/base/rep_base.h
+++ b/examples/c/ex_rep/base/rep_base.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -71,6 +71,8 @@ typedef SOCKET socket_t;
#define readsocket(s, buf, sz) recv((s), (buf), (int)(sz), 0)
#define writesocket(s, buf, sz) send((s), (const char *)(buf), (int)(sz), 0)
#define net_errno WSAGetLastError()
+#undef SHUT_RDWR
+#define SHUT_RDWR SD_BOTH
#else /* !_WIN32 */
@@ -104,9 +106,10 @@ socket_t get_accepted_socket __P((const char *, int));
socket_t get_connected_socket
__P((machtab_t *, const char *, const char *, int, int *, int *));
int get_next_message __P((socket_t, DBT *, DBT *));
-socket_t listen_socket_init __P((const char *, int));
+socket_t listen_socket_init __P((const char *, int, machtab_t *));
socket_t listen_socket_accept
__P((machtab_t *, const char *, socket_t, int *));
+int machtab_destroy __P((machtab_t *));
int machtab_getinfo __P((machtab_t *, int, u_int32_t *, int *));
int machtab_init __P((machtab_t **, int));
void machtab_parm __P((machtab_t *, int *, u_int32_t *));
diff --git a/examples/c/ex_rep/base/rep_msg.c b/examples/c/ex_rep/base/rep_msg.c
index 8ed45f7f..bbcaed45 100644
--- a/examples/c/ex_rep/base/rep_msg.c
+++ b/examples/c/ex_rep/base/rep_msg.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -80,6 +80,10 @@ hm_loop(args)
for (ret = 0; ret == 0;) {
if ((ret = get_next_message(fd, &rec, &control)) != 0) {
+ if (app->shared_data.app_finished) {
+ ret = 0;
+ goto netclose;
+ }
/*
* Close this connection; if it's the master call
* for an election.
@@ -183,6 +187,7 @@ hm_loop(args)
"thread join failure");
goto out;
}
+ free(ea);
ea = NULL;
}
if ((ea = calloc(sizeof(elect_args), 1)) == NULL) {
@@ -219,15 +224,21 @@ hm_loop(args)
out: if ((t_ret = machtab_rem(tab, eid, 1)) != 0 && ret == 0)
ret = t_ret;
-
+netclose:
/* Don't close the environment before any children exit. */
- if (ea != NULL && thread_join(elect_thr, &status) != 0)
- dbenv->errx(dbenv, "can't join election thread");
+ if (ea != NULL) {
+ if (thread_join(elect_thr, &status) != 0)
+ dbenv->errx(dbenv, "can't join election thread");
+ free(ea);
+ ea = NULL;
+ }
- if (site_thrs != NULL)
+ if (site_thrs != NULL) {
while (--nsites >= 0)
if (thread_join(site_thrs[nsites], &status) != 0)
dbenv->errx(dbenv, "can't join site thread");
+ free(site_thrs);
+ }
return ((void *)(uintptr_t)ret);
}
@@ -242,6 +253,7 @@ connect_thread(args)
void *args;
{
DB_ENV *dbenv;
+ APP_DATA *app;
const char *home, *progname;
hm_loop_args *ha;
connect_args *cargs;
@@ -252,18 +264,20 @@ connect_thread(args)
socket_t fd, ns;
ha = NULL;
+ i = 0;
cargs = (connect_args *)args;
dbenv = cargs->dbenv;
home = cargs->home;
progname = cargs->progname;
machtab = cargs->machtab;
port = cargs->port;
+ app = dbenv->app_private;
/*
* Loop forever, accepting connections from new machines,
* and forking off a thread to handle each.
*/
- if ((fd = listen_socket_init(progname, port)) < 0) {
+ if ((fd = listen_socket_init(progname, port, machtab)) < 0) {
ret = errno;
goto err;
}
@@ -271,7 +285,10 @@ connect_thread(args)
for (i = 0; i < MAX_THREADS; i++) {
if ((ns = listen_socket_accept(machtab,
progname, fd, &eid)) == SOCKET_CREATION_FAILURE) {
- ret = errno;
+ if (app->shared_data.app_finished)
+ ret = 0;
+ else
+ ret = errno;
goto err;
}
if ((ha = calloc(sizeof(hm_loop_args), 1)) == NULL) {
@@ -285,7 +302,7 @@ connect_thread(args)
ha->eid = eid;
ha->tab = machtab;
ha->dbenv = dbenv;
- if ((ret = thread_create(&hm_thrs[i++], NULL,
+ if ((ret = thread_create(&hm_thrs[i], NULL,
hm_loop, (void *)ha)) != 0) {
dbenv->errx(dbenv, "can't create thread for site");
goto err;
@@ -297,12 +314,13 @@ connect_thread(args)
dbenv->errx(dbenv, "Too many threads");
ret = ENOMEM;
+err:
/* Do not return until all threads have exited. */
while (--i >= 0)
if (thread_join(hm_thrs[i], &status) != 0)
dbenv->errx(dbenv, "can't join site thread");
-err: return (ret == 0 ? (void *)EXIT_SUCCESS : (void *)EXIT_FAILURE);
+ return (ret == 0 ? (void *)EXIT_SUCCESS : (void *)EXIT_FAILURE);
}
/*
@@ -314,15 +332,15 @@ connect_all(args)
void *args;
{
DB_ENV *dbenv;
+ APP_DATA *app;
all_args *aa;
const char *home, *progname;
- hm_loop_args *ha;
int failed, i, nsites, open, ret, *success;
machtab_t *machtab;
- thread_t *hm_thr;
+ thread_t empty_id, *hm_thr;
repsite_t *sites;
+ void *status;
- ha = NULL;
aa = (all_args *)args;
dbenv = aa->dbenv;
progname = aa->progname;
@@ -330,6 +348,9 @@ connect_all(args)
machtab = aa->machtab;
nsites = aa->nsites;
sites = aa->sites;
+ status = NULL;
+ app = dbenv->app_private;
+ memset(&empty_id, 0, sizeof(thread_t));
ret = 0;
hm_thr = NULL;
@@ -353,6 +374,9 @@ connect_all(args)
if (success[i])
continue;
+ if (app->shared_data.app_finished)
+ goto err;
+
ret = connect_site(dbenv, machtab,
progname, &sites[i], &open, &hm_thr[i]);
@@ -378,7 +402,15 @@ connect_all(args)
sleep(1);
}
-err: if (success != NULL)
+err:
+ for (i = 0; i < nsites; i++) {
+ if (!success[i] ||
+ memcmp(&hm_thr[i], &empty_id, sizeof(thread_t)) == 0)
+ continue;
+ if (thread_join(hm_thr[i], &status) != 0)
+ dbenv->errx(dbenv, "can't join site thread");
+ }
+ if (success != NULL)
free(success);
if (hm_thr != NULL)
free(hm_thr);
@@ -453,12 +485,16 @@ elect_thread(args)
machtab_parm(machtab, &n, &timeout);
(void)dbenv->rep_set_timeout(dbenv, DB_REP_ELECTION_TIMEOUT, timeout);
- while ((ret = dbenv->rep_elect(dbenv, n, (n/2+1), 0)) != 0)
+ while ((ret = dbenv->rep_elect(dbenv, n, (n/2+1), 0)) != 0) {
+ if (app->shared_data.app_finished)
+ return (NULL);
sleep(2);
+ }
if (app->elected) {
app->elected = 0;
- if ((ret = dbenv->rep_start(dbenv, NULL, DB_REP_MASTER)) != 0)
+ if ((ret = dbenv->rep_start(dbenv, NULL,
+ DB_REP_MASTER)) != 0 && !app->shared_data.app_finished)
dbenv->err(dbenv, ret,
"can't start as master in election thread");
}
diff --git a/examples/c/ex_rep/base/rep_net.c b/examples/c/ex_rep/base/rep_net.c
index 29012536..e57e3af8 100644
--- a/examples/c/ex_rep/base/rep_net.c
+++ b/examples/c/ex_rep/base/rep_net.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -70,6 +70,7 @@ struct __machtab {
int current;
int max;
int nsites;
+ socket_t listenfd;
};
/* Data structure that describes each entry in the machtab. */
@@ -113,6 +114,7 @@ machtab_init(machtabp, nsites)
machtab->timeout_time = 2 * 1000000; /* 2 seconds. */
machtab->current = machtab->max = 0;
machtab->nsites = nsites;
+ machtab->listenfd = SOCKET_CREATION_FAILURE;
ret = mutex_init(&machtab->mtmutex, NULL);
*machtabp = machtab;
@@ -265,6 +267,47 @@ machtab_rem(machtab, eid, lock)
return (ret);
}
+/*
+ * machtab_destroy --
+ * Close the listening socket and all connecting sockets,
+ * So that all threads blocked on 'accept' and 'read' will be
+ * unblocked.
+ */
+int machtab_destroy(machtab)
+ machtab_t *machtab;
+{
+ int ret;
+ socket_t listenfd;
+ member_t *member;
+
+ if ((ret = mutex_lock(&machtab->mtmutex)) != 0) {
+ fprintf(stderr, "can't lock mutex\n");
+ return (ret);
+ }
+
+ listenfd = machtab->listenfd;
+ machtab->listenfd = SOCKET_CREATION_FAILURE;
+ for (member = LIST_FIRST(&machtab->machlist);
+ member != NULL;
+ member = LIST_FIRST(&machtab->machlist)) {
+ LIST_REMOVE(member, links);
+ shutdown(member->fd, SHUT_RDWR);
+ (void)closesocket(member->fd);
+ free(member);
+ machtab->current--;
+ }
+ shutdown(listenfd, SHUT_RDWR);
+ (void)closesocket(listenfd);
+ machtab->nextid = 2;
+ machtab->current = machtab->max = 0;
+
+ if ((ret = mutex_unlock(&machtab->mtmutex)) != 0) {
+ fprintf(stderr, "can't unlock mutex\n");
+ return (ret);
+ }
+ return (ret);
+}
+
void
machtab_parm(machtab, nump, timeoutp)
machtab_t *machtab;
@@ -310,9 +353,10 @@ machtab_print(machtab)
* in a thread that we're happy to let block.
*/
socket_t
-listen_socket_init(progname, port)
+listen_socket_init(progname, port, machtab)
const char *progname;
int port;
+ machtab_t *machtab;
{
socket_t s;
int sockopt;
@@ -349,6 +393,7 @@ listen_socket_init(progname, port)
goto err;
}
+ machtab->listenfd = s;
return (s);
err: closesocket(s);
@@ -380,7 +425,8 @@ accept_wait:
si_len = sizeof(si);
ns = accept(s, (struct sockaddr *)&si, &si_len);
if (ns == SOCKET_CREATION_FAILURE) {
- fprintf(stderr, "can't accept incoming connection\n");
+ if (machtab->listenfd != SOCKET_CREATION_FAILURE)
+ fprintf(stderr, "can't accept incoming connection\n");
return ns;
}
host = ntohl(si.sin_addr.s_addr);
diff --git a/examples/c/ex_rep/common/rep_common.c b/examples/c/ex_rep/common/rep_common.c
index a091adda..d7d2585a 100644
--- a/examples/c/ex_rep/common/rep_common.c
+++ b/examples/c/ex_rep/common/rep_common.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -19,6 +19,18 @@
#define DATABASE "quote.db"
#define SLEEPTIME 3
+/*
+ * Definition of thread-specific data key for PERM_FAILED structure
+ * stored in thread local storage.
+ */
+#ifdef _WIN32
+/* Windows style. */
+DWORD permfail_key;
+#else
+/* Posix style. */
+pthread_key_t permfail_key;
+#endif
+
static int print_stocks __P((DB *));
/*
@@ -346,15 +358,27 @@ doloop(dbenv, shared_data)
{
DB *dbp;
DBT key, data;
+ permfail_t *pfinfo;
char buf[BUFSIZE], *first, *price;
u_int32_t flags;
int ret;
dbp = NULL;
+ pfinfo = NULL;
ret = 0;
memset(&key, 0, sizeof(key));
memset(&data, 0, sizeof(data));
+ /* Allocate put/commit thread's PERM_FAILED structure. */
+ if (shared_data->is_repmgr) {
+ if ((pfinfo = malloc(sizeof(permfail_t))) == NULL)
+ goto err;
+ if ((ret = thread_setspecific(permfail_key, pfinfo)) != 0)
+ goto err;
+ pfinfo->thread_name = "PutCommit";
+ pfinfo->flag = 0;
+ }
+
for (;;) {
printf("QUOTESERVER%s> ",
shared_data->is_master ? "" : " (read-only)");
@@ -431,6 +455,16 @@ doloop(dbenv, shared_data)
dbenv->err(dbenv, ret, "DB->open");
goto err;
}
+ /* Check this thread's PERM_FAILED indicator. */
+ if (shared_data->is_repmgr) {
+ pfinfo = (permfail_t *)thread_getspecific(
+ permfail_key);
+ if (pfinfo->flag)
+ printf(
+ "%s Thread: dbopen not durable.\n",
+ pfinfo->thread_name);
+ pfinfo->flag = 0;
+ }
}
if (first == NULL) {
@@ -470,11 +504,23 @@ doloop(dbenv, shared_data)
dbp->err(dbp, ret, "DB->put");
goto err;
}
+ /* Check this thread's PERM_FAILED indicator. */
+ if (shared_data->is_repmgr) {
+ pfinfo = (permfail_t *)thread_getspecific(
+ permfail_key);
+ if (pfinfo->flag)
+ printf(
+ "%s Thread: put %s %s not durable.\n",
+ pfinfo->thread_name, first, price);
+ pfinfo->flag = 0;
+ }
}
}
err: if (dbp != NULL)
(void)dbp->close(dbp, DB_NOSYNC);
+ if (pfinfo != NULL)
+ free(pfinfo);
return (ret);
}
@@ -575,12 +621,24 @@ checkpoint_thread(args)
{
DB_ENV *dbenv;
SHARED_DATA *shared;
+ permfail_t *pfinfo;
supthr_args *ca;
int i, ret;
ca = (supthr_args *)args;
dbenv = ca->dbenv;
shared = ca->shared;
+ pfinfo = NULL;
+
+ /* Allocate checkpoint thread's PERM_FAILED structure. */
+ if (shared->is_repmgr) {
+ if ((pfinfo = malloc(sizeof(permfail_t))) == NULL)
+ return ((void *)EXIT_FAILURE);
+ if ((ret = thread_setspecific(permfail_key, pfinfo)) != 0)
+ return ((void *)EXIT_FAILURE);
+ pfinfo->thread_name = "Checkpoint";
+ pfinfo->flag = 0;
+ }
for (;;) {
/*
@@ -590,16 +648,30 @@ checkpoint_thread(args)
*/
for (i = 0; i < 60; i++) {
sleep(1);
- if (shared->app_finished == 1)
+ if (shared->app_finished == 1) {
+ if (pfinfo != NULL)
+ free(pfinfo);
return ((void *)EXIT_SUCCESS);
+ }
}
/* Perform a checkpoint. */
if ((ret = dbenv->txn_checkpoint(dbenv, 0, 0, 0)) != 0) {
dbenv->err(dbenv, ret,
"Could not perform checkpoint.\n");
+ if (pfinfo != NULL)
+ free(pfinfo);
return ((void *)EXIT_FAILURE);
}
+ /* Check this thread's PERM_FAILED indicator. */
+ if (shared->is_repmgr) {
+ pfinfo = (permfail_t *)thread_getspecific(
+ permfail_key);
+ if (pfinfo->flag)
+ printf("%s Thread: checkpoint not durable.\n",
+ pfinfo->thread_name);
+ pfinfo->flag = 0;
+ }
}
}
diff --git a/examples/c/ex_rep/common/rep_common.h b/examples/c/ex_rep/common/rep_common.h
index edf3b67d..8f7d1348 100644
--- a/examples/c/ex_rep/common/rep_common.h
+++ b/examples/c/ex_rep/common/rep_common.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -33,6 +33,7 @@ typedef struct {
int is_master;
int app_finished;
int in_client_sync;
+ int is_repmgr;
} SHARED_DATA;
/* Arguments for support threads. */
@@ -41,6 +42,15 @@ typedef struct {
SHARED_DATA *shared;
} supthr_args;
+/*
+ * Per-thread Replication Manager structure to associate a PERM_FAILED event
+ * with its originating transaction.
+ */
+typedef struct {
+ char *thread_name;
+ int flag;
+} permfail_t;
+
/* Portability macros for basic threading & timing */
#ifdef _WIN32
#define WIN32_LEAN_AND_MEAN
@@ -59,6 +69,16 @@ typedef HANDLE thread_t;
((WaitForSingleObject((thr), INFINITE) == WAIT_OBJECT_0) && \
GetExitCodeThread((thr), (LPDWORD)(statusp)) ? 0 : -1)
+/* Thread-specific data key for PERM_FAILED structure for Windows. */
+extern DWORD permfail_key;
+/* Thread local storage routine definitions for Windows. */
+#define thread_key_create(keyp) ((*keyp = TlsAlloc()) == \
+ TLS_OUT_OF_INDEXES ? (int)GetLastError() : 0)
+#define thread_key_delete(key) (TlsFree(key) ? 0 : (int)GetLastError())
+#define thread_setspecific(key, value) (TlsSetValue(key, value) ? 0 : \
+ (int)GetLastError())
+#define thread_getspecific(key) TlsGetValue(key)
+
#else /* !_WIN32 */
#include <sys/time.h>
#include <pthread.h>
@@ -68,6 +88,14 @@ typedef pthread_t thread_t;
pthread_create((thrp), (attr), (func), (arg))
#define thread_join(thr, statusp) pthread_join((thr), (statusp))
+/* Thread-specific data key for PERM_FAILED structure for Posix. */
+extern pthread_key_t permfail_key;
+/* Thread local storage routine definitions for Posix. */
+#define thread_key_create(keyp) pthread_key_create(keyp, NULL)
+#define thread_key_delete(key) pthread_key_delete(key)
+#define thread_setspecific(key, value) pthread_setspecific(key, value)
+#define thread_getspecific(key) pthread_getspecific(key)
+
#endif
void *checkpoint_thread __P((void *));
diff --git a/examples/c/ex_rep/mgr/rep_mgr.c b/examples/c/ex_rep/mgr/rep_mgr.c
index 0eaf1971..5c6d15f5 100644
--- a/examples/c/ex_rep/mgr/rep_mgr.c
+++ b/examples/c/ex_rep/mgr/rep_mgr.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2001, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2001, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -115,6 +115,10 @@ main(argc, argv)
dbenv->err(dbenv, ret,
"Could not set heartbeat monitor timeout.\n");
+ /* Create thread-specific data key for PERM_FAILED structure. */
+ if ((ret = thread_key_create(&permfail_key)) != 0)
+ goto err;
+
/*
* The following repmgr features may also be useful to your
* application. See Berkeley DB documentation for more details.
@@ -133,6 +137,7 @@ main(argc, argv)
/* Start checkpoint and log archive threads. */
sup_args.dbenv = dbenv;
sup_args.shared = &my_app_data.shared_data;
+ my_app_data.shared_data.is_repmgr = 1;
if ((ret = start_support_threads(dbenv, &sup_args, &ckp_thr,
&lga_thr)) != 0)
goto err;
@@ -163,6 +168,10 @@ main(argc, argv)
goto err;
}
+ /* Delete thread-specific data key for PERM_FAILED structure. */
+ if ((ret = thread_key_delete(permfail_key)) != 0)
+ goto err;
+
err:
if (dbenv != NULL &&
(t_ret = dbenv->close(dbenv, 0)) != 0) {
@@ -183,8 +192,10 @@ event_callback(dbenv, which, info)
{
APP_DATA *app = dbenv->app_private;
SHARED_DATA *shared = &app->shared_data;
+ permfail_t *pfinfo;
int err;
+ pfinfo = NULL;
switch (which) {
case DB_EVENT_PANIC:
@@ -213,8 +224,12 @@ event_callback(dbenv, which, info)
* transaction will be flushed to the master site's
* local disk storage for durability.
*/
+ /* Set this thread's PERM_FAILED indicator. */
+ pfinfo = (permfail_t *)thread_getspecific(permfail_key);
+ printf("%s Thread: ", pfinfo->thread_name);
+ pfinfo->flag = 1;
printf(
- "Insufficient acknowledgements to guarantee transaction durability.\n");
+ "Insufficient acknowledgements for transaction durability.\n");
break;
case DB_EVENT_REP_STARTUPDONE:
diff --git a/examples/c/ex_rep_chan/rep_chan.c b/examples/c/ex_rep_chan/rep_chan.c
index f5638264..1c661746 100644
--- a/examples/c/ex_rep_chan/rep_chan.c
+++ b/examples/c/ex_rep_chan/rep_chan.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_rep_chan/rep_chan.h b/examples/c/ex_rep_chan/rep_chan.h
index 9eff740d..7f46b5ff 100644
--- a/examples/c/ex_rep_chan/rep_chan.h
+++ b/examples/c/ex_rep_chan/rep_chan.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2011, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2011, 2015 Oracle and/or its affiliates. All rights reserved.
* $Id$
*/
diff --git a/examples/c/ex_rep_chan/rep_chan_util.c b/examples/c/ex_rep_chan/rep_chan_util.c
index 07758152..b915e58d 100644
--- a/examples/c/ex_rep_chan/rep_chan_util.c
+++ b/examples/c/ex_rep_chan/rep_chan_util.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
@@ -622,7 +622,7 @@ open_dbp(dbenv, is_master, dbpp)
{
DB *dbp;
u_int32_t flags;
- int ret;
+ int ret, t_ret;
if ((ret = db_create(dbpp, dbenv, 0)) != 0)
return (ret);
@@ -647,13 +647,13 @@ open_dbp(dbenv, is_master, dbpp)
if ((ret = dbp->open(dbp,
NULL, DATABASE, NULL, DB_BTREE, flags, 0)) != 0) {
if (ret == ENOENT) {
- printf( "No stock database yet available.\n");
- if ((ret = dbp->close(dbp, 0)) != 0) {
- dbenv->err(dbenv, ret,
- "DB->close");
+ printf("No stock database yet available.\n");
+ *dbpp = NULL;
+ if ((t_ret = dbp->close(dbp, 0)) != 0) {
+ ret = t_ret;
+ dbenv->err(dbenv, ret, "DB->close");
goto err;
}
- *dbpp = NULL;
}
if (ret == DB_REP_HANDLE_DEAD ||
ret == DB_LOCK_DEADLOCK) {
diff --git a/examples/c/ex_rep_gsg/rep_mgr_gsg.c b/examples/c/ex_rep_gsg/rep_mgr_gsg.c
index aea8a05f..879a1c9d 100644
--- a/examples/c/ex_rep_gsg/rep_mgr_gsg.c
+++ b/examples/c/ex_rep_gsg/rep_mgr_gsg.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_rep_gsg/simple_txn.c b/examples/c/ex_rep_gsg/simple_txn.c
index c8feb16d..54406f4a 100644
--- a/examples/c/ex_rep_gsg/simple_txn.c
+++ b/examples/c/ex_rep_gsg/simple_txn.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2006, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2006, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_sequence.c b/examples/c/ex_sequence.c
index 28f0e199..dd01ec33 100644
--- a/examples/c/ex_sequence.c
+++ b/examples/c/ex_sequence.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_stream.c b/examples/c/ex_stream.c
index 209d6279..5bc0f0ed 100644
--- a/examples/c/ex_stream.c
+++ b/examples/c/ex_stream.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_thread.c b/examples/c/ex_thread.c
index 7b39c8eb..00e0c368 100644
--- a/examples/c/ex_thread.c
+++ b/examples/c/ex_thread.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/ex_tpcb.c b/examples/c/ex_tpcb.c
index 16807d2c..89a9210c 100644
--- a/examples/c/ex_tpcb.c
+++ b/examples/c/ex_tpcb.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 1997, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 1997, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/getting_started/example_database_load.c b/examples/c/getting_started/example_database_load.c
index 52127421..e09a1096 100644
--- a/examples/c/getting_started/example_database_load.c
+++ b/examples/c/getting_started/example_database_load.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015 Oracle and/or its affiliates. All rights reserved.
*/
#include "gettingstarted_common.h"
@@ -77,7 +77,7 @@ main(int argc, char *argv[])
/* Open all databases */
ret = databases_setup(&my_stock, "example_database_load", stderr);
if (ret) {
- fprintf(stderr, "Error opening databases\n");
+ fprintf(stderr, "Error opening databases.\n");
databases_close(&my_stock);
return (ret);
}
@@ -121,6 +121,7 @@ load_vendors_database(STOCK_DBS my_stock, char *vendor_file)
return (-1);
}
+ /* Iterate over the vendor file */
while (fgets(buf, MAXLINE, ifp) != NULL) {
/* zero out the structure */
memset(&my_vendor, 0, sizeof(VENDOR));
@@ -164,6 +165,7 @@ load_vendors_database(STOCK_DBS my_stock, char *vendor_file)
my_stock.vendor_dbp->put(my_stock.vendor_dbp, 0, &key, &data, 0);
} /* end vendors database while loop */
+ /* Close the vendor.txt file */
fclose(ifp);
return (0);
}
@@ -220,6 +222,10 @@ load_inventory_database(STOCK_DBS my_stock, char *inventory_file)
return (-1);
}
+ /*
+ * Read the inventory.txt file line by line, saving each line off to
+ * the database as we go.
+ */
while (fgets(buf, MAXLINE, ifp) != NULL) {
/*
* Scan the line into the appropriate buffers and variables.
@@ -238,10 +244,22 @@ load_inventory_database(STOCK_DBS my_stock, char *inventory_file)
bufLen = 0;
dataLen = 0;
+ /*
+ * We first store the fixed-length elements. This makes our code
+ * to retrieve this data from the database a little bit easier.
+ */
+
+ /* First discover how long the data element is. */
dataLen = sizeof(float);
+ /* Then copy it to our buffer */
memcpy(databuf, &price, dataLen);
+ /*
+ * Then figure out how much data is actually in our buffer.
+ * We repeat this pattern for all the data we want to store.
+ */
bufLen += dataLen;
+ /* Rinse, lather, repeat. */
dataLen = sizeof(int);
memcpy(databuf + bufLen, &quantity, dataLen);
bufLen += dataLen;
@@ -251,11 +269,19 @@ load_inventory_database(STOCK_DBS my_stock, char *inventory_file)
bufLen = pack_string(databuf, category, bufLen);
bufLen = pack_string(databuf, vendor, bufLen);
+ /*
+ * Now actually save the contents of the buffer off
+ * to our database.
+ */
+
/* Zero out the DBTs */
memset(&key, 0, sizeof(DBT));
memset(&data, 0, sizeof(DBT));
- /* The key is the item's SKU */
+ /*
+ * The key is the item's SKU. This is a unique value, so we need
+ * not support duplicates for this database.
+ */
key.data = sku;
key.size = (u_int32_t)strlen(sku) + 1;
diff --git a/examples/c/getting_started/example_database_read.c b/examples/c/getting_started/example_database_read.c
index 79a9fc2c..0e8486ff 100644
--- a/examples/c/getting_started/example_database_read.c
+++ b/examples/c/getting_started/example_database_read.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015 Oracle and/or its affiliates. All rights reserved.
*/
#include "gettingstarted_common.h"
@@ -72,6 +72,10 @@ main(int argc, char *argv[])
return (ret);
}
+ /*
+ * Show either a single item or all items, depending
+ * on whether itemname is set to a value.
+ */
if (itemname == NULL)
ret = show_all_records(&my_stock);
else
@@ -197,23 +201,33 @@ show_inventory_item(void *vBuf)
char *category, *name, *sku, *vendor_name;
char *buf = (char *)vBuf;
+ /* Get the price. */
price = *((float *)buf);
buf_pos = sizeof(float);
+ /* Get the quantity. */
quantity = *((int *)(buf + buf_pos));
buf_pos += sizeof(int);
+ /* Get the inventory item's name */
name = buf + buf_pos;
buf_pos += strlen(name) + 1;
+ /* Get the inventory item's sku */
sku = buf + buf_pos;
buf_pos += strlen(sku) + 1;
+ /*
+ * Get the category (fruits, vegetables, desserts) that this
+ * item belongs to.
+ */
category = buf + buf_pos;
buf_pos += strlen(category) + 1;
+ /* Get the vendor's name */
vendor_name = buf + buf_pos;
+ /* Display all this information */
printf("name: %s\n", name);
printf("\tSKU: %s\n", sku);
printf("\tCategory: %s\n", category);
@@ -221,6 +235,7 @@ show_inventory_item(void *vBuf)
printf("\tQuantity: %i\n", quantity);
printf("\tVendor:\n");
+ /* Return the vendor's name */
return (vendor_name);
}
diff --git a/examples/c/getting_started/gettingstarted_common.c b/examples/c/getting_started/gettingstarted_common.c
index 86faa1c0..f388b13d 100644
--- a/examples/c/getting_started/gettingstarted_common.c
+++ b/examples/c/getting_started/gettingstarted_common.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015 Oracle and/or its affiliates. All rights reserved.
*/
#include "gettingstarted_common.h"
@@ -49,9 +49,11 @@ get_item_name(DB *dbp, const DBT *pkey, const DBT *pdata, DBT *skey)
/* Opens a database */
int
-open_database(DB **dbpp, const char *file_name,
- const char *program_name, FILE *error_file_pointer,
- int is_secondary)
+open_database(DB **dbpp, /* The DB handle that we are opening */
+ const char *file_name, /* The file in which the db lives */
+ const char *program_name, /* Name of the program */
+ FILE *error_file_pointer,
+ int is_secondary)
{
DB *dbp; /* For convenience */
u_int32_t open_flags;
@@ -173,8 +175,8 @@ initialize_stockdbs(STOCK_DBS *my_stock)
my_stock->inventory_dbp = NULL;
my_stock->vendor_dbp = NULL;
my_stock->itemname_sdbp = NULL;
- my_stock->vendor_db_name = NULL;
my_stock->inventory_db_name = NULL;
+ my_stock->vendor_db_name = NULL;
my_stock->itemname_db_name = NULL;
}
diff --git a/examples/c/getting_started/gettingstarted_common.h b/examples/c/getting_started/gettingstarted_common.h
index 7365fc7f..90c12e6e 100644
--- a/examples/c/getting_started/gettingstarted_common.h
+++ b/examples/c/getting_started/gettingstarted_common.h
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2004, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2004, 2015 Oracle and/or its affiliates. All rights reserved.
*/
#include <db.h>
@@ -52,8 +52,8 @@ typedef struct vendor {
} VENDOR;
/* Function prototypes */
-int databases_close(STOCK_DBS *);
int databases_setup(STOCK_DBS *, const char *, FILE *);
+int databases_close(STOCK_DBS *);
void initialize_stockdbs(STOCK_DBS *);
int open_database(DB **, const char *, const char *, FILE *, int);
void set_db_filenames(STOCK_DBS *my_stock);
diff --git a/examples/c/txn_guide/txn_guide.c b/examples/c/txn_guide/txn_guide.c
index e278120e..813244fd 100644
--- a/examples/c/txn_guide/txn_guide.c
+++ b/examples/c/txn_guide/txn_guide.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/
diff --git a/examples/c/txn_guide/txn_guide_inmemory.c b/examples/c/txn_guide/txn_guide_inmemory.c
index 621bb2ae..d15397ad 100644
--- a/examples/c/txn_guide/txn_guide_inmemory.c
+++ b/examples/c/txn_guide/txn_guide_inmemory.c
@@ -1,7 +1,7 @@
/*-
* See the file LICENSE for redistribution information.
*
- * Copyright (c) 2005, 2012 Oracle and/or its affiliates. All rights reserved.
+ * Copyright (c) 2005, 2015 Oracle and/or its affiliates. All rights reserved.
*
* $Id$
*/