00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
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/symbol_table.cpp>
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
00029
00030
00031 using namespace basis;
00032
00033
00034 const int test_iterations = 20;
00035
00036 const int FIND_ITERATIONS = 100;
00037 const int MAXIMUM_RANDOM_ADDS = 200;
00038
00039 console_logger out;
00040
00041 #ifdef DEBUG_SYMBOL_TABLE
00042 #define LOG(to_print) { out.log(to_print); fflush(0); }
00043 #endif
00044
00045 HOOPLE_STARTUP_CODE;
00046
00047 #define WHERE __WHERE__.s()
00048
00049
00050
00051
00052 double time_in_add = 0;
00053 double time_in_dep_find = 0;
00054 double time_in_new_find = 0;
00055 double time_in_pack = 0;
00056 double time_in_unpack = 0;
00057 double time_in_copy = 0;
00058
00059 class my_table_def : public symbol_table<byte_array>
00060 {
00061 public:
00062 bool operator == (const my_table_def &to_compare) const {
00063 if (symbols() != to_compare.symbols()) return false;
00064 for (int i = 0; i < symbols(); i++) {
00065 if (name(i) != to_compare.name(i)) return false;
00066 if (operator [](i) != to_compare[i]) return false;
00067 }
00068 return true;
00069 }
00070 };
00071
00072 void ADD(my_table_def &syms, const istring &name, const istring &to_add)
00073 {
00074 byte_array to_stuff(to_add.length() + 1, (byte *)to_add.s());
00075 time_stamp start;
00076 outcome added = syms.add(name, to_stuff);
00077 if (added == common::EXISTING)
00078 deadly_error(WHERE, "ADD", "already in table");
00079 time_stamp end;
00080 time_in_add += end.value() - start.value();
00081 start.reset();
00082 #ifdef OLD_TEST
00083 int indy = syms.find(name);
00084 if (negative(indy))
00085 deadly_error(WHERE, "ADD", "not in table after add");
00086 end.reset();
00087 time_in_dep_find += end.value() - start.value();
00088 const byte_array *found = &syms[indy];
00089 #else
00090 byte_array *found = syms.find(name);
00091 if (!found)
00092 deadly_error(WHERE, "ADD", "not in table after add");
00093 end.reset();
00094 time_in_new_find += end.value() - start.value();
00095 #endif
00096 if (*found != to_stuff)
00097 deadly_error(WHERE, "ADD", "wrong value in table after add");
00098 }
00099
00100 void FIND(my_table_def &syms, const istring &name, const istring &to_add)
00101 {
00102 byte_array to_stuff(to_add.length() + 1, (byte *)to_add.s());
00103 for (int i = 0; i < FIND_ITERATIONS; i++) {
00104 time_stamp start;
00105 #ifdef OLD_TEST
00106
00107 int indy = syms.find(name);
00108 if (negative(indy)) deadly_error(WHERE, "FIND", "not in table");
00109 indy = syms.find(name);
00110 if (negative(indy)) deadly_error(WHERE, "FIND", "not in table");
00111 byte_array *found = &syms[indy];
00112 time_stamp end;
00113 time_in_dep_find += end.value() - start.value();
00114 #else
00115 int indy = syms.dep_find(name);
00116 if (negative(indy)) deadly_error(WHERE, "FIND", "not in table (dep_find)");
00117 time_stamp end;
00118 time_in_dep_find += end.value() - start.value();
00119 start.reset();
00120 byte_array *found = syms.find(name);
00121 if (!found) deadly_error(WHERE, "FIND", "not in table (new_find)");
00122 end.reset();
00123 time_in_new_find += end.value() - start.value();
00124 #endif
00125 }
00126 }
00127
00128 void pack(byte_array &packed_form, const my_table_def &to_pack)
00129 {
00130 attach(packed_form, to_pack.symbols());
00131 istring name;
00132 byte_array content;
00133 for (int i = 0; i < to_pack.symbols(); i++) {
00134 to_pack.retrieve(i, name, content);
00135 name.pack(packed_form);
00136 attach(packed_form, content);
00137 }
00138 }
00139
00140 bool unpack(byte_array &packed_form, my_table_def &to_unpack)
00141 {
00142 to_unpack.reset();
00143 int syms = 0;
00144 if (!detach(packed_form, syms)) return false;
00145 istring name;
00146 byte_array chunk;
00147 for (int i = 0; i < syms; i++) {
00148 if (!name.unpack(packed_form)) return false;
00149 if (!detach(packed_form, chunk)) return false;
00150 ADD(to_unpack, name, (char *)chunk.observe());
00151 }
00152 return true;
00153 }
00154
00156
00157 my_table_def creatapose()
00158 {
00159 my_table_def to_return;
00160 istring name;
00161 istring content;
00162 for (int y = 0; y < MAXIMUM_RANDOM_ADDS; y++) {
00163 name = string_manipulation::make_random_name(40, 108);
00164 content = string_manipulation::make_random_name(300, 1000);
00165 byte_array to_stuff(content.length() + 1, (byte *)content.s());
00166 to_return.add(name, to_stuff);
00167 }
00168 return to_return;
00169 }
00170
00172
00173 void test_byte_table()
00174 {
00175 my_table_def syms;
00176 my_table_def new_syms;
00177 my_table_def newer_syms;
00178 for (int qq = 0; qq < test_iterations; qq++) {
00179 syms.reset();
00180 #ifdef DEBUG_SYMBOL_TABLE
00181 LOG(istring(istring::SPRINTF, "index %d", qq));
00182 #endif
00183 istring freudname("blurgh");
00184 istring freud("Sigmund Freud was a very freaked dude.");
00185 ADD(syms, freudname, freud);
00186 istring borgname("borg");
00187 istring borg("You will be assimilated.");
00188 ADD(syms, borgname, borg);
00189 istring xname("X-Men");
00190 istring x("The great unknown superhero cartoon.");
00191 ADD(syms, xname, x);
00192 istring aname("fleeny-brickle");
00193 istring a("lallax menick publum.");
00194 ADD(syms, aname, a);
00195 istring axname("ax");
00196 istring ax("Lizzy Borden has a very large hatchet.");
00197 ADD(syms, axname, ax);
00198 istring bloinkname("urg.");
00199 istring bloink("this is a short and stupid string");
00200 ADD(syms, bloinkname, bloink);
00201 istring faxname("fax");
00202 istring fax("alligators in my teacup.");
00203 ADD(syms, faxname, fax);
00204 istring zname("eagle ovaries");
00205 istring z("malfeasors beware");
00206 ADD(syms, zname, z);
00207
00208 FIND(syms, freudname, freud);
00209 FIND(syms, borgname, borg);
00210 FIND(syms, xname, x);
00211 FIND(syms, aname, a);
00212 FIND(syms, axname, ax);
00213 FIND(syms, bloinkname, bloink);
00214 FIND(syms, faxname, fax);
00215 FIND(syms, zname, z);
00216
00217 istring name;
00218 istring content;
00219 for (int y = 0; y < MAXIMUM_RANDOM_ADDS; y++) {
00220 name = string_manipulation::make_random_name(40, 108);
00221 content = string_manipulation::make_random_name(300, 1000);
00222 ADD(syms, name, content);
00223 FIND(syms, name, content);
00224 }
00225
00226
00227 time_stamp start;
00228 my_table_def copy1(syms);
00229 {
00230 my_table_def joe(copy1);
00231 my_table_def joe2 = joe;
00232 if (joe2 != joe)
00233 deadly_error(WHERE, "copy test A", "different symbol tables");
00234 my_table_def joe3 = creatapose();
00235 my_table_def joe4 = joe3;
00236 my_table_def joe5 = joe4;
00237 if (joe5 != joe3)
00238 deadly_error(WHERE, "copy test A2", "different symbol tables");
00239 }
00240 if (! (syms == copy1) )
00241 deadly_error(WHERE, "copy test B", "different symbol tables");
00242 time_stamp end;
00243 time_in_copy += end.value() - start.value();
00244
00245 #ifdef DEBUG_SYMBOL_TABLE
00247 LOG("now packing the symbol table...");
00248 #endif
00249
00250 #ifdef DEBUG_SYMBOL_TABLE
00251 LOG("now unpacking from packed form");
00252 #endif
00253 byte_array packed_form;
00254 pack(packed_form, syms);
00255 if (!unpack(packed_form, new_syms))
00256 deadly_error(WHERE, "unpack test", "failed to unpack");
00257
00258 #ifdef DEBUG_SYMBOL_TABLE
00260 #endif
00261 if (! (syms == new_syms) )
00262 deadly_error(WHERE, "unpacked test", "different symbol tables");
00263
00264 #ifdef DEBUG_SYMBOL_TABLE
00265 LOG("now deleting old symbol table...");
00266 #endif
00268
00269 #ifdef DEBUG_SYMBOL_TABLE
00271 LOG("packing the symbol table again...");
00272 #endif
00273 byte_array packed_again(0);
00274 start.reset();
00275 pack(packed_again, new_syms);
00276 end.reset();
00277 time_in_pack += end.value() - start.value();
00278 #ifdef DEBUG_SYMBOL_TABLE
00279 LOG("now unpacking from packed form again...");
00280 #endif
00281 start = time_stamp();
00282 unpack(packed_again, newer_syms);
00283 end = time_stamp();
00284 time_in_unpack += end.value() - start.value();
00285 #ifdef DEBUG_SYMBOL_TABLE
00287 #endif
00288 if (new_syms != newer_syms)
00289 deadly_error(WHERE, "unpacked test", "different symbol tables");
00290
00291 #ifdef DEBUG_SYMBOL_TABLE
00292 LOG("now deleting new and newer symbol table...");
00293 #endif
00294 }
00295 }
00296
00298
00299
00300 class jethro
00301 {
00302 public:
00303 istring _truck;
00304
00305 bool operator ==(const jethro &tc) const { return tc._truck == _truck; }
00306 bool operator !=(const jethro &tc) const { return !(*this == tc); }
00307 };
00308
00310
00311
00312
00313 class test_content
00314 {
00315 public:
00316 int _q;
00317 istring _ted;
00318 istring _jed;
00319 int_array _ned;
00320 matrix<jethro> _med;
00321
00322 test_content() : _q(9) {}
00323
00324 test_content(const istring &ted, const istring &jed) : _q(4), _ted(ted),
00325 _jed(jed) {}
00326
00327 bool operator ==(const test_content &tc) const {
00328 if (tc._q != _q) return false;
00329 if (tc._ted != _ted) return false;
00330 if (tc._jed != _jed) return false;
00331 if (tc._ned.length() != _ned.length()) return false;
00332 for (int i = 0; i < _ned.length(); i++)
00333 if (tc._ned[i] != _ned[i]) return false;
00334
00335 if (tc._med.rows() != _med.rows()) return false;
00336 if (tc._med.columns() != _med.columns()) return false;
00337 for (int c = 0; c < _med.columns(); c++)
00338 for (int r = 0; r < _med.rows(); r++)
00339 if (tc._med.get(r, c) != _med.get(r, c)) return false;
00340
00341 return true;
00342 }
00343 bool operator !=(const test_content &tc) const { return !operator ==(tc); }
00344
00345 operator int() const { return _q; }
00346 };
00347
00349
00350 class second_table_def : public symbol_table<test_content>
00351 {
00352 public:
00353 bool operator == (const second_table_def &to_compare) {
00354 if (symbols() != to_compare.symbols()) return false;
00355 for (int i = 0; i < symbols(); i++) {
00356 if ((*this)[i] != to_compare[i]) return false;
00357 }
00358 return true;
00359 }
00360 bool operator != (const second_table_def &to_compare)
00361 { return !(*this == to_compare); }
00362 };
00363
00364 void ADD2(second_table_def &syms, const istring &name,
00365 const test_content &to_add)
00366 {
00367 time_stamp start;
00368 outcome added = syms.add(name, to_add);
00369 if (added == common::EXISTING)
00370 deadly_error(WHERE, "ADD2", "already in table");
00371 time_stamp end;
00372 time_in_add += end.value() - start.value();
00373 start = time_stamp();
00374 #ifdef OLD_TEST
00375 int indy = syms.find(name);
00376 if (negative(indy))
00377 deadly_error(WHERE, "ADD2", "not found after add");
00378
00379 indy = syms.find(name);
00380 if (negative(indy))
00381 deadly_error(WHERE, "ADD2", "not found after add");
00382 end = time_stamp();
00383 time_in_dep_find += end.value() - start.value();
00384 #else
00385 int indy = syms.dep_find(name);
00386 if (negative(indy))
00387 deadly_error(WHERE, "ADD2", "not found after add");
00388 end = time_stamp();
00389 time_in_dep_find += end.value() - start.value();
00390 start = time_stamp();
00391 test_content *found = syms.find(name);
00392 if (!found)
00393 deadly_error(WHERE, "ADD2", "not found after add");
00394 end = time_stamp();
00395 time_in_new_find += end.value() - start.value();
00396 #endif
00397 istring name_out;
00398 test_content content_out;
00399 if (syms.retrieve(indy, name_out, content_out) != common::OKAY) {
00400 if (name_out != name)
00401 deadly_error(WHERE, "ADD2", "name is incorrect after retrieve");
00402 if (content_out != to_add)
00403 deadly_error(WHERE, "ADD2", "content is incorrect after retrieve");
00404 }
00405 }
00406
00408
00409 void test_tc_table()
00410 {
00411 second_table_def syms;
00412 second_table_def new_syms;
00413 second_table_def newer_syms;
00414 for (int qq = 0; qq < test_iterations; qq++) {
00415 syms.reset();
00416 #ifdef DEBUG_SYMBOL_TABLE
00417 LOG(istring(istring::SPRINTF, "index %d", qq));
00418 #endif
00419 istring freudname("blurgh");
00420 test_content freud("Sigmund Freud was a very freaked dude.", "flutenorf");
00421 ADD2(syms, freudname, freud);
00422 istring borgname("borg");
00423 test_content borg("You will be assimilated.", "alabaster");
00424 ADD2(syms, borgname, borg);
00425 istring xname("X-Men");
00426 test_content x("The great unknown superhero cartoon.", "somnambulist");
00427 ADD2(syms, xname, x);
00428 istring aname("fleeny-brickle");
00429 test_content a("lallax menick publum.", "aglos bagnort pavlod");
00430 ADD2(syms, aname, a);
00431 istring axname("ax");
00432 test_content ax("Lizzy Borden has a very large hatchet.", "chop");
00433 ADD2(syms, axname, ax);
00434 istring bloinkname("urg.");
00435 test_content bloink("this is a short and stupid string", "not that short");
00436 ADD2(syms, bloinkname, bloink);
00437 istring faxname("fax");
00438 test_content fax("alligators in my teacup.", "lake placid");
00439 ADD2(syms, faxname, fax);
00440 istring zname("eagle ovaries");
00441 test_content z("malfeasors beware", "endangered");
00442 ADD2(syms, zname, z);
00443
00444
00445 time_stamp start;
00446 second_table_def copy1(syms);
00447 {
00448 second_table_def joe(copy1);
00449 second_table_def joe2 = joe;
00450 if (joe2 != joe)
00451 deadly_error(WHERE, "copy test C", "different symbol tables");
00452 }
00453 if (! (syms == copy1) )
00454 deadly_error(WHERE, "copy test D", "different symbol tables");
00455 time_stamp end;
00456 time_in_copy += end.value() - start.value();
00457
00458
00459
00460
00461
00462
00463
00464
00465
00466
00467
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496
00497
00498
00499
00500
00501
00502
00503 }
00504 }
00505
00507
00508 int main(int formal(argc), char *formal(argv)[])
00509 {
00510 out.log(istring("starting test 1: ") + timestamp(true, true));
00511 test_byte_table();
00512 out.log(istring("done test 1: ") + timestamp(true, true));
00513 out.log(istring("starting test 2: ") + timestamp(true, true));
00514 test_tc_table();
00515 out.log(istring("done test 2: ") + timestamp(true, true));
00516
00517 out.log(istring(istring::SPRINTF, "time in add=%f", time_in_add));
00518 out.log(istring(istring::SPRINTF, "time in dep_find=%f", time_in_dep_find));
00519 out.log(istring(istring::SPRINTF, "time in new_find=%f", time_in_new_find));
00520 out.log(istring(istring::SPRINTF, "time in pack=%f", time_in_pack));
00521 out.log(istring(istring::SPRINTF, "time in unpack=%f", time_in_unpack));
00522
00523 guards::alert_message("symbol_table:: works for those functions tested.");
00524 return 0;
00525 }
00526