test/Hash_test.cpp
author Jens Alfke <jens@mooseyard.com>
Sun Sep 20 15:14:12 2009 -0700 (2009-09-20)
changeset 0 31a43d94cc26
permissions -rw-r--r--
First official checkin.
jens@0
     1
/*
jens@0
     2
 *  Hash_test.cpp
jens@0
     3
 *  Ottoman
jens@0
     4
 *
jens@0
     5
 *  Created by Jens Alfke on 9/2/09.
jens@0
     6
 *  Copyright 2009 Jens Alfke. All rights reserved.
jens@0
     7
 *  BSD-Licensed: See the file "LICENSE.txt" for details.
jens@0
     8
 */
jens@0
     9
jens@0
    10
#include <gtest/gtest.h>
jens@0
    11
#include "TestUtils.h"
jens@0
    12
#include "File.h"
jens@0
    13
#include "Hash.h"
jens@0
    14
#include <stdio.h>
jens@0
    15
jens@0
    16
using namespace Mooseyard;
jens@0
    17
jens@0
    18
jens@0
    19
static bool verbose = false;
jens@0
    20
static int num = 100;
jens@0
    21
jens@0
    22
jens@0
    23
#pragma mark -
jens@0
    24
#pragma mark UTILITIES:
jens@0
    25
jens@0
    26
jens@0
    27
char* mkKey (int i) {
jens@0
    28
    static char* sKeys[100];
jens@0
    29
    if (i>=0 && i<100 && sKeys[i] != NULL)
jens@0
    30
        return sKeys[i];
jens@0
    31
    char str[10];
jens@0
    32
    sprintf(str, "%i",i);
jens@0
    33
    char *key = strdup(str);
jens@0
    34
    if (i>=0 && i<100)
jens@0
    35
        sKeys[i] = key;
jens@0
    36
    return key;
jens@0
    37
}
jens@0
    38
jens@0
    39
static char* Insert(Hash &hash, const char* key) {
jens@0
    40
    char string[100];
jens@0
    41
    sprintf(string, "value for %s", key);
jens@0
    42
    if (verbose)
jens@0
    43
        fprintf(stderr, "\nInserting %s -> '%s'\n", key,string);
jens@0
    44
    int count = hash.count();
jens@0
    45
    char *leaf = strdup(string);
jens@0
    46
    
jens@0
    47
    hash.put(key,leaf);
jens@0
    48
    
jens@0
    49
    if (verbose)
jens@0
    50
        hash.dump();
jens@0
    51
    EXPECT_EQ( count+1, hash.count() );
jens@0
    52
    EXPECT_EQ( leaf, hash.get(key) );
jens@0
    53
    return leaf;
jens@0
    54
}
jens@0
    55
jens@0
    56
static char* Insert(Hash &hash, int i) {
jens@0
    57
    return Insert(hash, mkKey(i));
jens@0
    58
}
jens@0
    59
jens@0
    60
static void Remove(Hash &hash, int i) {
jens@0
    61
    char* key = mkKey(i);
jens@0
    62
    char string[100];
jens@0
    63
    sprintf(string, "value for %s", key);
jens@0
    64
    if (verbose)
jens@0
    65
        fprintf(stderr, "\nRemoving %s\n", key);
jens@0
    66
    int count = hash.count();
jens@0
    67
    char *value = (char*) hash.get(key);
jens@0
    68
    EXPECT_TRUE(value!=NULL);
jens@0
    69
    EXPECT_EQ(0, strcmp(value,string));
jens@0
    70
jens@0
    71
    EXPECT_TRUE(hash.remove(key));
jens@0
    72
    
jens@0
    73
    if (verbose)
jens@0
    74
        hash.dump();
jens@0
    75
    EXPECT_EQ( count-1, hash.count() );
jens@0
    76
    EXPECT_EQ( NULL, hash.get(key) );
jens@0
    77
}
jens@0
    78
jens@0
    79
jens@0
    80
jens@0
    81
#pragma mark -
jens@0
    82
#pragma mark TESTS:
jens@0
    83
jens@0
    84
jens@0
    85
