1 | /* Copyright libuv project contributors. All rights reserved. |
2 | * |
3 | * Permission is hereby granted, free of charge, to any person obtaining a copy |
4 | * of this software and associated documentation files (the "Software"), to |
5 | * deal in the Software without restriction, including without limitation the |
6 | * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or |
7 | * sell copies of the Software, and to permit persons to whom the Software is |
8 | * furnished to do so, subject to the following conditions: |
9 | * |
10 | * The above copyright notice and this permission notice shall be included in |
11 | * all copies or substantial portions of the Software. |
12 | * |
13 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
14 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
15 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
16 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
17 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING |
18 | * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS |
19 | * IN THE SOFTWARE. |
20 | */ |
21 | |
22 | #if defined(_WIN32) && !defined(USING_UV_SHARED) |
23 | |
24 | #include "uv.h" |
25 | #include "task.h" |
26 | |
27 | #include "../src/win/fs-fd-hash-inl.h" |
28 | |
29 | |
30 | #define HASH_MAX 1000000000 |
31 | #define HASH_INC (1000 * UV__FD_HASH_SIZE + 2) |
32 | #define BUCKET_MAX (UV__FD_HASH_SIZE * UV__FD_HASH_GROUP_SIZE * 10) |
33 | #define BUCKET_INC UV__FD_HASH_SIZE |
34 | #define FD_DIFF 9 |
35 | |
36 | |
37 | void assert_nonexistent(int fd) { |
38 | struct uv__fd_info_s info = { 0 }; |
39 | ASSERT(!uv__fd_hash_get(fd, &info)); |
40 | ASSERT(!uv__fd_hash_remove(fd, &info)); |
41 | } |
42 | |
43 | void assert_existent(int fd) { |
44 | struct uv__fd_info_s info = { 0 }; |
45 | ASSERT(uv__fd_hash_get(fd, &info)); |
46 | ASSERT(info.flags == fd + FD_DIFF); |
47 | } |
48 | |
49 | void assert_insertion(int fd) { |
50 | struct uv__fd_info_s info = { 0 }; |
51 | assert_nonexistent(fd); |
52 | info.flags = fd + FD_DIFF; |
53 | uv__fd_hash_add(fd, &info); |
54 | assert_existent(fd); |
55 | } |
56 | |
57 | void assert_removal(int fd) { |
58 | struct uv__fd_info_s info = { 0 }; |
59 | assert_existent(fd); |
60 | uv__fd_hash_remove(fd, &info); |
61 | ASSERT(info.flags == fd + FD_DIFF); |
62 | assert_nonexistent(fd); |
63 | } |
64 | |
65 | |
66 | /* Run a function for a set of values up to a very high number */ |
67 | #define RUN_HASH(function) \ |
68 | do { \ |
69 | for (fd = 0; fd < HASH_MAX; fd += HASH_INC) { \ |
70 | function(fd); \ |
71 | } \ |
72 | } while (0) |
73 | |
74 | /* Run a function for a set of values that will cause many collisions */ |
75 | #define RUN_COLLISIONS(function) \ |
76 | do { \ |
77 | for (fd = 1; fd < BUCKET_MAX; fd += BUCKET_INC) { \ |
78 | function(fd); \ |
79 | } \ |
80 | } while (0) |
81 | |
82 | |
83 | TEST_IMPL(fs_fd_hash) { |
84 | int fd; |
85 | |
86 | uv__fd_hash_init(); |
87 | |
88 | /* Empty table */ |
89 | RUN_HASH(assert_nonexistent); |
90 | RUN_COLLISIONS(assert_nonexistent); |
91 | |
92 | /* Fill up */ |
93 | RUN_HASH(assert_insertion); |
94 | RUN_COLLISIONS(assert_insertion); |
95 | |
96 | /* Full */ |
97 | RUN_HASH(assert_existent); |
98 | RUN_COLLISIONS(assert_existent); |
99 | |
100 | /* Update */ |
101 | { |
102 | struct uv__fd_info_s info = { 0 }; |
103 | info.flags = FD_DIFF + FD_DIFF; |
104 | uv__fd_hash_add(0, &info); |
105 | } |
106 | { |
107 | struct uv__fd_info_s info = { 0 }; |
108 | ASSERT(uv__fd_hash_get(0, &info)); |
109 | ASSERT(info.flags == FD_DIFF + FD_DIFF); |
110 | } |
111 | { |
112 | /* Leave as it was, will be again tested below */ |
113 | struct uv__fd_info_s info = { 0 }; |
114 | info.flags = FD_DIFF; |
115 | uv__fd_hash_add(0, &info); |
116 | } |
117 | |
118 | /* Remove all */ |
119 | RUN_HASH(assert_removal); |
120 | RUN_COLLISIONS(assert_removal); |
121 | |
122 | /* Empty table */ |
123 | RUN_HASH(assert_nonexistent); |
124 | RUN_COLLISIONS(assert_nonexistent); |
125 | |
126 | return 0; |
127 | } |
128 | |
129 | #else |
130 | |
131 | typedef int file_has_no_tests; /* ISO C forbids an empty translation unit. */ |
132 | |
133 | #endif /* ifndef _WIN32 */ |
134 | |