nostrdb

an unfairly fast embedded nostr database backed by lmdb
git clone git://jb55.com/nostrdb
Log | Files | Refs | Submodules | README | LICENSE

mtest.c (5552B)


      1 /* mtest.c - memory-mapped database tester/toy */
      2 /*
      3  * Copyright 2011-2021 Howard Chu, Symas Corp.
      4  * All rights reserved.
      5  *
      6  * Redistribution and use in source and binary forms, with or without
      7  * modification, are permitted only as authorized by the OpenLDAP
      8  * Public License.
      9  *
     10  * A copy of this license is available in the file LICENSE in the
     11  * top-level directory of the distribution or, alternatively, at
     12  * <http://www.OpenLDAP.org/license.html>.
     13  */
     14 #include <stdio.h>
     15 #include <stdlib.h>
     16 #include <time.h>
     17 #include "lmdb.h"
     18 
     19 #define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr)
     20 #define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0))
     21 #define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \
     22 	"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort()))
     23 
     24 int main(int argc,char * argv[])
     25 {
     26 	int i = 0, j = 0, rc;
     27 	MDB_env *env;
     28 	MDB_dbi dbi;
     29 	MDB_val key, data;
     30 	MDB_txn *txn;
     31 	MDB_stat mst;
     32 	MDB_cursor *cursor, *cur2;
     33 	MDB_cursor_op op;
     34 	int count;
     35 	int *values;
     36 	char sval[32] = "";
     37 
     38 	srand(time(NULL));
     39 
     40 	    count = (rand()%384) + 64;
     41 	    values = (int *)malloc(count*sizeof(int));
     42 
     43 	    for(i = 0;i<count;i++) {
     44 			values[i] = rand()%1024;
     45 	    }
     46     
     47 		E(mdb_env_create(&env));
     48 		E(mdb_env_set_maxreaders(env, 1));
     49 		E(mdb_env_set_mapsize(env, 10485760));
     50 		E(mdb_env_open(env, "./testdb", MDB_FIXEDMAP /*|MDB_NOSYNC*/, 0664));
     51 
     52 		E(mdb_txn_begin(env, NULL, 0, &txn));
     53 		E(mdb_dbi_open(txn, NULL, 0, &dbi));
     54    
     55 		key.mv_size = sizeof(int);
     56 		key.mv_data = sval;
     57 
     58 		printf("Adding %d values\n", count);
     59 	    for (i=0;i<count;i++) {	
     60 			sprintf(sval, "%03x %d foo bar", values[i], values[i]);
     61 			/* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */
     62 			data.mv_size = sizeof(sval);
     63 			data.mv_data = sval;
     64 			if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) {
     65 				j++;
     66 				data.mv_size = sizeof(sval);
     67 				data.mv_data = sval;
     68 			}
     69 	    }
     70 		if (j) printf("%d duplicates skipped\n", j);
     71 		E(mdb_txn_commit(txn));
     72 		E(mdb_env_stat(env, &mst));
     73 
     74 		E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
     75 		E(mdb_cursor_open(txn, dbi, &cursor));
     76 		while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
     77 			printf("key: %p %.*s, data: %p %.*s\n",
     78 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
     79 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
     80 		}
     81 		CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
     82 		mdb_cursor_close(cursor);
     83 		mdb_txn_abort(txn);
     84 
     85 		j=0;
     86 		key.mv_data = sval;
     87 	    for (i= count - 1; i > -1; i-= (rand()%5)) {
     88 			j++;
     89 			txn=NULL;
     90 			E(mdb_txn_begin(env, NULL, 0, &txn));
     91 			sprintf(sval, "%03x ", values[i]);
     92 			if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) {
     93 				j--;
     94 				mdb_txn_abort(txn);
     95 			} else {
     96 				E(mdb_txn_commit(txn));
     97 			}
     98 	    }
     99 	    free(values);
    100 		printf("Deleted %d values\n", j);
    101 
    102 		E(mdb_env_stat(env, &mst));
    103 		E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn));
    104 		E(mdb_cursor_open(txn, dbi, &cursor));
    105 		printf("Cursor next\n");
    106 		while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) {
    107 			printf("key: %.*s, data: %.*s\n",
    108 				(int) key.mv_size,  (char *) key.mv_data,
    109 				(int) data.mv_size, (char *) data.mv_data);
    110 		}
    111 		CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
    112 		printf("Cursor last\n");
    113 		E(mdb_cursor_get(cursor, &key, &data, MDB_LAST));
    114 		printf("key: %.*s, data: %.*s\n",
    115 			(int) key.mv_size,  (char *) key.mv_data,
    116 			(int) data.mv_size, (char *) data.mv_data);
    117 		printf("Cursor prev\n");
    118 		while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) {
    119 			printf("key: %.*s, data: %.*s\n",
    120 				(int) key.mv_size,  (char *) key.mv_data,
    121 				(int) data.mv_size, (char *) data.mv_data);
    122 		}
    123 		CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get");
    124 		printf("Cursor last/prev\n");
    125 		E(mdb_cursor_get(cursor, &key, &data, MDB_LAST));
    126 			printf("key: %.*s, data: %.*s\n",
    127 				(int) key.mv_size,  (char *) key.mv_data,
    128 				(int) data.mv_size, (char *) data.mv_data);
    129 		E(mdb_cursor_get(cursor, &key, &data, MDB_PREV));
    130 			printf("key: %.*s, data: %.*s\n",
    131 				(int) key.mv_size,  (char *) key.mv_data,
    132 				(int) data.mv_size, (char *) data.mv_data);
    133 
    134 		mdb_cursor_close(cursor);
    135 		mdb_txn_abort(txn);
    136 
    137 		printf("Deleting with cursor\n");
    138 		E(mdb_txn_begin(env, NULL, 0, &txn));
    139 		E(mdb_cursor_open(txn, dbi, &cur2));
    140 		for (i=0; i<50; i++) {
    141 			if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT)))
    142 				break;
    143 			printf("key: %p %.*s, data: %p %.*s\n",
    144 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
    145 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
    146 			E(mdb_del(txn, dbi, &key, NULL));
    147 		}
    148 
    149 		printf("Restarting cursor in txn\n");
    150 		for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) {
    151 			if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op)))
    152 				break;
    153 			printf("key: %p %.*s, data: %p %.*s\n",
    154 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
    155 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
    156 		}
    157 		mdb_cursor_close(cur2);
    158 		E(mdb_txn_commit(txn));
    159 
    160 		printf("Restarting cursor outside txn\n");
    161 		E(mdb_txn_begin(env, NULL, 0, &txn));
    162 		E(mdb_cursor_open(txn, dbi, &cursor));
    163 		for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) {
    164 			if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op)))
    165 				break;
    166 			printf("key: %p %.*s, data: %p %.*s\n",
    167 				key.mv_data,  (int) key.mv_size,  (char *) key.mv_data,
    168 				data.mv_data, (int) data.mv_size, (char *) data.mv_data);
    169 		}
    170 		mdb_cursor_close(cursor);
    171 		mdb_txn_abort(txn);
    172 
    173 		mdb_dbi_close(env, dbi);
    174 		mdb_env_close(env);
    175 
    176 	return 0;
    177 }