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