Back to home page

Enduro/X

 
 

    


0001 /* mtest6.c - memory-mapped database tester/toy 
0002  * Test for duplicate keys when doing cursor loop
0003  */
0004 /*
0005  * Copyright 2011-2017 Howard Chu, Symas Corp.
0006  * All rights reserved.
0007  *
0008  * Redistribution and use in source and binary forms, with or without
0009  * modification, are permitted only as authorized by the OpenLDAP
0010  * Public License.
0011  *
0012  * A copy of this license is available in the file LICENSE in the
0013  * top-level directory of the distribution or, alternatively, at
0014  * <http://www.OpenLDAP.org/license.html>.
0015  */
0016 
0017 /* Tests for sorted duplicate DBs */
0018 #include <stdio.h>
0019 #include <stdlib.h>
0020 #include <string.h>
0021 #include <time.h>
0022 #include <cgreen/cgreen.h>
0023 #include <ndebug.h>
0024 #include <edbutil.h>
0025 #include "exdb.h"
0026 
0027 #define E(expr) CHECK((rc = (expr)) == EDB_SUCCESS, #expr)
0028 #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
0029 #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
0030     "%s:%d: %s: %s\n", __FILE__, __LINE__, msg, edb_strerror(rc)), abort()))
0031 
0032 /* have custom sort func */
0033 int sort_data(const EDB_val *a, const EDB_val *b)
0034 {
0035     int ret = strcmp((char *)b->mv_data, (char *)a->mv_data);
0036     
0037     fprintf(stderr, "sort called [%s] vs [%s]=%d\n", (char *)a->mv_data, (char *)b->mv_data, ret);
0038     return ret;
0039 }
0040 
0041 Ensure(test_nstd_mtest6_dupcursor)
0042 {
0043     int i = 0, j = 0, rc;
0044     EDB_env *env;
0045     EDB_dbi dbi;
0046     EDB_val key, data;
0047     EDB_txn *txn;
0048     EDB_stat mst;
0049     EDB_cursor *cursor;
0050     int count=100;
0051     char sval[32];
0052     char kval[sizeof(int)];
0053         char errdet[PATH_MAX];
0054 #define KEY_SIZE    4 /* 3 + EOS */
0055 
0056     memset(sval, 0, sizeof(sval));
0057 
0058         E(ndrx_mdb_unlink("./testdb", errdet, sizeof(errdet), 
0059             LOG_FACILITY_UBF));
0060         
0061     E(edb_env_create(&env));
0062     E(edb_env_set_mapsize(env, 10485760));
0063     E(edb_env_set_maxdbs(env, 4));
0064     E(edb_env_open(env, "./testdb", EDB_FIXEDMAP|EDB_NOSYNC, 0664));
0065 
0066     E(edb_txn_begin(env, NULL, 0, &txn));
0067         
0068         
0069     E(edb_dbi_open(txn, "id2", EDB_CREATE|EDB_DUPSORT, &dbi));
0070     E(edb_set_dupsort(txn, dbi, sort_data));
0071     
0072         
0073     key.mv_size = KEY_SIZE;
0074     key.mv_data = kval;
0075     data.mv_size = sizeof(sval);
0076     data.mv_data = sval;
0077 
0078     fprintf(stderr, "Adding %d values\n", count);
0079     for (i=0;i<count;i++) {
0080             sprintf(kval, "%03d", i);
0081             sprintf(sval, "%03d %03d foo bar", i, i);
0082             RES(0, edb_put(txn, dbi, &key, &data, 0L));
0083     }
0084         
0085         /* Add some random keys */
0086         i=5;
0087         sprintf(kval, "%03d", i);
0088         sprintf(sval, "%03d %03d foo bar", i, 12);
0089         RES(0, edb_put(txn, dbi, &key, &data, 0L));
0090         
0091         
0092         sprintf(sval, "%03d %03d foo bar", i, 10);
0093         RES(0, edb_put(txn, dbi, &key, &data, 0L));
0094                 
0095                 
0096         sprintf(sval, "%03d %03d foo bar", i, 13);
0097         RES(0, edb_put(txn, dbi, &key, &data, 0L));
0098                     
0099         i=16;
0100         sprintf(kval, "%03d", i);
0101         sprintf(sval, "%03d %03d foo bar", i, 17);
0102         RES(0, edb_put(txn, dbi, &key, &data, 0L));
0103         
0104         
0105         i=25;
0106         sprintf(kval, "%03d", i);
0107         sprintf(sval, "%03d %03d foo bar", i, 14);
0108         RES(0, edb_put(txn, dbi, &key, &data, 0L));
0109         
0110         
0111     E(edb_txn_commit(txn));
0112     E(edb_env_stat(env, &mst));
0113 
0114     E(edb_txn_begin(env, NULL, EDB_RDONLY, &txn));
0115         
0116     /* E(edb_set_dupsort(txn, dbi, sort_data)); */
0117         
0118         
0119     E(edb_cursor_open(txn, dbi, &cursor));
0120     while ((rc = edb_cursor_get(cursor, &key, &data, EDB_NEXT)) == 0) {
0121         fprintf(stderr, "key: %p %.*s, data: %p %.*s\n",
0122             key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
0123             data.mv_data, (int) data.mv_size, (char *) data.mv_data);
0124     }
0125         
0126     CHECK(rc == EDB_NOTFOUND, "edb_cursor_get");
0127         
0128         /* get stats... */
0129         E(edb_stat(txn, dbi, &mst));
0130         fprintf(stderr, "keys in db: %d\n", (int)mst.ms_entries);
0131         
0132         /* TODO: get first? */
0133         
0134         
0135     edb_cursor_close(cursor);
0136         
0137         E(edb_cursor_open(txn, dbi, &cursor));
0138         
0139         /* OK fetch the first rec of cursor, next records we shall kill (if any) */
0140         /* first: EDB_FIRST_DUP - this we accept and process */
0141         
0142         sprintf(kval, "%03d", 5);
0143         
0144         key.mv_size = KEY_SIZE;
0145     key.mv_data = kval;
0146         
0147         /* E(edb_get(txn, dbi, &key, &data)); */
0148         
0149         E(edb_cursor_get(cursor, &key, &data, EDB_SET_KEY));
0150         
0151         /* ok, test the data */
0152         if (0!=strcmp("005 013 foo bar", data.mv_data))
0153         {
0154             fprintf(stderr, "expected [005 013 foo bar] got [%s]\n", (char *)data.mv_data);
0155             abort();
0156         }
0157         
0158         /* now check the order.. of others... */
0159         
0160         E(edb_cursor_get(cursor, &key, &data, EDB_NEXT_DUP));
0161         
0162         if (0!=strcmp("005 012 foo bar", data.mv_data))
0163         {
0164             fprintf(stderr, "expected [005 012 foo bar] got [%s]\n", (char *)data.mv_data);
0165             abort();
0166         }
0167         
0168         E(edb_cursor_get(cursor, &key, &data, EDB_NEXT_DUP));
0169         
0170         if (0!=strcmp("005 010 foo bar", data.mv_data))
0171         {
0172             fprintf(stderr, "expected [005 010 foo bar] got [%s]\n", (char *)data.mv_data);
0173             abort();
0174         }
0175         
0176         RES(EDB_NOTFOUND, edb_cursor_get(cursor, &key, &data, EDB_NEXT_DUP));
0177         
0178     edb_txn_abort(txn);
0179 
0180     edb_dbi_close(env, dbi);
0181     edb_env_close(env);
0182     return;
0183 }
0184 
0185 /**
0186  * LMDB/EDB tests
0187  * @return
0188  */
0189     TestSuite *ubf_nstd_mtest6_dupcursor(void)
0190 {
0191     TestSuite *suite = create_test_suite();
0192 
0193     add_test(suite, test_nstd_mtest6_dupcursor);
0194             
0195     return suite;
0196 }
0197 
0198