~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/dbm/tests/lots.c

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
9
 *
 
10
 * Software distributed under the License is distributed on an "AS IS" basis,
 
11
 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
 
12
 * for the specific language governing rights and limitations under the
 
13
 * License.
 
14
 *
 
15
 * The Original Code is mozilla.org code.
 
16
 *
 
17
 * The Initial Developer of the Original Code is 
 
18
 * Netscape Communications Corporation.
 
19
 * Portions created by the Initial Developer are Copyright (C) 1998
 
20
 * the Initial Developer. All Rights Reserved.
 
21
 *
 
22
 * Contributor(s):
 
23
 *
 
24
 *
 
25
 * Alternatively, the contents of this file may be used under the terms of
 
26
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
27
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
28
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
29
 * of those above. If you wish to allow use of your version of this file only
 
30
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
31
 * use your version of this file under the terms of the NPL, indicate your
 
32
 * decision by deleting the provisions above and replace them with the notice
 
33
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
34
 * the provisions above, a recipient may use your version of this file under
 
35
 * the terms of any one of the NPL, the GPL or the LGPL.
 
36
 *
 
37
 * ***** END LICENSE BLOCK ***** */
 
38
 
 
39
/* use sequental numbers printed to strings
 
40
 * to store lots and lots of entries in the
 
41
 * database.
 
42
 *
 
43
 * Start with 100 entries, put them and then
 
44
 * read them out.  Then delete the first
 
45
 * half and verify that all of the first half
 
46
 * is gone and then verify that the second
 
47
 * half is still there.
 
48
 * Then add the first half back and verify
 
49
 * again.  Then delete the middle third
 
50
 * and verify again.
 
51
 * Then increase the size by 1000 and do
 
52
 * the whole add delete thing again.
 
53
 *
 
54
 * The data for each object is the number string translated
 
55
 * to hex and replicated a random number of times.  The
 
56
 * number of times that the data is replicated is the first
 
57
 * int32 in the data.
 
58
 */
 
59
 
 
60
#include <stdio.h>
 
61
 
 
62
#include <stdlib.h>
 
63
#ifdef STDC_HEADERS
 
64
#include <stdarg.h>
 
65
#else
 
66
#include <varargs.h>
 
67
#endif
 
68
 
 
69
#ifdef HAVE_MEMORY_H
 
70
#include <memory.h>
 
71
#endif
 
72
#include <string.h>
 
73
#include <assert.h>
 
74
#include "mcom_db.h"
 
75
 
 
76
DB *database=0;
 
77
int MsgPriority=5;
 
78
 
 
79
#if defined(_WINDOWS) && !defined(WIN32)
 
80
#define int32 long
 
81
#define uint32 unsigned long
 
82
#else
 
83
#define int32 int
 
84
#define uint32 unsigned int
 
85
#endif
 
86
 
 
87
typedef enum {
 
88
USE_LARGE_KEY,
 
89
USE_SMALL_KEY
 
90
} key_type_enum;
 
91
 
 
92
#define TraceMe(priority, msg)          \
 
93
        do {                                                    \
 
94
                if(priority <= MsgPriority)     \
 
95
                  {                                                     \
 
96
                        ReportStatus msg;               \
 
97
                  }                                                     \
 
98
        } while(0)
 
99
 
 
100
int
 
101
ReportStatus(char *string, ...)
 
102
{
 
103
    va_list args;
 
104
 
 
105
#ifdef STDC_HEADERS
 
106
    va_start(args, string);
 
107
#else
 
108
    va_start(args);
 
109
#endif
 
110
    vfprintf(stderr, string, args);
 
111
    va_end(args);
 
112
 
 
113
        fprintf (stderr, "\n");
 
114
 
 
115
        return(0);
 
116
}
 
117
 
 
118
int
 
119
ReportError(char *string, ...)
 
120
{
 
121
    va_list args;
 
122
 
 
123
#ifdef STDC_HEADERS
 
124
    va_start(args, string);
 
125
#else
 
126
    va_start(args);
 
127
#endif
 
128
        fprintf (stderr, "\n    ");
 
129
    vfprintf(stderr, string, args);
 
130
        fprintf (stderr, "\n");
 
131
    va_end(args);
 
132
 
 
133
        return(0);
 
134
}
 
