parent
b89f8fc9bc
commit
525a2cce91
@ -0,0 +1,183 @@ |
||||
/*
|
||||
chacha-merged.c version 20080118 |
||||
D. J. Bernstein |
||||
Public domain. |
||||
*/ |
||||
|
||||
#include <memory.h> |
||||
#include <stdio.h> |
||||
#include <sys/param.h> |
||||
|
||||
#include "chacha8.h" |
||||
#if 0 |
||||
#include "common/int-util.h" |
||||
#include "warnings.h" |
||||
#endif |
||||
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN |
||||
#define SWAP32LE(x) (x) |
||||
#else |
||||
#define SWAP32LE(x) ((((uint32_t) (x) & 0x000000ff) << 24) | \ |
||||
(((uint32_t) (x) & 0x0000ff00) << 8) | \
|
||||
(((uint32_t) (x) & 0x00ff0000) >> 8) | \
|
||||
(((uint32_t) (x) & 0xff000000) >> 24)) |
||||
#endif |
||||
|
||||
/*
|
||||
* The following macros are used to obtain exact-width results. |
||||
*/ |
||||
#define U8V(v) ((uint8_t)(v) & UINT8_C(0xFF)) |
||||
#define U32V(v) ((uint32_t)(v) & UINT32_C(0xFFFFFFFF)) |
||||
|
||||
/*
|
||||
* The following macros load words from an array of bytes with |
||||
* different types of endianness, and vice versa. |
||||
*/ |
||||
#define U8TO32_LITTLE(p) SWAP32LE(((uint32_t*)(p))[0]) |
||||
#define U32TO8_LITTLE(p, v) (((uint32_t*)(p))[0] = SWAP32LE(v)) |
||||
|
||||
#define ROTATE(v,c) (rol32(v,c)) |
||||
#define XOR(v,w) ((v) ^ (w)) |
||||
#define PLUS(v,w) (U32V((v) + (w))) |
||||
#define PLUSONE(v) (PLUS((v),1)) |
||||
|
||||
#define QUARTERROUND(a,b,c,d) \ |
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a),16); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c),12); \
|
||||
a = PLUS(a,b); d = ROTATE(XOR(d,a), 8); \
|
||||
c = PLUS(c,d); b = ROTATE(XOR(b,c), 7); |
||||
|
||||
static const char sigma[] = "expand 32-byte k"; |
||||
|
||||
static uint32_t rol32(uint32_t x, int r) { |
||||
return (x << (r & 31)) | (x >> (-r & 31)); |
||||
} |
||||
|
||||
void chacha8(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher) { |
||||
uint32_t x0, x1, x2, x3, x4, x5, x6, x7, x8, x9, x10, x11, x12, x13, x14, x15; |
||||
uint32_t j0, j1, j2, j3, j4, j5, j6, j7, j8, j9, j10, j11, j12, j13, j14, j15; |
||||
char* ctarget = 0; |
||||
char tmp[64]; |
||||
int i; |
||||
|
||||
if (!length) return; |
||||
|
||||
j0 = U8TO32_LITTLE(sigma + 0); |
||||
j1 = U8TO32_LITTLE(sigma + 4); |
||||
j2 = U8TO32_LITTLE(sigma + 8); |
||||
j3 = U8TO32_LITTLE(sigma + 12); |
||||
j4 = U8TO32_LITTLE(key + 0); |
||||
j5 = U8TO32_LITTLE(key + 4); |
||||
j6 = U8TO32_LITTLE(key + 8); |
||||
j7 = U8TO32_LITTLE(key + 12); |
||||
j8 = U8TO32_LITTLE(key + 16); |
||||
j9 = U8TO32_LITTLE(key + 20); |
||||
j10 = U8TO32_LITTLE(key + 24); |
||||
j11 = U8TO32_LITTLE(key + 28); |
||||
j12 = 0; |
||||
j13 = 0; |
||||
j14 = U8TO32_LITTLE(iv + 0); |
||||
j15 = U8TO32_LITTLE(iv + 4); |
||||
|
||||
for (;;) { |
||||
if (length < 64) { |
||||
memcpy(tmp, data, length); |
||||
data = tmp; |
||||
ctarget = cipher; |
||||
cipher = tmp; |
||||
} |
||||
x0 = j0; |
||||
x1 = j1; |
||||
x2 = j2; |
||||
x3 = j3; |
||||
x4 = j4; |
||||
x5 = j5; |
||||
x6 = j6; |
||||
x7 = j7; |
||||
x8 = j8; |
||||
x9 = j9; |
||||
x10 = j10; |
||||
x11 = j11; |
||||
x12 = j12; |
||||
x13 = j13; |
||||
x14 = j14; |
||||
x15 = j15; |
||||
for (i = 8;i > 0;i -= 2) { |
||||
QUARTERROUND( x0, x4, x8,x12) |
||||
QUARTERROUND( x1, x5, x9,x13) |
||||
QUARTERROUND( x2, x6,x10,x14) |
||||
QUARTERROUND( x3, x7,x11,x15) |
||||
QUARTERROUND( x0, x5,x10,x15) |
||||
QUARTERROUND( x1, x6,x11,x12) |
||||
QUARTERROUND( x2, x7, x8,x13) |
||||
QUARTERROUND( x3, x4, x9,x14) |
||||
} |
||||
x0 = PLUS( x0, j0); |
||||
x1 = PLUS( x1, j1); |
||||
x2 = PLUS( x2, j2); |
||||
x3 = PLUS( x3, j3); |
||||
x4 = PLUS( x4, j4); |
||||
x5 = PLUS( x5, j5); |
||||
x6 = PLUS( x6, j6); |
||||
x7 = PLUS( x7, j7); |
||||
x8 = PLUS( x8, j8); |
||||
x9 = PLUS( x9, j9); |
||||
x10 = PLUS(x10,j10); |
||||
x11 = PLUS(x11,j11); |
||||
x12 = PLUS(x12,j12); |
||||
x13 = PLUS(x13,j13); |
||||
x14 = PLUS(x14,j14); |
||||
x15 = PLUS(x15,j15); |
||||
|
||||
x0 = XOR( x0,U8TO32_LITTLE((uint8_t*)data + 0)); |
||||
x1 = XOR( x1,U8TO32_LITTLE((uint8_t*)data + 4)); |
||||
x2 = XOR( x2,U8TO32_LITTLE((uint8_t*)data + 8)); |
||||
x3 = XOR( x3,U8TO32_LITTLE((uint8_t*)data + 12)); |
||||
x4 = XOR( x4,U8TO32_LITTLE((uint8_t*)data + 16)); |
||||
x5 = XOR( x5,U8TO32_LITTLE((uint8_t*)data + 20)); |
||||
x6 = XOR( x6,U8TO32_LITTLE((uint8_t*)data + 24)); |
||||
x7 = XOR( x7,U8TO32_LITTLE((uint8_t*)data + 28)); |
||||
x8 = XOR( x8,U8TO32_LITTLE((uint8_t*)data + 32)); |
||||
x9 = XOR( x9,U8TO32_LITTLE((uint8_t*)data + 36)); |
||||
x10 = XOR(x10,U8TO32_LITTLE((uint8_t*)data + 40)); |
||||
x11 = XOR(x11,U8TO32_LITTLE((uint8_t*)data + 44)); |
||||
x12 = XOR(x12,U8TO32_LITTLE((uint8_t*)data + 48)); |
||||
x13 = XOR(x13,U8TO32_LITTLE((uint8_t*)data + 52)); |
||||
x14 = XOR(x14,U8TO32_LITTLE((uint8_t*)data + 56)); |
||||
x15 = XOR(x15,U8TO32_LITTLE((uint8_t*)data + 60)); |
||||
|
||||
j12 = PLUSONE(j12); |
||||
if (!j12) |
||||
{ |
||||
j13 = PLUSONE(j13); |
||||
/* stopping at 2^70 bytes per iv is user's responsibility */ |
||||
} |
||||
|
||||
U32TO8_LITTLE(cipher + 0,x0); |
||||
U32TO8_LITTLE(cipher + 4,x1); |
||||
U32TO8_LITTLE(cipher + 8,x2); |
||||
U32TO8_LITTLE(cipher + 12,x3); |
||||
U32TO8_LITTLE(cipher + 16,x4); |
||||
U32TO8_LITTLE(cipher + 20,x5); |
||||
U32TO8_LITTLE(cipher + 24,x6); |
||||
U32TO8_LITTLE(cipher + 28,x7); |
||||
U32TO8_LITTLE(cipher + 32,x8); |
||||
U32TO8_LITTLE(cipher + 36,x9); |
||||
U32TO8_LITTLE(cipher + 40,x10); |
||||
U32TO8_LITTLE(cipher + 44,x11); |
||||
U32TO8_LITTLE(cipher + 48,x12); |
||||
U32TO8_LITTLE(cipher + 52,x13); |
||||
U32TO8_LITTLE(cipher + 56,x14); |
||||
U32TO8_LITTLE(cipher + 60,x15); |
||||
|
||||
if (length <= 64) { |
||||
if (length < 64) { |
||||
memcpy(ctarget, cipher, length); |
||||
} |
||||
return; |
||||
} |
||||
length -= 64; |
||||
cipher += 64; |
||||
data = (uint8_t*)data + 64; |
||||
} |
||||
} |
@ -0,0 +1,8 @@ |
||||
#include <stdint.h> |
||||
#include <stddef.h> |
||||
|
||||
#define CHACHA8_KEY_SIZE 32 |
||||
#define CHACHA8_IV_SIZE 8 |
||||
|
||||
void chacha8(const void* data, size_t length, const uint8_t* key, const uint8_t* iv, char* cipher); |
||||
|
@ -0,0 +1,192 @@ |
||||
/* mtest_enc.c - memory-mapped database tester/toy with encryption */ |
||||
/*
|
||||
* Copyright 2011-2017 Howard Chu, Symas Corp. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted only as authorized by the Symas |
||||
* Dual-Use License. |
||||
* |
||||
* A copy of this license is available in the file LICENSE in the |
||||
* source distribution. |
||||
*/ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <time.h> |
||||
#include "lmdb.h" |
||||
#include "chacha8.h" |
||||
|
||||
#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) |
||||
#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) |
||||
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ |
||||
"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) |
||||
|
||||
static void encfunc(const MDB_val *src, MDB_val *dst, const MDB_val *key, int encdec) |
||||
{ |
||||
chacha8(src->mv_data, src->mv_size, key[0].mv_data, key[1].mv_data, dst->mv_data); |
||||
} |
||||
|
||||
int main(int argc,char * argv[]) |
||||
{ |
||||
int i = 0, j = 0, rc; |
||||
MDB_env *env; |
||||
MDB_dbi dbi; |
||||
MDB_val key, data; |
||||
MDB_txn *txn; |
||||
MDB_stat mst; |
||||
MDB_cursor *cursor, *cur2; |
||||
MDB_cursor_op op; |
||||
MDB_val enckey[2]; |
||||
int count; |
||||
int *values; |
||||
char sval[32] = ""; |
||||
char eiv[] = {3, 1, 4, 1, 5, 9, 2, 6}; |
||||
char ekey[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, |
||||
17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32}; |
||||
|
||||
srand(time(NULL)); |
||||
|
||||
count = (rand()%384) + 64; |
||||
values = (int *)malloc(count*sizeof(int)); |
||||
|
||||
for(i = 0;i<count;i++) { |
||||
values[i] = rand()%1024; |
||||
} |
||||
|
||||
enckey[0].mv_data = ekey; |
||||
enckey[0].mv_size = sizeof(ekey); |
||||
enckey[1].mv_data = eiv; |
||||
enckey[1].mv_size = sizeof(eiv); |
||||
|
||||
E(mdb_env_create(&env)); |
||||
E(mdb_env_set_maxreaders(env, 1)); |
||||
E(mdb_env_set_mapsize(env, 10485760)); |
||||
E(mdb_env_set_encrypt(env, encfunc, enckey)); |
||||
E(mdb_env_open(env, "./testdb", 0 /*|MDB_NOSYNC*/, 0664)); |
||||
|
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
E(mdb_dbi_open(txn, NULL, 0, &dbi)); |
||||
|
||||
key.mv_size = sizeof(int); |
||||
key.mv_data = sval; |
||||
|
||||
printf("Adding %d values\n", count); |
||||
for (i=0;i<count;i++) {
|
||||
sprintf(sval, "%03x %d foo bar", values[i], values[i]); |
||||
/* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */ |
||||
data.mv_size = sizeof(sval); |
||||
data.mv_data = sval; |
||||
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) { |
||||
j++; |
||||
data.mv_size = sizeof(sval); |
||||
data.mv_data = sval; |
||||
} |
||||
} |
||||
if (j) printf("%d duplicates skipped\n", j); |
||||
E(mdb_txn_commit(txn)); |
||||
E(mdb_env_stat(env, &mst)); |
||||
|
||||
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||
mdb_cursor_close(cursor); |
||||
mdb_txn_abort(txn); |
||||
|
||||
j=0; |
||||
key.mv_data = sval; |
||||
for (i= count - 1; i > -1; i-= (rand()%5)) { |
||||
j++; |
||||
txn=NULL; |
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
sprintf(sval, "%03x ", values[i]); |
||||
if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) { |
||||
j--; |
||||
mdb_txn_abort(txn); |
||||
} else { |
||||
E(mdb_txn_commit(txn)); |
||||
} |
||||
} |
||||
free(values); |
||||
printf("Deleted %d values\n", j); |
||||
|
||||
E(mdb_env_stat(env, &mst)); |
||||
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||
printf("Cursor next\n"); |
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||
printf("Cursor last\n"); |
||||
E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
printf("Cursor prev\n"); |
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||
printf("Cursor last/prev\n"); |
||||
E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
E(mdb_cursor_get(cursor, &key, &data, MDB_PREV)); |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
|
||||
mdb_cursor_close(cursor); |
||||
mdb_txn_abort(txn); |
||||
|
||||
printf("Deleting with cursor\n"); |
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cur2)); |
||||
for (i=0; i<50; i++) { |
||||
if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT))) |
||||
break; |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
E(mdb_del(txn, dbi, &key, NULL)); |
||||
} |
||||
|
||||
printf("Restarting cursor in txn\n"); |
||||
for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { |
||||
if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op))) |
||||
break; |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
mdb_cursor_close(cur2); |
||||
E(mdb_txn_commit(txn)); |
||||
|
||||
printf("Restarting cursor outside txn\n"); |
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||
for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { |
||||
if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op))) |
||||
break; |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
mdb_cursor_close(cursor); |
||||
mdb_txn_abort(txn); |
||||
|
||||
mdb_dbi_close(env, dbi); |
||||
mdb_env_close(env); |
||||
|
||||
return 0; |
||||
} |
@ -0,0 +1,177 @@ |
||||
/* mtest_remap.c - memory-mapped database tester/toy with page remapping */ |
||||
/*
|
||||
* Copyright 2011-2017 Howard Chu, Symas Corp. |
||||
* All rights reserved. |
||||
* |
||||
* Redistribution and use in source and binary forms, with or without |
||||
* modification, are permitted only as authorized by the Symas |
||||
* Dual-Use License. |
||||
* |
||||
* A copy of this license is available in the file LICENSE in the |
||||
* source distribution. |
||||
*/ |
||||
#include <stdio.h> |
||||
#include <stdlib.h> |
||||
#include <time.h> |
||||
#include "lmdb.h" |
||||
#include "chacha8.h" |
||||
|
||||
#define E(expr) CHECK((rc = (expr)) == MDB_SUCCESS, #expr) |
||||
#define RES(err, expr) ((rc = expr) == (err) || (CHECK(!rc, #expr), 0)) |
||||
#define CHECK(test, msg) ((test) ? (void)0 : ((void)fprintf(stderr, \ |
||||
"%s:%d: %s: %s\n", __FILE__, __LINE__, msg, mdb_strerror(rc)), abort())) |
||||
|
||||
int main(int argc,char * argv[]) |
||||
{ |
||||
int i = 0, j = 0, rc; |
||||
MDB_env *env; |
||||
MDB_dbi dbi; |
||||
MDB_val key, data; |
||||
MDB_txn *txn; |
||||
MDB_stat mst; |
||||
MDB_cursor *cursor, *cur2; |
||||
MDB_cursor_op op; |
||||
int count; |
||||
int *values; |
||||
char sval[32] = ""; |
||||
|
||||
srand(time(NULL)); |
||||
|
||||
count = (rand()%384) + 64; |
||||
values = (int *)malloc(count*sizeof(int)); |
||||
|
||||
for(i = 0;i<count;i++) { |
||||
values[i] = rand()%1024; |
||||
} |
||||
|
||||
E(mdb_env_create(&env)); |
||||
E(mdb_env_set_maxreaders(env, 1)); |
||||
E(mdb_env_set_mapsize(env, 10485760)); |
||||
E(mdb_env_open(env, "./testdb", MDB_REMAP_CHUNKS /*|MDB_NOSYNC*/, 0664)); |
||||
|
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
E(mdb_dbi_open(txn, NULL, 0, &dbi)); |
||||
|
||||
key.mv_size = sizeof(int); |
||||
key.mv_data = sval; |
||||
|
||||
printf("Adding %d values\n", count); |
||||
for (i=0;i<count;i++) {
|
||||
sprintf(sval, "%03x %d foo bar", values[i], values[i]); |
||||
/* Set <data> in each iteration, since MDB_NOOVERWRITE may modify it */ |
||||
data.mv_size = sizeof(sval); |
||||
data.mv_data = sval; |
||||
if (RES(MDB_KEYEXIST, mdb_put(txn, dbi, &key, &data, MDB_NOOVERWRITE))) { |
||||
j++; |
||||
data.mv_size = sizeof(sval); |
||||
data.mv_data = sval; |
||||
} |
||||
} |
||||
if (j) printf("%d duplicates skipped\n", j); |
||||
E(mdb_txn_commit(txn)); |
||||
E(mdb_env_stat(env, &mst)); |
||||
|
||||
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||
mdb_cursor_close(cursor); |
||||
mdb_txn_abort(txn); |
||||
|
||||
j=0; |
||||
key.mv_data = sval; |
||||
for (i= count - 1; i > -1; i-= (rand()%5)) { |
||||
j++; |
||||
txn=NULL; |
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
sprintf(sval, "%03x ", values[i]); |
||||
if (RES(MDB_NOTFOUND, mdb_del(txn, dbi, &key, NULL))) { |
||||
j--; |
||||
mdb_txn_abort(txn); |
||||
} else { |
||||
E(mdb_txn_commit(txn)); |
||||
} |
||||
} |
||||
free(values); |
||||
printf("Deleted %d values\n", j); |
||||
|
||||
E(mdb_env_stat(env, &mst)); |
||||
E(mdb_txn_begin(env, NULL, MDB_RDONLY, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||
printf("Cursor next\n"); |
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_NEXT)) == 0) { |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||
printf("Cursor last\n"); |
||||
E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
printf("Cursor prev\n"); |
||||
while ((rc = mdb_cursor_get(cursor, &key, &data, MDB_PREV)) == 0) { |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
CHECK(rc == MDB_NOTFOUND, "mdb_cursor_get"); |
||||
printf("Cursor last/prev\n"); |
||||
E(mdb_cursor_get(cursor, &key, &data, MDB_LAST)); |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
E(mdb_cursor_get(cursor, &key, &data, MDB_PREV)); |
||||
printf("key: %.*s, data: %.*s\n", |
||||
(int) key.mv_size, (char *) key.mv_data, |
||||
(int) data.mv_size, (char *) data.mv_data); |
||||
|
||||
mdb_cursor_close(cursor); |
||||
mdb_txn_abort(txn); |
||||
|
||||
printf("Deleting with cursor\n"); |
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cur2)); |
||||
for (i=0; i<50; i++) { |
||||
if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, MDB_NEXT))) |
||||
break; |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
E(mdb_del(txn, dbi, &key, NULL)); |
||||
} |
||||
|
||||
printf("Restarting cursor in txn\n"); |
||||
for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { |
||||
if (RES(MDB_NOTFOUND, mdb_cursor_get(cur2, &key, &data, op))) |
||||
break; |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
mdb_cursor_close(cur2); |
||||
E(mdb_txn_commit(txn)); |
||||
|
||||
printf("Restarting cursor outside txn\n"); |
||||
E(mdb_txn_begin(env, NULL, 0, &txn)); |
||||
E(mdb_cursor_open(txn, dbi, &cursor)); |
||||
for (op=MDB_FIRST, i=0; i<=32; op=MDB_NEXT, i++) { |
||||
if (RES(MDB_NOTFOUND, mdb_cursor_get(cursor, &key, &data, op))) |
||||
break; |
||||
printf("key: %p %.*s, data: %p %.*s\n", |
||||
key.mv_data, (int) key.mv_size, (char *) key.mv_data, |
||||
data.mv_data, (int) data.mv_size, (char *) data.mv_data); |
||||
} |
||||
mdb_cursor_close(cursor); |
||||
mdb_txn_abort(txn); |
||||
|
||||
mdb_dbi_close(env, dbi); |
||||
mdb_env_close(env); |
||||
|
||||
return 0; |
||||
} |
Loading…
Reference in new issue