Bug 470165 - Cleanup the GTK nsFilePicker code; r+sr=roc
[wine-gecko.git] / dbm / tests / lots.c
blobea8bc6ea2345ccf09db20329bffab1e1c1e98d0e
1 /* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
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.
15 * The Original Code is mozilla.org code.
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.
22 * Contributor(s):
24 * Alternatively, the contents of this file may be used under the terms of
25 * either the GNU General Public License Version 2 or later (the "GPL"), or
26 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
27 * in which case the provisions of the GPL or the LGPL are applicable instead
28 * of those above. If you wish to allow use of your version of this file only
29 * under the terms of either the GPL or the LGPL, and not to allow others to
30 * use your version of this file under the terms of the MPL, indicate your
31 * decision by deleting the provisions above and replace them with the notice
32 * and other provisions required by the GPL or the LGPL. If you do not delete
33 * the provisions above, a recipient may use your version of this file under
34 * the terms of any one of the MPL, the GPL or the LGPL.
36 * ***** END LICENSE BLOCK ***** */
38 /* use sequental numbers printed to strings
39 * to store lots and lots of entries in the
40 * database.
42 * Start with 100 entries, put them and then
43 * read them out. Then delete the first
44 * half and verify that all of the first half
45 * is gone and then verify that the second
46 * half is still there.
47 * Then add the first half back and verify
48 * again. Then delete the middle third
49 * and verify again.
50 * Then increase the size by 1000 and do
51 * the whole add delete thing again.
53 * The data for each object is the number string translated
54 * to hex and replicated a random number of times. The
55 * number of times that the data is replicated is the first
56 * int32 in the data.
59 #include <stdio.h>
61 #include <stdlib.h>
62 #ifdef STDC_HEADERS
63 #include <stdarg.h>
64 #else
65 #include <varargs.h>
66 #endif
68 #ifdef HAVE_MEMORY_H
69 #include <memory.h>
70 #endif
71 #include <string.h>
72 #include <assert.h>
73 #include "mcom_db.h"
75 DB *database=0;
76 int MsgPriority=5;
78 #if defined(_WINDOWS) && !defined(WIN32)
79 #define int32 long
80 #define uint32 unsigned long
81 #else
82 #define int32 int
83 #define uint32 unsigned int
84 #endif
86 typedef enum {
87 USE_LARGE_KEY,
88 USE_SMALL_KEY
89 } key_type_enum;
91 #define TraceMe(priority, msg) \
92 do { \
93 if(priority <= MsgPriority) \
94 { \
95 ReportStatus msg; \
96 } \
97 } while(0)
99 int
100 ReportStatus(char *string, ...)
102 va_list args;
104 #ifdef STDC_HEADERS
105 va_start(args, string);
106 #else
107 va_start(args);
108 #endif
109 vfprintf(stderr, string, args);
110 va_end(args);
112 fprintf (stderr, "\n");
114 return(0);
118 ReportError(char *string, ...)
120 va_list args;
122 #ifdef STDC_HEADERS
123 va_start(args, string);
124 #else
125 va_start(args);
126 #endif
127 fprintf (stderr, "\n ");
128 vfprintf(stderr, string, args);
129 fprintf (stderr, "\n");
130 va_end(args);
132 return(0);
135 DBT * MakeLargeKey(int32 num)
137 int32 low_bits;
138 static DBT rv;
139 static char *string_rv=0;
140 int rep_char;
141 size_t size;
143 if(string_rv)
144 free(string_rv);
146 /* generate a really large text key derived from
147 * an int32
149 low_bits = (num % 10000) + 1;
151 /* get the repeat char from the low 26 */
152 rep_char = (char) ((low_bits % 26) + 'a');
154 /* malloc a string low_bits wide */
155 size = low_bits*sizeof(char);
156 string_rv = (char *)malloc(size);
158 memset(string_rv, rep_char, size);
160 rv.data = string_rv;
161 rv.size = size;
163 return(&rv);
166 DBT * MakeSmallKey(int32 num)
168 static DBT rv;
169 static char data_string[64];
171 rv.data = data_string;
173 sprintf(data_string, "%ld", (long)num);
174 rv.size = strlen(data_string);
176 return(&rv);
180 DBT * GenKey(int32 num, key_type_enum key_type)
182 DBT *key;
184 switch(key_type)
186 case USE_LARGE_KEY:
187 key = MakeLargeKey(num);
188 break;
189 case USE_SMALL_KEY:
190 key = MakeSmallKey(num);
191 break;
192 default:
193 abort();
194 break;
197 return(key);
201 SeqDatabase()
203 int status;
204 DBT key, data;
206 ReportStatus("SEQuencing through database...");
208 /* seq through the whole database */
209 if(!(status = (*database->seq)(database, &key, &data, R_FIRST)))
211 while(!(status = (database->seq) (database, &key, &data, R_NEXT)))
212 ; /* null body */
215 if(status < 0)
216 ReportError("Error seq'ing database");
218 return(status);
221 int
222 VerifyData(DBT *data, int32 num, key_type_enum key_type)
224 int32 count, compare_num;
225 size_t size;
226 int32 *int32_array;
228 /* The first int32 is count
229 * The other n entries should
230 * all equal num
232 if(data->size < sizeof(int32))
234 ReportError("Data size corrupted");
235 return -1;
238 memcpy(&count, data->data, sizeof(int32));
240 size = sizeof(int32)*(count+1);
242 if(size != data->size)
244 ReportError("Data size corrupted");
245 return -1;
248 int32_array = (int32*)data->data;
250 for(;count > 0; count--)
252 memcpy(&compare_num, &int32_array[count], sizeof(int32));
254 if(compare_num != num)
256 ReportError("Data corrupted");
257 return -1;
261 return(0);
265 /* verify that a range of number strings exist
266 * or don't exist. And that the data is valid
268 #define SHOULD_EXIST 1
269 #define SHOULD_NOT_EXIST 0
271 VerifyRange(int32 low, int32 high, int32 should_exist, key_type_enum key_type)
273 DBT *key, data;
274 int32 num;
275 int status;
277 TraceMe(1, ("Verifying: %ld to %ld, using %s keys",
278 low, high, key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
280 for(num = low; num <= high; num++)
283 key = GenKey(num, key_type);
285 status = (*database->get)(database, key, &data, 0);
287 if(status == 0)
289 /* got the item */
290 if(!should_exist)
292 ReportError("Item exists but shouldn't: %ld", num);
294 else
296 /* else verify the data */
297 VerifyData(&data, num, key_type);
300 else if(status > 0)
302 /* item not found */
303 if(should_exist)
305 ReportError("Item not found but should be: %ld", num);
308 else
310 /* database error */
311 ReportError("Database error");
312 return(-1);
317 TraceMe(1, ("Correctly verified: %ld to %ld", low, high));
319 return(0);
323 DBT *
324 GenData(int32 num)
326 int32 n;
327 static DBT *data=0;
328 int32 *int32_array;
329 size_t size;
331 if(!data)
333 data = (DBT*)malloc(sizeof(DBT));
334 data->size = 0;
335 data->data = 0;
337 else if(data->data)
339 free(data->data);
342 n = rand();
344 n = n % 512; /* bound to a 2K size */
347 size = sizeof(int32)*(n+1);
348 int32_array = (int32 *) malloc(size);
350 memcpy(&int32_array[0], &n, sizeof(int32));
352 for(; n > 0; n--)
354 memcpy(&int32_array[n], &num, sizeof(int32));
357 data->data = (void*)int32_array;
358 data->size = size;
360 return(data);
363 #define ADD_RANGE 1
364 #define DELETE_RANGE 2
367 AddOrDelRange(int32 low, int32 high, int action, key_type_enum key_type)
369 DBT *key, *data;
370 #if 0 /* only do this if your really analy checking the puts */
371 DBT tmp_data;
372 #endif
373 int32 num;
374 int status;
376 if(action != ADD_RANGE && action != DELETE_RANGE)
377 assert(0);
379 if(action == ADD_RANGE)
381 TraceMe(1, ("Adding: %ld to %ld: %s keys", low, high,
382 key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
384 else
386 TraceMe(1, ("Deleting: %ld to %ld: %s keys", low, high,
387 key_type == USE_SMALL_KEY ? "SMALL" : "LARGE"));
390 for(num = low; num <= high; num++)
393 key = GenKey(num, key_type);
395 if(action == ADD_RANGE)
397 data = GenData(num);
398 status = (*database->put)(database, key, data, 0);
400 else
402 status = (*database->del)(database, key, 0);
405 if(status < 0)
407 ReportError("Database error %s item: %ld",
408 action == ADD_RANGE ? "ADDING" : "DELETING",
409 num);
411 else if(status > 0)
413 ReportError("Could not %s item: %ld",
414 action == ADD_RANGE ? "ADD" : "DELETE",
415 num);
417 else if(action == ADD_RANGE)
419 #define SYNC_EVERY_TIME
420 #ifdef SYNC_EVERY_TIME
421 status = (*database->sync)(database, 0);
422 if(status != 0)
423 ReportError("Database error syncing after add");
424 #endif
426 #if 0 /* only do this if your really analy checking the puts */
428 /* make sure we can still get it
430 status = (*database->get)(database, key, &tmp_data, 0);
432 if(status != 0)
434 ReportError("Database error checking item just added: %d",
435 num);
437 else
439 /* now verify that none of the ones we already
440 * put in have disappeared
442 VerifyRange(low, num, SHOULD_EXIST, key_type);
444 #endif
450 if(action == ADD_RANGE)
452 TraceMe(1, ("Successfully added: %ld to %ld", low, high));
454 else
456 TraceMe(1, ("Successfully deleted: %ld to %ld", low, high));
459 return(0);
463 TestRange(int32 low, int32 range, key_type_enum key_type)
465 int status; int32 low_of_range1, high_of_range1; int32 low_of_range2, high_of_range2;
466 int32 low_of_range3, high_of_range3;
468 status = AddOrDelRange(low, low+range, ADD_RANGE, key_type);
469 status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
471 TraceMe(1, ("Finished with sub test 1"));
473 SeqDatabase();
475 low_of_range1 = low;
476 high_of_range1 = low+(range/2);
477 low_of_range2 = high_of_range1+1;
478 high_of_range2 = low+range;
479 status = AddOrDelRange(low_of_range1, high_of_range1, DELETE_RANGE, key_type);
480 status = VerifyRange(low_of_range1, high_of_range1, SHOULD_NOT_EXIST, key_type);
481 status = VerifyRange(low_of_range2, low_of_range2, SHOULD_EXIST, key_type);
483 TraceMe(1, ("Finished with sub test 2"));
485 SeqDatabase();
487 status = AddOrDelRange(low_of_range1, high_of_range1, ADD_RANGE, key_type);
488 /* the whole thing should exist now */
489 status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
491 TraceMe(1, ("Finished with sub test 3"));
493 SeqDatabase();
495 status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
496 status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
497 status = VerifyRange(low_of_range2, high_of_range2, SHOULD_NOT_EXIST, key_type);
499 TraceMe(1, ("Finished with sub test 4"));
501 SeqDatabase();
503 status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
504 /* the whole thing should exist now */
505 status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
507 TraceMe(1, ("Finished with sub test 5"));
509 SeqDatabase();
511 low_of_range1 = low;
512 high_of_range1 = low+(range/3);
513 low_of_range2 = high_of_range1+1;
514 high_of_range2 = high_of_range1+(range/3);
515 low_of_range3 = high_of_range2+1;
516 high_of_range3 = low+range;
517 /* delete range 2 */
518 status = AddOrDelRange(low_of_range2, high_of_range2, DELETE_RANGE, key_type);
519 status = VerifyRange(low_of_range1, high_of_range1, SHOULD_EXIST, key_type);
520 status = VerifyRange(low_of_range2, low_of_range2, SHOULD_NOT_EXIST, key_type);
521 status = VerifyRange(low_of_range3, low_of_range2, SHOULD_EXIST, key_type);
523 TraceMe(1, ("Finished with sub test 6"));
525 SeqDatabase();
527 status = AddOrDelRange(low_of_range2, high_of_range2, ADD_RANGE, key_type);
528 /* the whole thing should exist now */
529 status = VerifyRange(low, low+range, SHOULD_EXIST, key_type);
531 TraceMe(1, ("Finished with sub test 7"));
533 return(0);
536 #define START_RANGE 109876
538 main(int argc, char **argv)
540 int32 i, j=0;
541 int quick_exit = 0;
542 int large_keys = 0;
543 HASHINFO hash_info = {
544 16*1024,
552 if(argc > 1)
554 while(argc > 1)
556 if(!strcmp(argv[argc-1], "-quick"))
557 quick_exit = 1;
558 else if(!strcmp(argv[argc-1], "-large"))
560 large_keys = 1;
562 argc--;
566 database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, &hash_info);
568 if(!database)
570 ReportError("Could not open database");
571 #ifdef unix
572 perror("");
573 #endif
574 exit(1);
577 if(quick_exit)
579 if(large_keys)
580 TestRange(START_RANGE, 200, USE_LARGE_KEY);
581 else
582 TestRange(START_RANGE, 200, USE_SMALL_KEY);
584 (*database->sync)(database, 0);
585 (*database->close)(database);
586 exit(0);
589 for(i=100; i < 10000000; i+=200)
591 if(1 || j)
593 TestRange(START_RANGE, i, USE_LARGE_KEY);
594 j = 0;
596 else
598 TestRange(START_RANGE, i, USE_SMALL_KEY);
599 j = 1;
602 if(1 == rand() % 3)
604 (*database->sync)(database, 0);
607 if(1 == rand() % 3)
609 /* close and reopen */
610 (*database->close)(database);
611 database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
612 if(!database)
614 ReportError("Could not reopen database");
615 #ifdef unix
616 perror("");
617 #endif
618 exit(1);
621 else
623 /* reopen database without closeing the other */
624 database = dbopen("test.db", O_RDWR | O_CREAT, 0644, DB_HASH, 0);
625 if(!database)
627 ReportError("Could not reopen database "
628 "after not closing the other");
629 #ifdef unix
630 perror("");
631 #endif
632 exit(1);
637 return(0);