Back to home page

Enduro/X

 
 

    


0001 /* mtest.c - memory-mapped database tester/toy */
0002 /*
0003  * Copyright 2011-2017 Howard Chu, Symas Corp.
0004  * All rights reserved.
0005  *
0006  * Redistribution and use in source and binary forms, with or without
0007  * modification, are permitted only as authorized by the OpenLDAP
0008  * Public License.
0009  *
0010  * A copy of this license is available in the file LICENSE in the
0011  * top-level directory of the distribution or, alternatively, at
0012  * <http://www.OpenLDAP.org/license.html>.
0013  */
0014 #include <stdio.h>
0015 #include <stdlib.h>
0016 #include <time.h>
0017 #include <cgreen/cgreen.h>
0018 #include <ndebug.h>
0019 #include <edbutil.h>
0020 #include "exdb.h"
0021 #include "ndebug.h"
0022 
0023 #define E(expr) CHECK((rc = (expr)) == EDB_SUCCESS, #expr)
0024 #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
0025 #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
0026     "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, edb_strerror(rc)), abort()))
0027 
0028 Ensure(test_nstd_mtest)
0029 {
0030     int i = 0, j = 0, rc;
0031     EDB_env *env;
0032     EDB_dbi dbi;
0033     EDB_val key, data;
0034     EDB_txn *txn;
0035     EDB_stat mst;
0036     EDB_cursor *cursor, *cur2;
0037     EDB_cursor_op op;
0038     int count;
0039     int *values;
0040     char sval[32] = "";
0041     char errdet[PATH_MAX];
0042 
0043     srand(time(NULL));
0044 
0045     count = (rand()%384) + 64;
0046     values = (int *)malloc(count*sizeof(int));
0047 
0048     for(i = 0;i<count;i++) {
0049                 values[i] = rand()%1024;
0050     }
0051 
0052     E(ndrx_mdb_unlink("./testdb", errdet, sizeof(errdet), 
0053             LOG_FACILITY_UBF));
0054 
0055     E(edb_env_create(&env));
0056     E(edb_env_set_maxreaders(env, 1));
0057     E(edb_env_set_mapsize(env, 10485760));
0058     E(edb_env_open(env, "./testdb", EDB_FIXEDMAP /*|EDB_NOSYNC*/, 0664));
0059 
0060     E(edb_txn_begin(env, NULL, 0, &txn));
0061     E(edb_dbi_open(txn, NULL, 0, &dbi));
0062 
0063     key.mv_size = sizeof(int);
0064     key.mv_data = sval;
0065 
0066     fprintf(stderr, "Adding %d values\n", count);
0067     for (i=0;i<count;i++) { 
0068         sprintf(sval, "%03x %d foo bar", values[i], values[i]);
0069         /* Set <data> in each iteration, since EDB_NOOVERWRITE may modify it */
0070         data.mv_size = sizeof(sval);
0071         data.mv_data = sval;
0072         if (RES(EDB_KEYEXIST, edb_put(txn, dbi, &key, &data, EDB_NOOVERWRITE))) {
0073                 j++;
0074                 data.mv_size = sizeof(sval);
0075                 data.mv_data = sval;
0076         }
0077     }
0078     if (j) fprintf(stderr, "%d duplicates skipped\n", j);
0079     E(edb_txn_commit(txn));
0080     E(edb_env_stat(env, &mst));
0081 
0082     E(edb_txn_begin(env, NULL, EDB_RDONLY, &txn));
0083     E(edb_cursor_open(txn, dbi, &cursor));
0084     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_NEXT)) == 0) {
0085             fprintf(stderr, "key: %p %.*s, data: %p %.*s\n",
0086                     key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
0087                     data.mv_data, (int) data.mv_size, (char *) data.mv_data);
0088     }
0089     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0090     edb_cursor_close(cursor);
0091     edb_txn_abort(txn);
0092 
0093     j=0;
0094     key.mv_data = sval;
0095     for (i= count - 1; i > -1; i-= (rand()%5)) {
0096         j++;
0097         txn=NULL;
0098         E(edb_txn_begin(env, NULL, 0, &txn));
0099         sprintf(sval, "%03x ", values[i]);
0100         if (RES(EDB_NOTFOUND, edb_del(txn, dbi, &key, NULL))) {
0101                 j--;
0102                 edb_txn_abort(txn);
0103         } else {
0104                 E(edb_txn_commit(txn));
0105         }
0106     }
0107     free(values);
0108     fprintf(stderr, "Deleted %d values\n", j);
0109 
0110     E(edb_env_stat(env, &mst));
0111     E(edb_txn_begin(env, NULL, EDB_RDONLY, &txn));
0112     E(edb_cursor_open(txn, dbi, &cursor));
0113     fprintf(stderr, "Cursor next\n");
0114     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_NEXT)) == 0) {
0115             fprintf(stderr, "key: %.*s, data: %.*s\n",
0116                     (int) key.mv_size,  (char *) key.mv_data,
0117                     (int) data.mv_size, (char *) data.mv_data);
0118     }
0119     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0120     fprintf(stderr, "Cursor last\n");
0121     E(edb_cursor_get(cursor, &key, &data, EDB_LAST));
0122     fprintf(stderr, "key: %.*s, data: %.*s\n",
0123             (int) key.mv_size,  (char *) key.mv_data,
0124             (int) data.mv_size, (char *) data.mv_data);
0125     fprintf(stderr, "Cursor prev\n");
0126     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_PREV)) == 0) {
0127             fprintf(stderr, "key: %.*s, data: %.*s\n",
0128                     (int) key.mv_size,  (char *) key.mv_data,
0129                     (int) data.mv_size, (char *) data.mv_data);
0130     }
0131     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0132     fprintf(stderr, "Cursor last/prev\n");
0133     E(edb_cursor_get(cursor, &key, &data, EDB_LAST));
0134             fprintf(stderr, "key: %.*s, data: %.*s\n",
0135                     (int) key.mv_size,  (char *) key.mv_data,
0136                     (int) data.mv_size, (char *) data.mv_data);
0137     E(edb_cursor_get(cursor, &key, &data, EDB_PREV));
0138             fprintf(stderr, "key: %.*s, data: %.*s\n",
0139                     (int) key.mv_size,  (char *) key.mv_data,
0140                     (int) data.mv_size, (char *) data.mv_data);
0141 
0142     edb_cursor_close(cursor);
0143     edb_txn_abort(txn);
0144 
0145     fprintf(stderr, "Deleting with cursor\n");
0146     E(edb_txn_begin(env, NULL, 0, &txn));
0147     E(edb_cursor_open(txn, dbi, &cur2));
0148     for (i=0; i<50; i++) {
0149             if (RES(EDB_NOTFOUND, edb_cursor_get(cur2, &key, &data, EDB_NEXT)))
0150                     break;
0151             fprintf(stderr, "key: %p %.*s, data: %p %.*s\n",
0152                     key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
0153                     data.mv_data, (int) data.mv_size, (char *) data.mv_data);
0154             E(edb_del(txn, dbi, &key, NULL));
0155     }
0156 
0157     fprintf(stderr, "Restarting cursor in txn\n");
0158     for (op=EDB_FIRST, i=0; i<=32; op=EDB_NEXT, i++) {
0159             if (RES(EDB_NOTFOUND, edb_cursor_get(cur2, &key, &data, op)))
0160                     break;
0161             fprintf(stderr, "key: %p %.*s, data: %p %.*s\n",
0162                     key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
0163                     data.mv_data, (int) data.mv_size, (char *) data.mv_data);
0164     }
0165     edb_cursor_close(cur2);
0166     E(edb_txn_commit(txn));
0167 
0168     fprintf(stderr, "Restarting cursor outside txn\n");
0169     E(edb_txn_begin(env, NULL, 0, &txn));
0170     E(edb_cursor_open(txn, dbi, &cursor));
0171     for (op=EDB_FIRST, i=0; i<=32; op=EDB_NEXT, i++) {
0172             if (RES(EDB_NOTFOUND, edb_cursor_get(cursor, &key, &data, op)))
0173                     break;
0174             fprintf(stderr, "key: %p %.*s, data: %p %.*s\n",
0175                     key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
0176                     data.mv_data, (int) data.mv_size, (char *) data.mv_data);
0177     }
0178     edb_cursor_close(cursor);
0179     edb_txn_abort(txn);
0180 
0181     edb_dbi_close(env, dbi);
0182     edb_env_close(env);
0183 
0184     return;
0185 }
0186 
0187 
0188 /**
0189  * LMDB/EDB tests
0190  * @return
0191  */
0192 TestSuite *ubf_nstd_mtest(void)
0193 {
0194     TestSuite *suite = create_test_suite();
0195 
0196     add_test(suite, test_nstd_mtest);
0197             
0198     return suite;
0199 }
0200