Back to home page

Enduro/X

 
 

    


0001 /* mtest4.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 
0015 /* Tests for sorted duplicate DBs with fixed-size keys */
0016 #include <stdio.h>
0017 #include <stdlib.h>
0018 #include <string.h>
0019 #include <time.h>
0020 #include <cgreen/cgreen.h>
0021 #include <ndebug.h>
0022 #include <edbutil.h>
0023 #include "exdb.h"
0024 
0025 #define E(expr) CHECK((rc = (expr)) == EDB_SUCCESS, #expr)
0026 #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
0027 #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
0028     "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, edb_strerror(rc)), abort()))
0029 
0030 Ensure(test_nstd_mtest4)
0031 {
0032     int i = 0, j = 0, rc;
0033     EDB_env *env;
0034     EDB_dbi dbi;
0035     EDB_val key, data;
0036     EDB_txn *txn;
0037     EDB_stat mst;
0038     EDB_cursor *cursor;
0039     int count;
0040     int *values;
0041     char sval[8];
0042     char kval[sizeof(int)];
0043         char errdet[PATH_MAX];
0044             
0045     memset(sval, 0, sizeof(sval));
0046 
0047     count = 510;
0048     values = (int *)malloc(count*sizeof(int));
0049 
0050     for(i = 0;i<count;i++) {
0051         values[i] = i*5;
0052     }
0053 
0054         E(ndrx_mdb_unlink("./testdb", errdet, sizeof(errdet), 
0055             LOG_FACILITY_UBF));
0056         
0057     E(edb_env_create(&env));
0058     E(edb_env_set_mapsize(env, 10485760));
0059     E(edb_env_set_maxdbs(env, 4));
0060     E(edb_env_open(env, "./testdb", EDB_FIXEDMAP|EDB_NOSYNC, 0664));
0061 
0062     E(edb_txn_begin(env, NULL, 0, &txn));
0063     E(edb_dbi_open(txn, "id4", EDB_CREATE|EDB_DUPSORT|EDB_DUPFIXED, &dbi));
0064         
0065 
0066     key.mv_size = sizeof(int);
0067     key.mv_data = kval;
0068     data.mv_size = sizeof(sval);
0069     data.mv_data = sval;
0070 
0071     fprintf(stderr, "Adding %d values\n", count);
0072     strcpy(kval, "001");
0073     for (i=0;i<count;i++) {
0074         sprintf(sval, "%07x", values[i]);
0075         if (RES(EDB_KEYEXIST, edb_put(txn, dbi, &key, &data, EDB_NODUPDATA)))
0076             j++;
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     /* there should be one full page of dups now.
0083      */
0084     E(edb_txn_begin(env, NULL, EDB_RDONLY, &txn));
0085     E(edb_cursor_open(txn, dbi, &cursor));
0086     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_NEXT)) == 0) {
0087         fprintf(stderr, "key: %p %.*s, data: %p %.*s\n",
0088             key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
0089             data.mv_data, (int) data.mv_size, (char *) data.mv_data);
0090     }
0091     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0092     edb_cursor_close(cursor);
0093     edb_txn_abort(txn);
0094 
0095     /* test all 3 branches of split code:
0096      * 1: new key in lower half
0097      * 2: new key at split point
0098      * 3: new key in upper half
0099      */
0100 
0101     key.mv_size = sizeof(int);
0102     key.mv_data = kval;
0103     data.mv_size = sizeof(sval);
0104     data.mv_data = sval;
0105 
0106     sprintf(sval, "%07x", values[3]+1);
0107     E(edb_txn_begin(env, NULL, 0, &txn));
0108     (void)RES(EDB_KEYEXIST, edb_put(txn, dbi, &key, &data, EDB_NODUPDATA));
0109     edb_txn_abort(txn);
0110 
0111     sprintf(sval, "%07x", values[255]+1);
0112     E(edb_txn_begin(env, NULL, 0, &txn));
0113     (void)RES(EDB_KEYEXIST, edb_put(txn, dbi, &key, &data, EDB_NODUPDATA));
0114     edb_txn_abort(txn);
0115 
0116     sprintf(sval, "%07x", values[500]+1);
0117     E(edb_txn_begin(env, NULL, 0, &txn));
0118     (void)RES(EDB_KEYEXIST, edb_put(txn, dbi, &key, &data, EDB_NODUPDATA));
0119     E(edb_txn_commit(txn));
0120 
0121     /* Try EDB_NEXT_MULTIPLE */
0122     E(edb_txn_begin(env, NULL, 0, &txn));
0123     E(edb_cursor_open(txn, dbi, &cursor));
0124     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_NEXT_MULTIPLE)) == 0) {
0125         fprintf(stderr, "key: %.*s, data: %.*s\n",
0126             (int) key.mv_size,  (char *) key.mv_data,
0127             (int) data.mv_size, (char *) data.mv_data);
0128     }
0129     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0130     edb_cursor_close(cursor);
0131     edb_txn_abort(txn);
0132     j=0;
0133 
0134     for (i= count - 1; i > -1; i-= (rand()%3)) {
0135         j++;
0136         txn=NULL;
0137         E(edb_txn_begin(env, NULL, 0, &txn));
0138         sprintf(sval, "%07x", values[i]);
0139         key.mv_size = sizeof(int);
0140         key.mv_data = kval;
0141         data.mv_size = sizeof(sval);
0142         data.mv_data = sval;
0143         if (RES(EDB_NOTFOUND, edb_del(txn, dbi, &key, &data))) {
0144             j--;
0145             edb_txn_abort(txn);
0146         } else {
0147             E(edb_txn_commit(txn));
0148         }
0149     }
0150     free(values);
0151     fprintf(stderr, "Deleted %d values\n", j);
0152 
0153     E(edb_env_stat(env, &mst));
0154     E(edb_txn_begin(env, NULL, EDB_RDONLY, &txn));
0155     E(edb_cursor_open(txn, dbi, &cursor));
0156     fprintf(stderr, "Cursor next\n");
0157     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_NEXT)) == 0) {
0158         fprintf(stderr, "key: %.*s, data: %.*s\n",
0159             (int) key.mv_size,  (char *) key.mv_data,
0160             (int) data.mv_size, (char *) data.mv_data);
0161     }
0162     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0163     fprintf(stderr, "Cursor prev\n");
0164     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_PREV)) == 0) {
0165         fprintf(stderr, "key: %.*s, data: %.*s\n",
0166             (int) key.mv_size,  (char *) key.mv_data,
0167             (int) data.mv_size, (char *) data.mv_data);
0168     }
0169     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0170     edb_cursor_close(cursor);
0171     edb_txn_abort(txn);
0172 
0173     edb_dbi_close(env, dbi);
0174     edb_env_close(env);
0175     return;
0176 }
0177 
0178 /**
0179  * LMDB/EDB tests
0180  * @return
0181  */
0182 TestSuite *ubf_nstd_mtest4(void)
0183 {
0184     TestSuite *suite = create_test_suite();
0185 
0186     add_test(suite, test_nstd_mtest4);
0187             
0188     return suite;
0189 }
0190 
0191