135
 
 
136
DBT * MakeLargeKey(int32 num)
 
137
{
 
138
        int32 low_bits;
 
139
        static DBT rv;
 
140
        static char *string_rv=0;
 
141
        int rep_char;
 
142
        size_t size;
 
143
 
 
144
        if(string_rv)
 
145
                free(string_rv);
 
146
 
 
147
        /* generate a really large text key derived from
 
148
         * an int32
 
149
         */
 
150
        low_bits = (num % 10000) + 1;
 
151
 
 
152
        /* get the repeat char from the low 26 */
 
153
        rep_char = (char) ((low_bits % 26) + 'a');
 
154
 
 
155
        /* malloc a string low_bits wide */
 
156
        size = low_bits*sizeof(char);
 
157
        string_rv = (char *)malloc(size);
 
158
 
 
159
        memset(string_rv, rep_char, size);
 
160
 
 
161
        rv.data = string_rv;
 
162
        rv.size = size;
 
163
 
 
164
        return(&rv);
 
165
}
 
166
 
 
167
DBT * MakeSmallKey(int32 num)
 
168
{
 
169
        static DBT rv;
 
170
        static char data_string[64];
 
171
 
 
172
        rv.data = data_string;
 
173
 
 
174
        sprintf(data_string, "%ld", (long)num);
 
175
        rv.size = strlen(data_string);
 
176
 
 
177
        return(&rv);
 
178
 
 
179
}
 
180
 
 
181
DBT * GenKey(int32 num, key_type_enum key_type)
 
182
{
 
183
        DBT *key;
 
184
 
 
185
        switch(key_type)
 
186
          {
 
187
                case USE_LARGE_KEY:
 
188
                        key = MakeLargeKey(num);
 
189
                        break;
 
190
                case USE_SMALL_KEY:
 
191
                        key = MakeSmallKey(num);
 
192
                        break;
 
193
                default:
 
194
                        abort();
 
195
                        break;
 
196
          }
 
197
 
 
198
        return(key);
 
199
}
 
200
 
 
201
int
 
202
SeqDatabase()
 
203
{
 
204
        int status;
 
205
        DBT key, data;
 
206
 
 
207
        ReportStatus("SEQuencing through database...");
 
208
 
 
209
        /* seq throught the whole database */
 
210
    if(!(status = (*database->seq)(database, &key, &data, R_FIRST)))
 
211
          {
 
212
        while(!(status = (database->seq) (database, &key, &data, R_NEXT)));
 
213
                        ; /* null body */
 
214
          }
 
215
 
 
216
        if(status < 0)
 
217
                ReportError("Error seq'ing database");
 
218
 
 
219
        return(status);
 
220
}
 
221
 
 
222
int 
 
223
VerifyData(DBT *data, int32 num, key_type_enum key_type)
 
224
{
 
225
        int32 count, compare_num;
 
226
        size_t size;
 
227
        int32 *int32_array;
 
228
 
 
229
        /* The first int32 is count 
 
230
         * The other n entries should
 
231
         * all equal num
 
232
         */
 
233
        if(data->size < sizeof(int32))
 
234
          {
 
235
                ReportError("Data size corrupted");
 
236
                return -1;
 
237
          }
 
238
 
 
239
        memcpy(&count, data->data, sizeof(int32));
 
240
 
 
241
        size = sizeof(int32)*(count+1);
 
242
 
 
243
        if(size != data->size)
 
244
          {
 
245
                ReportError("Data size corrupted");
 
246
                return -1;
 
247
          }
 
248
 
 
249
        int32_array = (int32*)data->data;
 
250
 
 
251
        for(;count > 0; count--)
 
252
          {
 
253
                memcpy(&compare_num, &int32_array[count], sizeof(int32));
 
254
 
 
255
                if(compare_num != num)
 
256
              {
 
257
                    ReportError("Data corrupted");
 
258
                    return -1;
 
259
              }
 
260
          }
 
261
 
 
262
        return(0);
 
263
}
 
264
 
 
265
 
 
266
/* verify that a range of number strings exist
 
267
 * or don't exist. And that the data is valid
 
268
 */
 
