Main Page | Namespace List | Class Hierarchy | Class List | Directories | File List | Namespace Members | Class Members | File Members

TestLongId.C

Go to the documentation of this file.
00001 // This file is part of Vesta.
00002 // 
00003 // Vesta is free software; you can redistribute it and/or
00004 // modify it under the terms of the GNU Lesser General Public
00005 // License as published by the Free Software Foundation; either
00006 // version 2.1 of the License, or (at your option) any later version.
00007 // 
00008 // Vesta is distributed in the hope that it will be useful,
00009 // but WITHOUT ANY WARRANTY; without even the implied warranty of
00010 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00011 // Lesser General Public License for more details.
00012 // 
00013 // You should have received a copy of the GNU Lesser General Public
00014 // License along with Vesta; if not, write to the Free Software
00015 // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00016 
00017 // Last modified on Wed Dec  8 01:33:47 EST 2004 by ken@xorian.net
00018 
00019 #include <VestaSource.H>
00020 #include "VLogHelp.H"
00021 
00022 using std::cout;
00023 using std::cerr;
00024 using std::endl;
00025 
00026 // The number of generated LongIds of maximum length that have been
00027 // generated.
00028 
00029 unsigned int max_length_count = 0;
00030 
00031 // Perform consistency checks on a generated LongId.  If any of the
00032 // checks fail, exit with a non-zero status.
00033 
00034 void check(const LongId &parent, const LongId &child, unsigned int child_index)
00035 {
00036   if(child.length() > sizeof(child.value))
00037     {
00038       cerr << "child length exceeds maximum:" << endl
00039            << "  child = " << child << endl;
00040       exit(1);
00041     }
00042   else if(child.length() == sizeof(child.value))
00043     {
00044       max_length_count++;
00045     }
00046 
00047   // The parent should be an ancestor of the child
00048   if(!parent.isAncestorOf(child))
00049     {
00050       cerr << "parent.isAncestorOf(child) failed:" << endl
00051            << "  parent = " << parent << endl
00052            << "  child = " << child << endl;
00053       exit(1);
00054     }
00055 
00056   // A LongId is its own ancestor
00057   if(!child.isAncestorOf(child))
00058     {
00059       cerr << "child.isAncestorOf(child) failed:" << endl
00060            << "  child = " << child << endl;
00061       exit(1);
00062     }
00063 
00064   // The child should not be an ancestor fo the parent
00065   if(child.isAncestorOf(parent))
00066     {
00067       cerr << "child.isAncestorOf(parent) failed:" << endl
00068            << "  parent = " << parent << endl
00069            << "  child = " << child << endl;
00070       exit(1);
00071     }
00072 
00073   // Determine parent and index from child
00074   unsigned int computed_child_index;
00075   LongId computed_parent = child.getParent(&computed_child_index);
00076 
00077   // The computed parent should be the same as the parent.
00078   if(!(computed_parent == parent))
00079     {
00080       cerr << "child.getParent != parent:" << endl
00081            << "  child           = " << child << endl
00082            << "  child.getParent = " << computed_parent << endl
00083            << "  parent          = " << parent << endl;
00084       exit(1);
00085     }
00086 
00087   // The child index computed by getParent should be the same as the
00088   // index appended.
00089   if(computed_child_index != child_index)
00090     {
00091       cerr << "child index from child.getParent wrong:" << endl
00092            << "  child          = " << child << endl
00093            << "  parent         = " << parent << endl
00094            << "  appended index = " << child_index << endl
00095            << "  computed index = " << computed_child_index << endl;
00096       exit(1);
00097     }
00098 }
00099 
00100 // Generate a random number with a specified number of significant
00101 // bits.
00102 
00103 unsigned int random_bits(int bits)
00104 {
00105   // Get a random positive (31 bit) integer
00106   unsigned int result = 0;
00107 
00108   // Make sure we get a non-zero random number.
00109   while(!result)
00110   {
00111     // random only returns positive 32-bit integers, so we use a
00112     // second one to randomize the upper bit.
00113     unsigned int r1 = random();
00114     unsigned int r2 = random();
00115 
00116     result = (r1 ^ (r2 << 1));
00117   }
00118 
00119   // Right shift it to remove unwanted bits, but make sure we don't
00120   // shit off all non-zero bits.
00121   int shift = 32 - bits;
00122   while(((result >> shift) == 0) && (shift > 0))
00123     {
00124       shift--;
00125     }
00126 
00127   return (result >> shift);
00128 }
00129 
00130 // Generate LongIds by extending the specified base with random
00131 // numbers up to max_bits in size.
00132 
00133 unsigned int test(const LongId &base, int max_bits)
00134 {
00135   unsigned int test_count = 0;
00136   LongId last = base;
00137 
00138   // Loop until the newly generated LongId won't fit.
00139   while(!(last == NullLongId))
00140     {
00141       // Chose a random number of bits to use to extend the LongId.
00142       int append_bits = (random() % max_bits) + 1;
00143       // Chose a random index.
00144       unsigned int index = random_bits(append_bits);
00145       // Extend the LongId
00146       LongId next = last.append(index);
00147       // If we didn't overflow, perform consistency checks.
00148       if(!(next == NullLongId))
00149         {
00150           check(last, next, index);
00151           test_count++;
00152         }
00153       last = next;
00154     }
00155 
00156   return test_count;
00157 }
00158 
00159 int main()
00160 {
00161   // Initialize the random number generator
00162   srandom(time(0));
00163 
00164   // Used to cound the total number of LongIds generated
00165   unsigned int test_count = 0;
00166 
00167   for(int bits = 3; bits < 33; bits++)
00168     {
00169       test_count += test(RootLongId, bits);
00170       test_count += test(MutableRootLongId, bits);
00171       test_count += test(VolatileRootLongId, bits);
00172     }
00173 
00174   cout << test_count << " randomly generated LongIds passed" << endl
00175        << "LongId length limit reached " << max_length_count << " times"
00176        << endl;
00177 
00178   return 0;
00179 }

Generated on Mon May 8 00:48:47 2006 for Vesta by  doxygen 1.4.2