1 /*
2  * Copyright (c) 2012 Tim Ruehsen
3  * Copyright (c) 2015-2021 Free Software Foundation, Inc.
4  *
5  * This file is part of Wget.
6  *
7  * Wget is free software: you can redistribute it and/or modify
8  * it under the terms of the GNU General Public License as published by
9  * the Free Software Foundation, either version 3 of the License, or
10  * (at your option) any later version.
11  *
12  * Wget is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15  * GNU General Public License for more details.
16  *
17  * You should have received a copy of the GNU General Public License
18  * along with Wget.  If not, see <https://www.gnu.org/licenses/>.
19  *
20  *
21  * testing performance of hashmap/stringmap routines
22  *
23  * Changelog
24  * 06.07.2012  Tim Ruehsen  created
25  *
26  */
27 
28 #include <config.h>
29 
30 #include <stdio.h>
31 #include <sys/types.h>
32 #include <sys/stat.h>
33 #include <unistd.h>
34 #include <fcntl.h>
35 #include <ctype.h>
36 #include <string.h>
37 #ifdef HAVE_MMAP
38 #	include <sys/mman.h>
39 #endif
40 #include <errno.h>
41 
42 #include <wget.h>
43 
44 static wget_stringmap_browse_fn _print_word;
_print_word(WGET_GCC_UNUSED void * ctx,const char * word,WGET_GCC_UNUSED void * value)45 static int WGET_GCC_NONNULL_ALL _print_word(WGET_GCC_UNUSED void *ctx, const char *word, WGET_GCC_UNUSED void *value)
46 {
47 	printf("%s\n", word);
48 	return 0;
49 }
50 
main(int argc,const char * const * argv)51 int main(int argc, const char *const *argv)
52 {
53 	int fd, it, unique = 0, duple = 0;
54 	char *buf, *word, *end;
55 	size_t length;
56 	struct stat st;
57 	wget_stringmap *map = wget_stringmap_create(1024);
58 
59 	for (it = 1; it < argc; it++) {
60 		if ((fd = open(argv[it], O_RDONLY | O_BINARY)) == -1) {
61 			wget_fprintf(stderr, "Failed to read open %s\n", argv[it]);
62 			continue;
63 		}
64 
65 		if (fstat(fd, &st)) {
66 			wget_fprintf(stderr, "Failed to stat %s\n", argv[it]);
67 			close(fd);
68 			continue;
69 		}
70 
71 		length = st.st_size;
72 
73 #ifdef HAVE_MMAP
74 		if (!(buf = mmap(NULL, length + 1, PROT_READ|PROT_WRITE, MAP_PRIVATE, fd, 0))) {
75 			wget_fprintf(stderr, "Failed to mmap %s (%d)\n", argv[it], errno);
76 			close(fd);
77 			continue;
78 		}
79 #else
80 		if (!(buf = wget_malloc(length + 1)) || read(fd, buf, length) != (signed)length) {
81 			wget_fprintf(stderr, "Failed to read %s (%d)\n", argv[it], errno);
82 			close(fd);
83 			continue;
84 		}
85 #endif
86 
87 		buf[length] = 0;
88 
89 		for (word = buf; *word; word = end) {
90 			while (*word && !isalnum(*word)) word++;
91 			for (end = word; *end && isalnum(*end);) end++;
92 			if (word != end) {
93 				char c = *end;
94 				*end = 0;
95 
96 /*				if (stringmap_get(map, word)) {
97 					duple++;
98 				} else {
99 					stringmap_put_ident_noalloc(map, wget_strmemdup(word, end - word));
100 					unique++;
101 				}
102 */
103 				if (wget_stringmap_put(map, word, NULL))
104 					duple++;
105 				else
106 					unique++;
107 
108 				*end = c;
109 			}
110 		}
111 
112 #ifdef HAVE_MMAP
113 		munmap(buf, length);
114 #else
115 		wget_free(buf);
116 #endif
117 		close(fd);
118 	}
119 
120 	printf("read %d words, %d uniques, %d doubles\n", unique + duple, unique, duple);
121 
122 	// const void *keys = stringmap_get_keys(map);
123 	wget_stringmap_browse(map, _print_word, NULL);
124 
125 	wget_stringmap_free(&map);
126 
127 	return 0;
128 }
129