71acaecdb7c9ff6ac0670bff476bd85bc2b0a427
[xfstests-dev.git] / dmapi / src / suite1 / cmd / randomize_file.c
1 /*
2  * Copyright (c) 2000 Silicon Graphics, Inc.  All Rights Reserved.
3  * 
4  * This program is free software; you can redistribute it and/or modify it
5  * under the terms of version 2 of the GNU General Public License as
6  * published by the Free Software Foundation.
7  * 
8  * This program is distributed in the hope that it would be useful, but
9  * WITHOUT ANY WARRANTY; without even the implied warranty of
10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
11  * 
12  * Further, this software is distributed without any warranty that it is
13  * free of the rightful claim of any third person regarding infringement
14  * or the like.  Any license provided herein, whether implied or
15  * otherwise, applies only to this software file.  Patent licenses, if
16  * any, provided herein do not apply to combinations of this program with
17  * other software, or any other product whatsoever.
18  * 
19  * You should have received a copy of the GNU General Public License along
20  * with this program; if not, write the Free Software Foundation, Inc., 59
21  * Temple Place - Suite 330, Boston MA 02111-1307, USA.
22  * 
23  * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
24  * Mountain View, CA  94043, or:
25  * 
26  * http://www.sgi.com 
27  * 
28  * For further information regarding this notice, see: 
29  * 
30  * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
31  */
32
33 #include <sys/types.h>
34
35 #include <malloc.h>
36 #include <stdio.h>
37 #include <stdlib.h>
38 #include <unistd.h>
39
40 /*
41         This program reads the file specified on the command line and
42         produces a new file on stdout which contains the lines from the
43         input file scrambled into a random order.  This is useful for
44         'randomizing' a database to simulate the kind of I/O that will
45         occur when many records have been added and deleted over time.
46 */
47
48 #define FIELD_WIDTH 21
49
50 static  char    buffer[4096];
51 char *Progname;
52
53 int
54 main(
55         int     argc,
56         char    **argv)
57 {
58         FILE    *infile;
59         FILE    *tmpfile;
60         char    *path;
61         int     line_count = 0;
62         int     i;
63         int     j;
64
65         Progname = argv[0];
66         if (argc != 2) {
67                 fprintf(stderr, "Usage: %s infile\n", argv[0]);
68                 exit(1);
69         }
70
71         /* Read through the input file and count how many lines are present. */
72
73         if ((infile = fopen(argv[1], "r")) == NULL) {
74                 fprintf(stderr, "can't open %s\n", argv[1]);
75                 exit(1);
76         }
77         for (;;) {
78                 if (fgets(buffer, sizeof(buffer), infile) == NULL) {
79                         if (!ferror(infile))
80                                 break;
81                         fprintf(stderr, "Error on infile\n");
82                         exit(1);
83                 }
84                 line_count++;
85         }
86         fprintf(stderr, "%d lines in input file\n", line_count);
87
88         /* Create a temp file.  Copy the input file to the temp file,
89            prepending a random number in the range
90                 0 <= X <= linecount-1
91            to each line copied.
92         */
93
94         path = tmpnam(NULL);
95         if ((tmpfile = fopen(path, "w")) == NULL) {
96                 fprintf(stderr, "error opening temp file %s\n", path);
97                 exit(1);
98         }
99         rewind(infile);
100         srand48((long)getpid());
101
102         for (i = line_count - 1; i >= 0; i--) {
103                 if (fgets(buffer, sizeof(buffer), infile) == NULL) {
104                         if (!ferror(infile))
105                                 break;
106                         fprintf(stderr, "Error on infile\n");
107                         exit(1);
108                 }
109                 j = (int)(drand48() * (float)i);
110                 fprintf(tmpfile, "%*d ", FIELD_WIDTH - 1, j);
111                 fputs(buffer, tmpfile);
112         }
113         if (fclose(infile)) {
114                 fprintf(stderr, "close of input file failed\n");
115                 exit(1);
116         }
117         if (fclose(tmpfile)) {
118                 fprintf(stderr, "close of temp file %s failed\n", path);
119                 exit(1);
120         }
121         fprintf(stderr, "random mapping complete\n");
122
123         /* Use the system sort routine to sort the file into order on the
124            first field, effectively randomizing the lines.
125         */
126
127         sprintf(buffer, "sort +0 -1 -o %s %s", path, path);
128         if (system(buffer)) {
129                 fprintf(stderr, "sort call failed\n");
130                 exit(1);
131         }
132         fprintf(stderr, "sort complete\n");
133
134         /* Copy the temp file to stdout, removing the prepended field. */
135
136         if ((tmpfile = fopen(path, "rw")) == NULL) {
137                 fprintf(stderr, "error reopening temp file %s\n", path);
138                 exit(1);
139         }
140
141         for (i = 0; i < line_count; i++) {
142                 if (fgets(buffer, sizeof(buffer), tmpfile) == NULL) {
143                         if (!ferror(tmpfile))
144                                 break;
145                         fprintf(stderr, "Error on tmpfile\n");
146                         exit(1);
147                 }
148                 if (fputs(buffer + FIELD_WIDTH, stdout) < 0) {
149                         fprintf(stderr, "Error on outfile\n");
150                         exit(1);
151                 }
152         }
153         if (unlink(path)) {
154                 fprintf(stderr, "can't unlink %s\n", path);
155                 exit(1);
156         }
157         exit(0);
158 }