TEST(Hash,Simple) {
jens@0
    86
    Hash hash;
jens@0
    87
    hash.dump();
jens@0
    88
    EXPECT_EQ(0, hash.count());
jens@0
    89
    
jens@0
    90
    char *seventeen = Insert(hash, "seventeen");
jens@0
    91
    
jens@0
    92
    EXPECT_EQ(NULL, hash.get("zero"));
jens@0
    93
    EXPECT_EQ(NULL, hash.get("eighteen"));
jens@0
    94
    
jens@0
    95
    char *four = Insert(hash, "four");
jens@0
    96
    EXPECT_EQ(seventeen, hash.get("seventeen"));
jens@0
    97
    
jens@0
    98
    char *zero = Insert(hash, "zero");
jens@0
    99
    char *hundred = Insert(hash, "one hundred");
jens@0
   100
    char *eight = Insert(hash, "eight");
jens@0
   101
    char *twenty = Insert(hash, "twenty");
jens@0
   102
    
jens@0
   103
    EXPECT_EQ(zero, hash.get("zero"));
jens@0
   104
    EXPECT_EQ(four, hash.get("four"));
jens@0
   105
    EXPECT_EQ(eight, hash.get("eight"));
jens@0
   106
    EXPECT_EQ(seventeen, hash.get("seventeen"));
jens@0
   107
    EXPECT_EQ(twenty, hash.get("twenty"));
jens@0
   108
    EXPECT_EQ(hundred, hash.get("one hundred"));
jens@0
   109
    
jens@0
   110
    int i=0;
jens@0
   111
    for (Hash::Iterator iter(&hash); iter; ++iter, ++i) {
jens@0
   112
        Blob key = iter.key();
jens@0
   113
        if (verbose)
jens@0
   114
            fprintf(stderr, "   %*s -> %s\n", 
jens@0
   115
                    (int)key.length,(const char*)key.bytes,
jens@0
   116
                    ((char*)iter.value()));
jens@0
   117
    }
jens@0
   118
    EXPECT_EQ(6, i);
jens@0
   119
}
jens@0
   120
jens@0
   121
TEST(Hash,InsertLotsAtRandom) {
jens@0
   122
    int map[num];
jens@0
   123
    for (int i=0; i<num; i++)
jens@0
   124
        map[i] = i;
jens@0
   125
    shuffle(map,num);
jens@0
   126
    if (verbose) {
jens@0
   127
        for (int i=0; i<num; i++)
jens@0
   128
            fprintf(stderr, "%3d ",map[i]);
jens@0
   129
        fprintf(stderr, "\n");
jens@0
   130
    }
jens@0
   131
    
jens@0
   132
    Hash hash(8);
jens@0
   133
    char* expected[num];
jens@0
   134
    memset(&expected,0,sizeof(expected));
jens@0
   135
    for (int i=0; i<num; i++) {
jens@0
   136
        expected[map[i]] = Insert(hash, map[i]);
jens@0
   137
        for (int j=0; j<num; j++)
jens@0
   138
            EXPECT_EQ(expected[map[j]], hash.get(mkKey(map[j])));
jens@0
   139
    }
jens@0
   140
}
jens@0
   141
jens@0
   142
TEST(Hash,DeleteAtRandom) {
jens@0
   143
    Hash hash;
jens@0
   144
    for (int i=0; i<num; i++)
jens@0
   145
        Insert(hash,i);
jens@0
   146
jens@0
   147
    int map[num];
jens@0
   148
    for (int i=0; i<num; i++)
jens@0
   149
        map[i] = i;
jens@0
   150
    shuffle(map,num);
jens@0
   151
    if (verbose) {
jens@0
   152
        for (int i=0; i<num; i++)
jens@0
   153
            fprintf(stderr, "%3d ",map[i]);
jens@0
   154
        fprintf(stderr, "\n");
jens@0
   155
    }
jens@0
   156
    
jens@0
   157
    for (int i=0; i<num; i++)
jens@0
   158
        Remove(hash,map[i]);
jens@0
   159
}
jens@0
   160
jens@0
   161
TEST(Hash,Words) {
jens@0
   162
    const int kIterations = 3;
jens@0
   163
    readWords();
jens@0
   164
    double totalAdd = 0.0, totalGet = 0.0, totalRemove = 0.0;
jens@0
   165
    for (int iter=0; iter<kIterations; iter++) {
jens@0
   166
        printf("Adding words to Hash...\n");
jens@0
   167
        Hash hash;
jens@0
   168
        {
jens@0
   169
            Timer t("adding");
jens@0
   170
            for( int i=0; i<sNWords; i++)
jens@0
   171
                hash.put(sWords[i], sWords[i]);
jens@0
   172
            EXPECT_EQ(sNWords, hash.count());
jens@0
   173
            totalAdd += t.elapsed();
jens@0
   174
        }        
jens@0
   175
        {
jens@0
   176
            Timer t("getting");
jens@0
   177
            for( int i=0; i<sNWords; i++)
jens@0
   178
                EXPECT_EQ( sWords[i] ,  hash.get(sWords[i]) );
jens@0
   179
            totalGet += t.elapsed();
jens@0
   180
        }        
jens@0
   181
        {
jens@0
   182
            Timer t("removing");
jens@0
   183
            for( int i=0; i<sNWords; i++)
jens@0
   184
                EXPECT_TRUE( hash.remove(sWords[i]) );
jens@0
   185
            totalRemove += t.elapsed();
jens@0
   186
        }        
jens@0
   187
    }
jens@0
   188
    printf("Average put   = %.0lfns\n", totalAdd/kIterations/sNWords*1e9);
jens@0
   189
    printf("Average get   = %.0lfns\n", totalGet/kIterations/sNWords*1e9);
jens@0
   190
    printf("Average remove= %.0lfns\n", totalRemove/kIterations/sNWords*1e9);
jens@0
   191
}
jens@0
   192
jens@0
   193