t_stringtab.cpp

Go to the documentation of this file.
00001 /*****************************************************************************\
00002 *                                                                             *
00003 *  Name   : test_string_table                                                 *
00004 *  Author : Chris Koeritz                                                     *
00005 *                                                                             *
00006 *******************************************************************************
00007 * Copyright (c) 1994-$now By Author.  This program is free software; you can  *
00008 * redistribute it and/or modify it under the terms of the GNU General Public  *
00009 * License as published by the Free Software Foundation; either version 2 of   *
00010 * the License or (at your option) any later version.  This is online at:      *
00011 *     http://www.fsf.org/copyleft/gpl.html                                    *
00012 * Please send any updates to: fred@gruntose.com                               *
00013 \*****************************************************************************/
00014 
00015 #include <basis/byte_array.h>
00016 #include <basis/guards.h>
00017 #include <basis/istring.h>
00018 #include <data_struct/matrix.cpp>
00019 #include <data_struct/string_table.h>
00020 #include <mechanisms/time_stamp.h>
00021 #include <loggers/console_logger.h>
00022 #include <data_struct/static_memory_gremlin.h>
00023 #include <textual/string_manipulation.h>
00024 
00025 #include <stdio.h>
00026 #include <stdlib.h>
00027 
00028 //#define DEBUG_SYMBOL_TABLE
00029   // uncomment for noisy version.
00030 
00031 //#define TEST_SIZE_TABLE
00032   // uncomment for testing of the size of a string_table.
00033 
00034 //#define OLD_TEST
00035   // uncomment for the older version of symbol table.
00036 
00037 using namespace basis;  // pull in the auto compare functions.
00038 
00039 const int test_iterations = 100;
00040 
00041 const int FIND_ITERATIONS = 100;
00042 const int MAXIMUM_RANDOM_ADDS = 200;
00043 
00044 const int TEST_SIZE_TABLE_COUNT = 10000;
00045   // the number of string_table elements we create for checking how
00046   // big one of them is.
00047 
00048 console_logger out;
00049 
00050 #define LOG(to_print) { out.log(to_print); }
00051 
00052 HOOPLE_STARTUP_CODE;
00053 
00054 #define WHERE __WHERE__.s()
00055 
00056 double time_in_add = 0;
00057 double time_in_find = 0;
00058 double time_in_pack = 0;
00059 double time_in_unpack = 0;
00060 u_int operations = 0;
00061 
00062 void ADD(string_table &syms, const istring &name, const istring &to_add)
00063 {
00064   time_stamp start;
00065   outcome added = syms.add(name, to_add);
00066   operations++;
00067   if (added == common::EXISTING)
00068     deadly_error(WHERE, "ADD", "already in table");
00069   time_stamp end;
00070   time_in_add += end.value() - start.value();
00071 }
00072 
00073 void FIND(const string_table &syms, const istring &name, const istring &to_find)
00074 {
00075   for (int i = 0; i < FIND_ITERATIONS; i++) {
00076     time_stamp start;
00077     istring *found = syms.find(name);
00078     operations++;
00079     time_stamp end;
00080     time_in_find += end.value() - start.value();
00081     if (!found)
00082       deadly_error(WHERE, "FIND", "not in table");
00083     if (*found != to_find)
00084       deadly_error(WHERE, "FIND", "string in table was incorrect");
00085   }
00086 }
00087 
00089 
00090 #define static_class_name() "test_string_table"
00091 
00092 void test_string_table()
00093 {
00094   FUNCDEF("test_string_table");
00095 #ifdef TEST_SIZE_TABLE
00096   {
00097     array<string_table> symso(TEST_SIZE_TABLE_COUNT);
00098     operations++;
00099     guards::alert_message(istring(istring::SPRINTF, "we should effectively "
00100         "have swamped out the size of other code in the program now.  the size "
00101         "should represent %d string_table instantiations.  take the current "
00102         "memory size (minus maybe 2 megs) and divide by %d and you will have "
00103         "a fairly accurate cost for instantiating a string table.  hit a key.",
00104         TEST_SIZE_TABLE_COUNT, TEST_SIZE_TABLE_COUNT));
00105     #ifdef _CONSOLE
00106     getchar();
00107     #elif defined(__UNIX__)
00108     getchar();
00109     #endif
00110   }
00111 #endif
00112 
00113   string_table syms;
00114   string_table new_syms;
00115   string_table newer_syms;
00116   operations += 3;
00117   for (int qq = 0; qq < test_iterations; qq++) {
00118     syms.reset();  // still could be costly.
00119     operations++;
00120 #ifdef DEBUG_SYMBOL_TABLE
00121     LOG(istring(istring::SPRINTF, "index %d", qq));
00122 #endif
00123     istring freudname("blurgh");
00124     istring freud("Sigmund Freud was a very freaked dude.");
00125     ADD(syms, freudname, freud);
00126     istring borgname("borg");
00127     istring borg("You will be assimilated.");
00128     ADD(syms, borgname, borg);
00129     istring xname("X-Men");
00130     istring x("The great unknown superhero cartoon.");
00131     ADD(syms, xname, x);
00132     istring aname("fleeny-brickle");
00133     istring a("lallax menick publum.");
00134     ADD(syms, aname, a);
00135     istring axname("ax");
00136     istring ax("Lizzy Borden has a very large hatchet.");
00137     ADD(syms, axname, ax);
00138     istring bloinkname("urg.");
00139     istring bloink("this is a short and stupid string");
00140     ADD(syms, bloinkname, bloink);
00141     istring faxname("fax");
00142     istring fax("alligators in my teacup.");
00143     ADD(syms, faxname, fax);
00144     istring zname("eagle ovaries");
00145     istring z("malfeasors beware");
00146     ADD(syms, zname, z);
00147 
00148     FIND(syms, freudname, freud);
00149     FIND(syms, borgname, borg);
00150     FIND(syms, xname, x);
00151     FIND(syms, aname, a);
00152     FIND(syms, axname, ax);
00153     FIND(syms, bloinkname, bloink);
00154     FIND(syms, faxname, fax);
00155     FIND(syms, zname, z);
00156 
00157     istring name;
00158     istring content;
00159     for (int y = 0; y < MAXIMUM_RANDOM_ADDS; y++) {
00160       name = string_manipulation::make_random_name(40, 108);
00161       content = string_manipulation::make_random_name(300, 1000);
00162       ADD(syms, name, content);
00163       FIND(syms, name, content);
00164     }
00165 
00166     // test copying of the string tables.
00167     string_table chronos = syms;
00168     operations++;
00169     {
00170       string_table mary = syms;
00171       operations++;
00172       string_table june = mary;
00173       operations++;
00174       if (mary != syms)
00175         deadly_error(WHERE, "copy test", "failed to compare properly");
00176       operations++;
00177     }
00178     if (syms != chronos)
00179       deadly_error(WHERE, "copy test", "original was harmed");
00180     operations++;
00181 
00182     {
00183       // test the bug we think we found in the operator =.
00184       string_table fred;
00185       fred.add("urp", "rarp");
00186       fred.add("hyurgh", "ralph");
00187       string_table med;
00188       med.add("urp", "rarp");
00189       med.add("hyurgh", "ralph");
00190       fred = med;  // the deadly assignment.
00191       fred = med;  // the deadly assignment.
00192       fred = med;  // the deadly assignment.
00193       fred = med;  // the deadly assignment.
00194       fred.add("urp", "rarp");
00195       fred.add("gurp", "flaarp");  // a new entry.
00196       istring *urp = fred.find("urp");
00197       istring *hyurgh = fred.find("hyurgh");
00198       if (!urp)
00199         deadly_error(static_class_name(), func, "missing urp");
00200       if (!hyurgh)
00201         deadly_error(static_class_name(), func, "missing hyurgh");
00202 #ifdef DEBUG_SYMBOL_TABLE
00203       LOG(istring("got urp as ") + (urp? *urp : "empty!!!!"));
00204       LOG(istring("got hyurgh as ") + (hyurgh? *hyurgh : "empty!!!!"));
00205 #endif
00206       istring urp_val = fred[0];
00207         // AH HA!  this one finds it.  accessing via bracket or other methods
00208         // that use the internal get() method will fail.
00209         // if there is no outright crash, then the bug is gone.
00210 #ifdef DEBUG_SYMBOL_TABLE
00211       LOG(istring("got urp_val as ") + (urp_val.t()? urp_val : "empty!!!!"));
00212 #endif
00213     }
00214 
00215 #ifdef DEBUG_SYMBOL_TABLE
00217     LOG("now packing the symbol table...");
00218 #endif
00219     byte_array packed_form;
00220     time_stamp start;
00221     syms.pack(packed_form);
00222     operations++;
00223     time_stamp end;
00224     time_in_pack += end.value() - start.value();
00225 #ifdef DEBUG_SYMBOL_TABLE
00226     LOG("now unpacking from packed form");
00227 #endif
00228     start.reset();
00229     if (!new_syms.unpack(packed_form))
00230       deadly_error(WHERE, "unpack test", "failed to unpack");
00231     operations++;
00232     end.reset();  // click, off.
00233     time_in_unpack += end.value() - start.value();
00234 
00235 #ifdef DEBUG_SYMBOL_TABLE
00237 #endif
00238     if (! (syms == new_syms) )
00239       deadly_error(WHERE, "unpacked test", "different symbol tables");
00240     operations++;
00241 
00242 #ifdef DEBUG_SYMBOL_TABLE
00243     LOG("now deleting old symbol table...");
00244 #endif
00245 
00246 #ifdef DEBUG_SYMBOL_TABLE
00248     LOG("packing the symbol table again...");
00249 #endif
00250     byte_array packed_again(0);
00251     start.reset();  // click, on.
00252     new_syms.pack(packed_again);
00253     operations++;
00254     end.reset();  // click, off.
00255     time_in_pack += end.value() - start.value();
00256 #ifdef DEBUG_SYMBOL_TABLE
00257     LOG("now unpacking from packed form again...");
00258 #endif
00259     start = time_stamp();
00260     newer_syms.unpack(packed_again);
00261     operations++;
00262     end = time_stamp();
00263     time_in_unpack += end.value() - start.value();
00264 #ifdef DEBUG_SYMBOL_TABLE
00265     LOG(istring(istring::SPRINTF, "got the unpacked form, and dumping "
00266         "it:\n%s", newer_syms.text_form().s()));
00267 #endif
00268     if (new_syms != newer_syms)
00269       deadly_error(WHERE, "unpacked test", "different symbol tables");
00270     operations++;
00271 
00272 #ifdef DEBUG_SYMBOL_TABLE
00273     LOG("now deleting new and newer symbol table...");
00274 #endif
00275   }
00276 }
00277 
00279 
00280 int main(int formal(argc), char *formal(argv)[])
00281 {
00282   out.log(istring("starting test: ") + timestamp(true, true));
00283   test_string_table();
00284   out.log(istring("done test: ") + timestamp(true, true));
00285 
00286   out.log(istring(istring::SPRINTF, "time in add=%f", time_in_add));
00287   out.log(istring(istring::SPRINTF, "time in find=%f", time_in_find));
00288   out.log(istring(istring::SPRINTF, "time in pack=%f", time_in_pack));
00289   out.log(istring(istring::SPRINTF, "time in unpack=%f", time_in_unpack));
00290   out.log(istring(istring::SPRINTF, "total operations=%u", operations));
00291 
00292   guards::alert_message("string_table:: works for those functions tested.");
00293   return 0;
00294 }
00295 
00296 #undef static_class_name
00297 

Generated on Tue Aug 19 04:29:55 2008 for HOOPLE Libraries by  doxygen 1.5.1