Back to index

lightning-sunbird  0.9+nobinonly
Defines | Enumerations | Functions | Variables
lots.c File Reference
#include <stdio.h>
#include <stdlib.h>
#include <varargs.h>
#include <string.h>
#include <assert.h>
#include "mcom_db.h"

Go to the source code of this file.

Defines

#define int32   int
#define uint32   unsigned int
#define TraceMe(priority, msg)
#define SHOULD_EXIST   1
#define SHOULD_NOT_EXIST   0
#define ADD_RANGE   1
#define DELETE_RANGE   2
#define SYNC_EVERY_TIME
#define START_RANGE   109876

Enumerations

enum  key_type_enum { USE_LARGE_KEY, USE_SMALL_KEY }

Functions

int ReportStatus (char *string,...)
int ReportError (char *string,...)
DBTMakeLargeKey (int32 num)
DBTMakeSmallKey (int32 num)
DBTGenKey (int32 num, key_type_enum key_type)
int SeqDatabase ()
int VerifyData (DBT *data, int32 num, key_type_enum key_type)
int VerifyRange (int32 low, int32 high, int32 should_exist, key_type_enum key_type)
DBTGenData (int32 num)
int AddOrDelRange (int32 low, int32 high, int action, key_type_enum key_type)
int TestRange (int32 low, int32 range, key_type_enum key_type)
int main (int argc, char **argv)

Variables

DBdatabase = 0
int MsgPriority = 5

Define Documentation

#define ADD_RANGE   1

Definition at line 364 of file lots.c.

Definition at line 365 of file lots.c.

#define int32   int

Definition at line 83 of file lots.c.

Definition at line 269 of file lots.c.

Definition at line 270 of file lots.c.

#define START_RANGE   109876

Definition at line 537 of file lots.c.

#define TraceMe (   priority,
  msg 
)
Value:
do {                                             \
              if(priority <= MsgPriority) \
                {                                              \
                     ReportStatus msg;           \
                }                                              \
       } while(0)

Definition at line 92 of file lots.c.

#define uint32   unsigned int

Definition at line 84 of file lots.c.


Enumeration Type Documentation

Enumerator:
USE_LARGE_KEY 
USE_SMALL_KEY 

Definition at line 87 of file lots.c.


Function Documentation

int AddOrDelRange ( int32  low,
int32  high,
int  action,
key_type_enum  key_type 
)

Definition at line 368 of file lots.c.

