test_zero_length_keys.c 4.34 KB
Newer Older
1 2 3 4 5 6 7
/* -*- mode: C; c-basic-offset: 4 -*- */
#ident "Copyright (c) 2007 Tokutek Inc.  All rights reserved."

#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include <unistd.h>
8
#include <memory.h>
9
#include <sys/stat.h>
10
#include <toku_portability.h>
11 12 13
#include <db.h>

#include "test.h"
14 15
#ifndef ENVDIR
#define ENVDIR "./test.dir"
16 17
#endif

18 19
static void
walk (DB *db) {
20 21 22 23 24 25 26 27 28 29 30 31 32
    int r;
    DB_TXN * const null_txn = 0;

    DBC *cursor;
    r = db->cursor(db, null_txn, &cursor, 0); assert(r == 0);

    DBT key; memset(&key, 0, sizeof key); key.flags = DB_DBT_REALLOC;
    DBT val; memset(&val, 0, sizeof val); val.flags = DB_DBT_REALLOC;
    int i;
    for (i=0; ; i++) {
        r = cursor->c_get(cursor, &key, &val, DB_NEXT);
        if (r != 0) 
            break;
33
        if (verbose) printf("%d %u %u\n", i, key.size, val.size);
34 35 36 37 38
        if (i == 0) assert(key.size == 0);
    }
    assert(i != 0);
    r = cursor->c_close(cursor); assert(r == 0);

39 40
    if (key.data) toku_free(key.data);
    if (val.data) toku_free(val.data);
41 42
}

43 44
static void
test_insert_zero_length (int n, int dup_mode, const char *dbname) {
45 46 47 48 49 50 51
    if (verbose) printf("test_insert_zero_length:%d %d\n", n, dup_mode);

    DB_ENV * const null_env = 0;
    DB *db;
    DB_TXN * const null_txn = 0;
    int r;

52 53
    char fname[strlen(ENVDIR) + strlen("/") + strlen(dbname) + 1];
    sprintf(fname, "%s/%s", ENVDIR, dbname);
Rich Prohaska's avatar
Rich Prohaska committed
54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73
    unlink(fname);

    /* create the dup database file */
    r = db_create(&db, null_env, 0); assert(r == 0);
    r = db->set_flags(db, dup_mode); assert(r == 0);
    r = db->set_pagesize(db, 4096); assert(r == 0);
    r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); assert(r == 0);

    int i;
    for (i=0; i<n; i++) {
        char k[n]; memset(k, i, n);
        char v[n]; memset(v, i, n);
        DBT key;
        DBT val;
        r = db->put(db, null_txn, dbt_init(&key, &k, i), dbt_init(&val, &v, i), 0);
        if (r != 0) {
            if (verbose) printf("db->put %d %d = %d\n", n, n, r);
            assert(r == 0);
        }
74 75 76 77 78 79 80 81
        if (i == 0) {
            dbt_init(&key, &k, i);
            memset(&val, 0, sizeof val);
            r = db->get(db, null_txn, &key, &val, 0);
            assert(r == 0 && val.data == 0 && val.size == 0);

            r = db->get(db, null_txn, &key, dbt_init_malloc(&val), 0);
            assert(r == 0 && val.data != 0 && val.size == 0);
82
            toku_free(val.data);
83 84 85 86 87 88 89 90

            memset(&key, 0, sizeof key);
            memset(&val, 0, sizeof val);
            r = db->get(db, null_txn, &key, &val, 0);
            assert(r == 0 && val.data == 0 && val.size == 0);

            r = db->get(db, null_txn, &key, dbt_init_malloc(&val), 0);
            assert(r == 0 && val.data != 0 && val.size == 0);
91
            toku_free(val.data);
92
        }
93 94 95 96 97 98 99
    }

    walk(db);

    r = db->close(db, 0); assert(r == 0);
}

100 101
static void
test_insert_zero_length_keys (int n, int dup_mode, const char *dbname) {
102 103 104 105 106 107 108
    if (verbose) printf("test_insert_zero_length_keys:%d %d\n", n, dup_mode);

    DB_ENV * const null_env = 0;
    DB *db;
    DB_TXN * const null_txn = 0;
    int r;

109 110
    char fname[strlen(ENVDIR) + strlen("/") + strlen(dbname) + 1];
    sprintf(fname, "%s/%s", ENVDIR, dbname);
Rich Prohaska's avatar
Rich Prohaska committed
111

112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137
    unlink(fname);

    /* create the dup database file */
    r = db_create(&db, null_env, 0); assert(r == 0);
    r = db->set_flags(db, dup_mode); assert(r == 0);
    r = db->set_pagesize(db, 4096); assert(r == 0);
    r = db->open(db, null_txn, fname, "main", DB_BTREE, DB_CREATE, 0666); assert(r == 0);

    int i;
    for (i=0; i<n; i++) {
        char k[n]; memset(k, i, n);
        char v[n]; memset(v, i, n);
        DBT key;
        DBT val;
        r = db->put(db, null_txn, dbt_init(&key, &k, 0), dbt_init(&val, &v, i), DB_YESOVERWRITE);
        if (r != 0) {
            if (verbose) printf("db->put %d %d = %d\n", n, n, r);
            assert(r == 0);
        }
    }

    walk(db);

    r = db->close(db, 0); assert(r == 0);
}

Yoni Fogel's avatar
Yoni Fogel committed
138 139
int
test_main(int argc, const char *argv[]) {
140 141 142

    parse_args(argc, argv);
  
143 144 145 146
#define TFILE __FILE__ ".tktrace"
    unlink(TFILE);
    SET_TRACE_FILE(TFILE);

147
    system("rm -rf " ENVDIR);
148
    toku_os_mkdir(ENVDIR, S_IRWXU+S_IRWXG+S_IRWXO);
149

Rich Prohaska's avatar
Rich Prohaska committed
150 151 152
    test_insert_zero_length(32, 0, "test0");
    test_insert_zero_length_keys(32, 0, "test0keys");
    test_insert_zero_length_keys(32, DB_DUP+DB_DUPSORT, "test0keys_dupsort");
153

154 155
    CLOSE_TRACE_FILE();

156 157
    return 0;
}