root/test/class/opal_hash_table.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. validate_table
  2. validate_remove_traversal
  3. test_htable
  4. test_dynamic
  5. test_static
  6. main

   1 /*
   2  * Copyright (c) 2004-2005 The Trustees of Indiana University and Indiana
   3  *                         University Research and Technology
   4  *                         Corporation.  All rights reserved.
   5  * Copyright (c) 2004-2005 The University of Tennessee and The University
   6  *                         of Tennessee Research Foundation.  All rights
   7  *                         reserved.
   8  * Copyright (c) 2004-2005 High Performance Computing Center Stuttgart,
   9  *                         University of Stuttgart.  All rights reserved.
  10  * Copyright (c) 2004-2005 The Regents of the University of California.
  11  *                         All rights reserved.
  12  * Copyright (c) 2008-2014 Cisco Systems, Inc.  All rights reserved.
  13  * Copyright (c) 2014-2015 Hewlett-Packard Development Company, LP.
  14  *                         All rights reserved.
  15  * Copyright (c) 2014-2015 Mellanox Technologies, Inc.
  16  *                         All rights reserved.
  17  * $COPYRIGHT$
  18  *
  19  * Additional copyrights may follow
  20  *
  21  * $HEADER$
  22  */
  23 
  24 #include "opal_config.h"
  25 #include <stdint.h>
  26 #include <string.h>
  27 #include "support.h"
  28 #include "opal/class/opal_object.h"
  29 #include "opal/class/opal_hash_table.h"
  30 #include "opal/runtime/opal.h"
  31 #include "opal/constants.h"
  32 
  33 static FILE *error_out=NULL;
  34 
  35 char *num_keys[] = {
  36     "1234", "1234",
  37     "5678", "5678",
  38     "12450", "12450",
  39     "45623", "45623",
  40     NULL
  41 };
  42 
  43 
  44 char *str_keys[] = {
  45     "foo", "bar",
  46     "2", "this cow jumped over the moon",
  47     "this is another key", "this is another value",
  48     "key key", "value value",
  49     NULL
  50 };
  51 
  52 
  53 char *perm_keys[] = {
  54     "abcdef", "abcdef",
  55     "bcdefa", "bcdefa",
  56     "cdefab", "cdefab",
  57     "defabc", "defabc",
  58     "efabcd", "efabcd",
  59     "fabcde", "fabcde",
  60     "badcfe", "badcfe",
  61     "badcef", "badcef",
  62     "abdcfe", "abdcfe",
  63     "bcdaef", "bcdaef",
  64     NULL
  65 };
  66 
  67 /*
  68  * This data specifically knows about the April'2014 version of hash tables.
  69  * It inserts some keys.
  70  * It inserts some more with a capacity offset to generate collisions.
  71  * Then it checks the table via traversal.
  72  * Then... it removes a key and checks again (via traversal)
  73  * and removes another key and re-checks.
  74  */
  75 static char* remove_keys[] = {
  76     "1", "A", "2", "B", "4", "D", "6", "F", "10", "J", NULL, /* insert as-is: ...AB.D.F...J... */
  77     "2", "b", "4", "d", "5", "e", "3", "c", NULL, /* insert with capacity-offset: ...ABbDdFec.J... */
  78     "ABbDdFecJ",                /* traversal expectation */
  79     "4", "ABbdeFcJ",            /* remove D (...ABbdeFc..J...) then expected traversal */
  80     "2", "AbcdeFJ",             /* remove B (...AbcdeF...J...) then expected traversal */
  81     NULL                        /* end removals and expectations */
  82 };
  83 
  84 typedef union {
  85     uint32_t uvalue;
  86     void *vvalue;
  87 } value_t;
  88 
  89 static void validate_table(opal_hash_table_t *table, char *keys[], int is_numeric_keys)
  90 {
  91     int         j, ret;
  92     value_t value;
  93 
  94     for ( j = 0; keys[j]; j += 2) {
  95         if ( 1 == is_numeric_keys ) {
  96             ret = opal_hash_table_get_value_uint32(table, atoi(keys[j]),
  97                                                    (void**) &value.uvalue);
  98             if (OPAL_SUCCESS != ret) {
  99                 test_failure("opal_hash_table_get_value_uint32 failed");
 100             }
 101         } else {
 102             ret = opal_hash_table_get_value_ptr(table, keys[j],
 103                                                 strlen(keys[j]),
 104                                                 &value.vvalue);
 105             if (OPAL_SUCCESS != ret) {
 106                 test_failure("opal_hash_table_get_value_ptr failed");
 107             }
 108         }
 109         test_verify_str(keys[j+1], value.vvalue);
 110     }
 111     test_verify_int(j/2, opal_hash_table_get_size(table));
 112 }
 113 
 114 static void
 115 validate_remove_traversal(opal_hash_table_t * table, const char * expected_chars)
 116 {
 117     /* all values are single-character strings */
 118     /* expected_chars are those single characters as a string */
 119     const int debug = 0;        /* turn this on if you want to see the details */
 120     int rc, problems = 0;
 121     const char * expected_scanner = expected_chars;
 122     uint32_t key;
 123     void * raw_value;
 124     void * node;
 125     if (debug) {
 126         fprintf(stderr, "debug: expecting '%s' capacity is %d\n",
 127                 expected_chars, (int) table->ht_capacity);
 128     }
 129     for (rc = opal_hash_table_get_first_key_uint32(table, &key, &raw_value, &node);
 130          OPAL_SUCCESS == rc;
 131          rc = opal_hash_table_get_next_key_uint32(table, &key, &raw_value, node, &node)) {
 132         const char * value = (const char *) raw_value;
 133         char expected, actual;
 134         if (debug) {
 135             fprintf(stderr, "key %d (probe at %d) value '%s' excpected_scanner '%s'\n",
 136                     key, (int) (key%table->ht_capacity), value, expected_scanner);
 137         }
 138         if (1 != strlen(value)) {
 139             fprintf(stderr, "key %d's value '%s' is not a one-character string\n", key, value);
 140             problems += 1;
 141             continue;           /* might as well be completely noisy */
 142         }
 143         if ('\0' == *expected_scanner) {
 144             fprintf(stderr, "Found key %d value '%s' but not expected!\n", key, value);
 145             problems += 1;
 146             continue;
 147         }
 148         expected = *expected_scanner++;
 149         actual = *value;
 150         if (actual != expected) {
 151             fprintf(stderr, "Expected '%c' but got '%c'\n", expected, actual);
 152             problems += 1;
 153             continue;
 154         }
 155     }
 156     /* final checks */
 157     if (OPAL_ERROR != rc) {
 158         fprintf(stderr, "table traversal did not end in OPAL_ERROR?!?\n");
 159         problems += 1;
 160     }
 161     if ('\0' != *expected_scanner) {
 162         fprintf(stderr, "Still expecting more key/values: '%s'\n", expected_scanner);
 163         problems += 1;
 164     }
 165 
 166     /* resolution */
 167     if (problems > 0) {
 168         fflush(stderr);
 169         test_failure("validate_remove_traversal");
 170     } else {
 171         test_success();
 172     }
 173 }
 174 
 175 static void test_htable(opal_hash_table_t *table)
 176 {
 177     int j;
 178     fprintf(error_out, "\nTesting integer keys...\n");
 179     for ( j = 0; num_keys[j]; j += 2)
 180     {
 181         opal_hash_table_set_value_uint32(table, atoi(num_keys[j]), num_keys[j+1]);
 182     }
 183     validate_table(table, num_keys, 1);
 184 
 185     /* remove all values for next test */
 186     opal_hash_table_remove_all(table);
 187     test_verify_int(0, opal_hash_table_get_size(table));
 188 
 189     fprintf(error_out, "\nTesting string keys...\n");
 190     for ( j = 0; str_keys[j]; j += 2)
 191     {
 192         opal_hash_table_set_value_ptr(table, str_keys[j], strlen(str_keys[j]), str_keys[j+1]);
 193     }
 194     validate_table(table, str_keys, 0);
 195 
 196     /* remove all values for next test */
 197     opal_hash_table_remove_all(table);
 198     test_verify_int(0, opal_hash_table_get_size(table));
 199 
 200     fprintf(error_out, "\nTesting collision resolution...\n");
 201     /* All of the string keys in keys array should
 202         have the same hash value. */
 203     for ( j = 0; perm_keys[j]; j += 2)
 204     {
 205         opal_hash_table_set_value_ptr(table, perm_keys[j], strlen(perm_keys[j]), perm_keys[j+1]);
 206     }
 207 
 208     validate_table(table, perm_keys, 0);
 209 
 210     /* remove all values for next test */
 211     opal_hash_table_remove_all(table);
 212     test_verify_int(0, opal_hash_table_get_size(table));
 213 
 214     fprintf(error_out, "\nTesting removal and traversal...\n");
 215     j = 0;
 216     char * str;
 217     while (NULL != (str = remove_keys[j++])) {
 218         opal_hash_table_set_value_uint32(table, atoi(str), remove_keys[j++]);
 219     }
 220     while (NULL != (str = remove_keys[j++])) {
 221         /* generate collisions */
 222         opal_hash_table_set_value_uint32(table, atoi(str) + table->ht_capacity, remove_keys[j++]);
 223     }
 224     validate_remove_traversal(table, remove_keys[j++]);
 225     while (NULL != (str = remove_keys[j++])) {
 226         opal_hash_table_remove_value_uint32(table, atoi(str));
 227         validate_remove_traversal(table, remove_keys[j++]);
 228     }
 229 
 230     /* remove all values for next test */
 231     opal_hash_table_remove_all(table);
 232     test_verify_int(0, opal_hash_table_get_size(table));
 233 
 234     fprintf(error_out, "\n\n");
 235 }
 236 
 237 
 238 static void test_dynamic(void)
 239 {
 240     opal_hash_table_t     *table;
 241 
 242     table = OBJ_NEW(opal_hash_table_t);
 243     if ( NULL == table )
 244     {
 245         fprintf(error_out, "Error: Unable to create hash table.\n");
 246         exit(-1);
 247     }
 248     fprintf(error_out, "Testing with dynamically created table...\n");
 249     opal_hash_table_init(table, 4);
 250     test_htable(table);
 251 
 252     OBJ_RELEASE(table);
 253 }
 254 
 255 
 256 static void test_static(void)
 257 {
 258     opal_hash_table_t     table;
 259 
 260     OBJ_CONSTRUCT(&table, opal_hash_table_t);
 261     opal_hash_table_init(&table, 128);
 262 
 263     fprintf(error_out, "Testing with statically created table...\n");
 264     test_htable(&table);
 265 
 266     OBJ_DESTRUCT(&table);
 267 }
 268 
 269 
 270 int main(int argc, char **argv)
 271 {
 272     int rc;
 273 
 274     test_init("opal_hash_table_t");
 275 
 276     rc = opal_init_util(&argc, &argv);
 277     test_verify_int(OPAL_SUCCESS, rc);
 278     if (OPAL_SUCCESS != rc) {
 279         test_finalize();
 280         exit(1);
 281     }
 282 
 283 #ifdef STANDALONE
 284     error_out = stderr;
 285 #else
 286     error_out = fopen( "./opal_hash_table_test_out.txt", "w" );
 287     if( error_out == NULL ) error_out = stderr;
 288 #endif
 289 
 290     test_dynamic();
 291     test_static();
 292 #ifndef STANDALONE
 293     fclose( error_out );
 294 #endif
 295 
 296     opal_finalize_util ();
 297 
 298     return test_finalize();
 299 }

/* [<][>][^][v][top][bottom][index][help] */