{
       DBT *key, *data;
#if 0 /* only do this if your really analy checking the puts */
       DBT tmp_data;
#endif 
       int32 num;
       int status;

       if(action != ADD_RANGE && action != DELETE_RANGE)
              assert(0);

       if(action == ADD_RANGE)
         {
              TraceMe(1, ("Adding: %ld to %ld: %s keys", low, high,
                     key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
         }
       else
         {
              TraceMe(1, ("Deleting: %ld to %ld: %s keys", low, high,
                     key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
         }

       for(num = low; num <= high; num++)
         {

              key = GenKey(num, key_type);

              if(action == ADD_RANGE)
                {
                     data = GenData(num);
                     status = (*database->put)(database, key, data, 0);
                }
              else
                {
                     status = (*database->del)(database, key, 0);
                }

              if(status < 0)
                {
                     ReportError("Database error %s item: %ld",
                                                 action == ADD_RANGE ? "ADDING" : "DELETING", 
                                                 num);
                }
              else if(status > 0)
                {
                     ReportError("Could not %s item: %ld", 
                                                 action == ADD_RANGE ? "ADD" : "DELETE", 
                                                 num);
                }
              else if(action == ADD_RANGE)
                {
#define SYNC_EVERY_TIME
#ifdef SYNC_EVERY_TIME
                     status = (*database->sync)(database, 0);
                     if(status != 0)
                            ReportError("Database error syncing after add");
#endif

#if 0 /* only do this if your really analy checking the puts */
        
                     /* make sure we can still get it
                      */
                     status = (*database->get)(database, key, &tmp_data, 0);

                     if(status != 0)
                       {
                            ReportError("Database error checking item just added: %d",
                                                 num);
                       }
                     else
                       {
                            /* now verify that none of the ones we already
                             * put in have disappeared
                             */
                            VerifyRange(low, num, SHOULD_EXIST, key_type);
                       }
#endif
                     
                }
         }


       if(action == ADD_RANGE)
         {
              TraceMe(1, ("Successfully added: %ld to %ld", low, high));
         }
       else
         {
              TraceMe(1, ("Successfully deleted: %ld to %ld", low, high));
         }

       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

DBT* GenData ( int32  num)

Definition at line 325 of file lots.c.

{
       int32 n;
       static DBT *data=0;
       int32 *int32_array;
       size_t size;

       if(!data)
         {
              data = (DBT*)malloc(sizeof(DBT));
              data->size = 0;
              data->data = 0;
         }
       else if(data->data)
         {
              free(data->data);
         }

       n = rand();

       n = n % 512;  /* bound to a 2K size */

       
       size = sizeof(int32)*(n+1);
       int32_array = (int32 *) malloc(size);

       memcpy(&int32_array[0], &n, sizeof(int32));

       for(; n > 0; n--)
         {
              memcpy(&int32_array[n], &num, sizeof(int32));
         }

       data->data = (void*)int32_array;
       data->size = size;

       return(data);
}

Here is the call graph for this function:

Here is the caller graph for this function:

DBT* GenKey ( int32  num,
key_type_enum  key_type 
)

Definition at line 181 of file lots.c.

{
       DBT *key;

       switch(key_type)
         {
              case USE_LARGE_KEY:
                     key = MakeLargeKey(num);
                     break;
              case USE_SMALL_KEY:
                     key = MakeSmallKey(num);
                     break;
              default:
                     abort();
                     break;
         }

       return(key);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int main ( int  argc,
char **  argv 
)

Definition at line 539 of file lots.c.

{
       int32 i, j=0;
    int quick_exit = 0;
    int large_keys = 0;
    HASHINFO hash_info = {
        16*1024,
        0,
        0,
        0,
        0,
        0};


    if(argc > 1)
      {
        while(argc > 1)
         {
            if(!strcmp(argv[argc-1], "-quick"))
                quick_exit = 1;
            else if(!strcmp(argv[argc-1], "-large"))
                       {
                large_keys = 1;
                       }
            argc--;
          }
      }

       database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);

       if(!database)
         {
              ReportError("Could not open database");
#ifdef unix
              perror("");
#endif
              exit(1);
         }

       if(quick_exit)
         {
              if(large_keys)
                     TestRange(START_RANGE, 200, USE_LARGE_KEY);
              else
                     TestRange(START_RANGE, 200, USE_SMALL_KEY);

              (*database->sync)(database, 0);
              (*database->close)(database);
        exit(0);
         }

       for(i=100; i < 10000000; i+=200)
         {
              if(1 || j)
                {
                     TestRange(START_RANGE, i, USE_LARGE_KEY);
                     j = 0;
                }
              else
                {
                     TestRange(START_RANGE, i, USE_SMALL_KEY);
                     j = 1;
                }

              if(1 == rand() % 3)
                {
                     (*database->sync)(database, 0);
                }
              
              if(1 == rand() % 3)
                {
                     /* close and reopen */
                     (*database->close)(database);
                     database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
                     if(!database)
                     {
                            ReportError("Could not reopen database");
#ifdef unix
                            perror("");
#endif
                            exit(1);
                     }
                }
              else
                {
                     /* reopen database without closeing the other */
                     database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
                     if(!database)
                     {
                            ReportError("Could not reopen database "
                                                 "after not closing the other");
#ifdef unix
                            perror("");
#endif
                            exit(1);
                     }
                }
         }

       return(0);
}

Here is the call graph for this function:

DBT* MakeLargeKey ( int32  num)

Definition at line 136 of file lots.c.

{
       int32 low_bits;
       static DBT rv;
       static char *string_rv=0;
       int rep_char;
       size_t size;

       if(string_rv)
              free(string_rv);

       /* generate a really large text key derived from
        * an int32
        */
       low_bits = (num % 10000) + 1;

       /* get the repeat char from the low 26 */
       rep_char = (char) ((low_bits % 26) + 'a');

       /* malloc a string low_bits wide */
       size = low_bits*sizeof(char);
       string_rv = (char *)malloc(size);

       memset(string_rv, rep_char, size);

       rv.data = string_rv;
       rv.size = size;

       return(&rv);
}

Here is the call graph for this function:

Here is the caller graph for this function:

DBT* MakeSmallKey ( int32  num)

Definition at line 167 of file lots.c.

{
       static DBT rv;
       static char data_string[64];

       rv.data = data_string;

       sprintf(data_string, "%ld", (long)num);
       rv.size = strlen(data_string);

       return(&rv);

}

Here is the caller graph for this function:

int ReportError ( char *  string,
  ... 
)

Definition at line 119 of file lots.c.

{
    va_list args;

#ifdef STDC_HEADERS
    va_start(args, string);
#else
    va_start(args);
#endif
       fprintf (stderr, "\n ");
    vfprintf(stderr, string, args);
       fprintf (stderr, "\n");
    va_end(args);

       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int ReportStatus ( char *  string,
  ... 
)

Definition at line 101 of file lots.c.

{
    va_list args;

#ifdef STDC_HEADERS
    va_start(args, string);
#else
    va_start(args);
#endif
    vfprintf(stderr, string, args);
    va_end(args);

       fprintf (stderr, "\n");

       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

Definition at line 202 of file lots.c.

{
       int status;
       DBT key, data;

       ReportStatus("SEQuencing through database...");

       /* seq throught the whole database */
    if(!(status = (*database->seq)(database, &key, &data, R_FIRST)))
         {
        while(!(status = (database->seq) (database, &key, &data, R_NEXT)));
                     ; /* null body */
         }

       if(status < 0)
              ReportError("Error seq'ing database");

       return(status);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int TestRange ( int32  low,
int32  range,
key_type_enum  key_type 
)

Definition at line 464 of file lots.c.

{
       int status; int32 low_of_range1, high_of_range1; int32 low_of_range2, high_of_range2;
       int32 low_of_range3, high_of_range3;

       status = AddOrDelRange(low, low+range, ADD_RANGE, key_type);
       status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 1"));

       SeqDatabase();

       low_of_range1 = low;
       high_of_range1 = low+(range/2);
       low_of_range2 = high_of_range1+1;
       high_of_range2 = low+range;
       status = AddOrDelRange(low_of_range1, high_of_range1, DELETE_RANGE, key_type);
       status = VerifyRange(low_of_range1, high_of_range1, SHOULD_NOT_EXIST, key_type);
       status = VerifyRange(low_of_range2, low_of_range2, SHOULD_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 2"));

       SeqDatabase();

       status = AddOrDelRange(low_of_range1, high_of_range1, ADD_RANGE, key_type);
       /* the whole thing should exist now */
       status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 3"));

       SeqDatabase();

       status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
       status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
       status = VerifyRange(low_of_range2, high_of_range2, SHOULD_NOT_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 4"));

       SeqDatabase();

       status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
       /* the whole thing should exist now */
       status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 5"));

       SeqDatabase();

       low_of_range1 = low;
       high_of_range1 = low+(range/3);
       low_of_range2 = high_of_range1+1;
       high_of_range2 = high_of_range1+(range/3);
       low_of_range3 = high_of_range2+1;
       high_of_range3 = low+range;
       /* delete range 2 */
       status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
       status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
       status = VerifyRange(low_of_range2, low_of_range2, SHOULD_NOT_EXIST, key_type);
       status = VerifyRange(low_of_range3, low_of_range2, SHOULD_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 6"));

       SeqDatabase();

       status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
       /* the whole thing should exist now */
       status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);

       TraceMe(1, ("Finished with sub test 7"));

       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int VerifyData ( DBT data,
int32  num,
key_type_enum  key_type 
)

Definition at line 223 of file lots.c.

{
       int32 count, compare_num;
       size_t size;
       int32 *int32_array;

       /* The first int32 is count 
        * The other n entries should
        * all equal num
        */
       if(data->size < sizeof(int32))
         {
              ReportError("Data size corrupted");
              return -1;
         }

       memcpy(&count, data->data, sizeof(int32));

       size = sizeof(int32)*(count+1);

       if(size != data->size)
         {
              ReportError("Data size corrupted");
              return -1;
         }

       int32_array = (int32*)data->data;

       for(;count > 0; count--)
         {
              memcpy(&compare_num, &int32_array[count], sizeof(int32));

              if(compare_num != num)
             {
                  ReportError("Data corrupted");
                  return -1;
             }
         }

       return(0);
}

Here is the call graph for this function:

Here is the caller graph for this function:

int VerifyRange ( int32  low,
int32  high,
int32  should_exist,
key_type_enum  key_type 
)

Definition at line 272 of file lots.c.

{
       DBT *key, data;
       int32 num;
       int status;

       TraceMe(1, ("Verifying: %ld to %ld, using %s keys", 
                  low, high, key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));

       for(num = low; num <= high; num++)
         {

              key = GenKey(num, key_type);

              status = (*database->get)(database, key, &data, 0);

              if(status == 0)
                {
                     /* got the item */
                     if(!should_exist)
                       {
                            ReportError("Item exists but shouldn't: %ld", num);
                       }
                     else
                       {
                         /* else verify the data */
                         VerifyData(&data, num, key_type);
                       }
                }
              else if(status > 0)
                {
                     /* item not found */
                     if(should_exist)
                       {
                            ReportError("Item not found but should be: %ld", num);
                       }
                }
              else
                {
                     /* database error */
                     ReportError("Database error");
                     return(-1);
                }
                     
         }

       TraceMe(1, ("Correctly verified: %ld to %ld", low, high));

       return(0);

}

Here is the call graph for this function:

Here is the caller graph for this function:


Variable Documentation

DB* database = 0

Definition at line 76 of file lots.c.

Definition at line 77 of file lots.c.