269
#define SHOULD_EXIST 1
 
270
#define SHOULD_NOT_EXIST 0
 
271
int
 
272
VerifyRange(int32 low, int32 high, int32 should_exist, key_type_enum key_type)
 
273
{
 
274
        DBT *key, data;
 
275
        int32 num;
 
276
        int status;
 
277
 
 
278
        TraceMe(1, ("Verifying: %ld to %ld, using %s keys", 
 
279
                    low, high, key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
 
280
 
 
281
        for(num = low; num <= high; num++)
 
282
          {
 
283
 
 
284
                key = GenKey(num, key_type);
 
285
 
 
286
                status = (*database->get)(database, key, &data, 0);
 
287
 
 
288
                if(status == 0)
 
289
                  {
 
290
                        /* got the item */
 
291
                        if(!should_exist)
 
292
                          {
 
293
                                ReportError("Item exists but shouldn't: %ld", num);
 
294
                          }
 
295
                        else
 
296
                          {
 
297
                            /* else verify the data */
 
298
                            VerifyData(&data, num, key_type);
 
299
                          }
 
300
                  }
 
301
                else if(status > 0)
 
302
                  {
 
303
                        /* item not found */
 
304
                        if(should_exist)
 
305
                          {
 
306
                                ReportError("Item not found but should be: %ld", num);
 
307
                          }
 
308
                  }
 
309
                else
 
310
                  {
 
311
                        /* database error */
 
312
                        ReportError("Database error");
 
313
                        return(-1);
 
314
                  }
 
315
                        
 
316
          }
 
317
 
 
318
        TraceMe(1, ("Correctly verified: %ld to %ld", low, high));
 
319
 
 
320
        return(0);
 
321
 
 
322
}
 
323
 
 
324
DBT *
 
325
GenData(int32 num)
 
326
{
 
327
        int32 n;
 
328
        static DBT *data=0;
 
329
        int32 *int32_array;
 
330
        size_t size;
 
331
 
 
332
        if(!data)
 
333
          {
 
334
                data = (DBT*)malloc(sizeof(DBT));
 
335
                data->size = 0;
 
336
                data->data = 0;
 
337
          }
 
338
        else if(data->data)
 
339
          {
 
340
                free(data->data);
 
341
          }
 
342
 
 
343
        n = rand();
 
344
 
 
345
        n = n % 512;  /* bound to a 2K size */
 
346
 
 
347
        
 
348
        size = sizeof(int32)*(n+1);
 
349
        int32_array = (int32 *) malloc(size);
 
350
 
 
351
        memcpy(&int32_array[0], &n, sizeof(int32));
 
352
 
 
353
        for(; n > 0; n--)
 
354
          {
 
355
                memcpy(&int32_array[n], &num, sizeof(int32));
 
356
          }
 
357
 
 
358
        data->data = (void*)int32_array;
 
359
        data->size = size;
 
360
 
 
361
        return(data);
 
362
}
 
363
 
 
364
#define ADD_RANGE 1
 
365
#define DELETE_RANGE 2
 
366
 
 
367
int
 
368
AddOrDelRange(int32 low, int32 high, int action, key_type_enum key_type)
 
369
{
 
370
        DBT *key, *data;
 
371
#if 0 /* only do this if your really analy checking the puts */
 
372
        DBT tmp_data;
 
373
#endif 
 
374
        int32 num;
 
375
        int status;
 
376
 
 
377
        if(action != ADD_RANGE && action != DELETE_RANGE)
 
378
                assert(0);
 
379
 
 
380
        if(action == ADD_RANGE)
 
381
          {
 
382
                TraceMe(1, ("Adding: %ld to %ld: %s keys", low, high,
 
383
                        key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
 
384
          }
 
385
        else
 
386
          {
 
387
                TraceMe(1, ("Deleting: %ld to %ld: %s keys", low, high,
 
388
                        key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
 
389
          }
 
390
 
 
391
        for(num = low; num <= high; num++)
 
392
          {
 
393
 
 
394
                key = GenKey(num, key_type);
 
395
 
 
396
                if(action == ADD_RANGE)
 
397
                  {
 
398
                        data = GenData(num);
 
399
                        status = (*database->put)(database, key, data, 0);
 
400
                  }
 
401
                else
 
402
                  {
 
403
                        status = (*database->del)(database, key, 0);
 
404
                  }
 
405
 
 
406
                if(status < 0)
 
407
                  {
 
408
                        ReportError("Database error %s item: %ld",
 
409
                                                        action == ADD_RANGE ? "ADDING" : "DELETING", 
 
410
                                                        num);
 
411
                  }
 
412
                else if(status > 0)
 
413
                  {
 
414
                        ReportError("Could not %s item: %ld", 
 
415
                                                        action == ADD_RANGE ? "ADD" : "DELETE", 
 
416
                                                        num);
 
417
                  }
 
418
                else if(action == ADD_RANGE)
 
419
                  {
 
420
#define SYNC_EVERY_TIME
 
421
#ifdef SYNC_EVERY_TIME
 
422
                        status = (*database->sync)(database, 0);
 
423
                        if(status != 0)
 
424
                                ReportError("Database error syncing after add");
 
425
#endif
 
426
 
 
427
#if 0 /* only do this if your really analy checking the puts */
 
428
         
 
429
                        /* make sure we can still get it
 
430
                         */
 
431
                        status = (*database->get)(database, key, &tmp_data, 0);
 
432
 
 
433
                        if(status != 0)
 
434
                          {
 
435
                                ReportError("Database error checking item just added: %d",
 
436
                                                        num);
 
437
                          }
 
438
                        else
 
439
                          {
 
440
                                /* now verify that none of the ones we already
 
441
                                 * put in have disappeared
 
442
                                 */
 
443
                                VerifyRange(low, num, SHOULD_EXIST, key_type);
 
444
                          }
 
445
#endif
 
446
                        
 
447
                  }
 
448
          }
 
449
 
 
450
 
 
451
        if(action == ADD_RANGE)
 
452
          {
 
453
                TraceMe(1, ("Successfully added: %ld to %ld", low, high));
 
454
          }
 
455
        else
 
456
          {
 
457
                TraceMe(1, ("Successfully deleted: %ld to %ld", low, high));
 
458
          }
 
459
 
 
460
        return(0);
 
461
}
 
462
 
 
463
int
 
464
TestRange(int32 low, int32 range, key_type_enum key_type)
 
465
{
 
466
        int status; int32 low_of_range1, high_of_range1; int32 low_of_range2, high_of_range2;
 
467
        int32 low_of_range3, high_of_range3;
 
468
 
 
469
        status = AddOrDelRange(low, low+range, ADD_RANGE, key_type);
 
470
        status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
 
471
 
 
472
        TraceMe(1, ("Finished with sub test 1"));
 
473
 
 
474
        SeqDatabase();
 
475
 
 
476
        low_of_range1 = low;
 
477
        high_of_range1 = low+(range/2);
 
478
        low_of_range2 = high_of_range1+1;
 
479
        high_of_range2 = low+range;
 
480
        status = AddOrDelRange(low_of_range1, high_of_range1, DELETE_RANGE, key_type);
 
481
        status = VerifyRange(low_of_range1, high_of_range1, SHOULD_NOT_EXIST, key_type);
 
482
        status = VerifyRange(low_of_range2, low_of_range2, SHOULD_EXIST, key_type);
 
483
 
 
484
        TraceMe(1, ("Finished with sub test 2"));
 
485
 
 
486
        SeqDatabase();
 
487
 
 
488
        status = AddOrDelRange(low_of_range1, high_of_range1, ADD_RANGE, key_type);
 
489
        /* the whole thing should exist now */
 
490
        status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
 
491
 
 
492
        TraceMe(1, ("Finished with sub test 3"));
 
493
 
 
494
        SeqDatabase();
 
495
 
 
496
        status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
 
497
        status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
 
498
        status = VerifyRange(low_of_range2, high_of_range2, SHOULD_NOT_EXIST, key_type);
 
499
 
 
500
        TraceMe(1, ("Finished with sub test 4"));
 
501
 
 
502
        SeqDatabase();
 
503
 
 
504
        status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
 
505
        /* the whole thing should exist now */
 
506
        status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
 
507
 
 
508
        TraceMe(1, ("Finished with sub test 5"));
 
509
 
 
510
        SeqDatabase();
 
511
 
 
512
        low_of_range1 = low;
 
513
        high_of_range1 = low+(range/3);
 
514
        low_of_range2 = high_of_range1+1;
 
515
        high_of_range2 = high_of_range1+(range/3);
 
516
        low_of_range3 = high_of_range2+1;
 
517
        high_of_range3 = low+range;
 
518
        /* delete range 2 */
 
519
        status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
 
520
        status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
 
521
        status = VerifyRange(low_of_range2, low_of_range2, SHOULD_NOT_EXIST, key_type);
 
522
        status = VerifyRange(low_of_range3, low_of_range2, SHOULD_EXIST, key_type);
 
523
 
 
524
        TraceMe(1, ("Finished with sub test 6"));
 
525
 
 
526
        SeqDatabase();
 
527
 
 
528
        status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
 
529
        /* the whole thing should exist now */
 
530
        status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
 
531
 
 
532
        TraceMe(1, ("Finished with sub test 7"));
 
533
 
 
534
        return(0);
 
535
}
 
536
 
 
537
#define START_RANGE 109876
 
538
int
 
539
main(int argc, char **argv)
 
540
{
 
541
        int32 i, j=0;
 
542
    int quick_exit = 0;
 
543
    int large_keys = 0;
 
544
    HASHINFO hash_info = {
 
545
        16*1024,
 
546
        0,
 
547
        0,
 
548
        0,
 
549
        0,
 
550
        0};
 
551
 
 
552
 
 
553
    if(argc > 1)
 
554
      {
 
555
        while(argc > 1)
 
556
          {
 
557
            if(!strcmp(argv[argc-1], "-quick"))
 
558
                quick_exit = 1;
 
559
            else if(!strcmp(argv[argc-1], "-large"))
 
560
                          {
 
561
                large_keys = 1;
 
562
                          }
 
563
            argc--;
 
564
          }
 
565
      }
 
566
 
 
567
        database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
 
568
 
 
569
        if(!database)
 
570
          {
 
571
                ReportError("Could not open database");
 
572
#ifdef unix
 
573
                perror("");
 
574
#endif
 
575
                exit(1);
 
576
          }
 
577
 
 
578
        if(quick_exit)
 
579
          {
 
580
                if(large_keys)
 
581
                        TestRange(START_RANGE, 200, USE_LARGE_KEY);
 
582
                else
 
583
                        TestRange(START_RANGE, 200, USE_SMALL_KEY);
 
584
 
 
585
                (*database->sync)(database, 0);
 
586
                (*database->close)(database);
 
587
        exit(0);
 
588
          }
 
589
 
 
590
        for(i=100; i < 10000000; i+=200)
 
591
          {
 
592
                if(1 || j)
 
593
                  {
 
594
                        TestRange(START_RANGE, i, USE_LARGE_KEY);
 
595
                        j = 0;
 
596
                  }
 
597
                else
 
598
                  {
 
599
                        TestRange(START_RANGE, i, USE_SMALL_KEY);
 
600
                        j = 1;
 
601
                  }
 
602
 
 
603
                if(1 == rand() % 3)
 
604
                  {
 
605
                        (*database->sync)(database, 0);
 
606
                  }
 
607
                
 
608
                if(1 == rand() % 3)
 
609
                  {
 
610
                        /* close and reopen */
 
611
                        (*database->close)(database);
 
612
                        database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
 
613
                        if(!database)
 
614
                        {
 
615
                                ReportError("Could not reopen database");
 
616
#ifdef unix
 
617
                                perror("");
 
618
#endif
 
619
                                exit(1);
 
620
                        }
 
621
                  }
 
622
                else
 
623
                  {
 
624
                        /* reopen database without closeing the other */
 
625
                        database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
 
626
                        if(!database)
 
627
                        {
 
628
                                ReportError("Could not reopen database "
 
629
                                                        "after not closing the other");
 
630
#ifdef unix
 
631
                                perror("");
 
632
#endif
 
633
                                exit(1);
 
634
                        }
 
635
                  }
 
636
          }
 
637
 
 
638
        return(0);
 
639
}