Commit | Line | Data |
---|---|---|
380065aa JA |
1 | #include <stdlib.h> |
2 | #include <assert.h> | |
3 | ||
4 | #include "fio.h" | |
5 | #include "list.h" | |
6 | #include "crc/crc16.h" | |
7 | ||
8 | #define HASH_BUCKETS 512 | |
9 | #define HASH_MASK (HASH_BUCKETS - 1) | |
10 | ||
11 | unsigned int file_hash_size = HASH_BUCKETS * sizeof(struct list_head); | |
12 | ||
13 | static struct list_head *file_hash; | |
14 | static struct fio_mutex *hash_lock; | |
15 | ||
16 | static void dump_hash(void) | |
17 | { | |
18 | struct list_head *n; | |
19 | unsigned int i; | |
20 | ||
21 | for (i = 0; i < HASH_BUCKETS; i++) { | |
22 | list_for_each(n, &file_hash[i]) { | |
23 | struct fio_file *f; | |
24 | ||
25 | f = list_entry(n, struct fio_file, hash_list); | |
26 | printf("%d: %s\n", i, f->file_name); | |
27 | } | |
28 | } | |
29 | } | |
30 | ||
31 | static unsigned short hash(const char *name) | |
32 | { | |
33 | return crc16((const unsigned char *) name, strlen(name)) & HASH_MASK; | |
34 | } | |
35 | ||
36 | void remove_file_hash(struct fio_file *f) | |
37 | { | |
38 | fio_mutex_down(hash_lock); | |
39 | ||
40 | if (f->flags & FIO_FILE_HASHED) { | |
41 | assert(!list_empty(&f->hash_list)); | |
42 | list_del_init(&f->hash_list); | |
43 | f->flags &= ~FIO_FILE_HASHED; | |
44 | } | |
45 | ||
46 | fio_mutex_up(hash_lock); | |
47 | } | |
48 | ||
49 | static struct fio_file *__lookup_file_hash(const char *name) | |
50 | { | |
51 | struct list_head *bucket = &file_hash[hash(name)]; | |
52 | struct list_head *n; | |
53 | ||
54 | list_for_each(n, bucket) { | |
55 | struct fio_file *f = list_entry(n, struct fio_file, hash_list); | |
56 | ||
57 | if (!strcmp(f->file_name, name)) { | |
58 | assert(f->fd != -1); | |
59 | return f; | |
60 | } | |
61 | } | |
62 | ||
63 | dump_hash(); | |
64 | return NULL; | |
65 | } | |
66 | ||
67 | struct fio_file *lookup_file_hash(const char *name) | |
68 | { | |
69 | struct fio_file *f; | |
70 | ||
71 | fio_mutex_down(hash_lock); | |
72 | f = __lookup_file_hash(name); | |
73 | fio_mutex_up(hash_lock); | |
74 | return f; | |
75 | } | |
76 | ||
77 | struct fio_file *add_file_hash(struct fio_file *f) | |
78 | { | |
79 | struct fio_file *alias; | |
80 | ||
81 | if (f->flags & FIO_FILE_HASHED) | |
82 | return NULL; | |
83 | ||
84 | INIT_LIST_HEAD(&f->hash_list); | |
85 | ||
86 | fio_mutex_down(hash_lock); | |
87 | ||
88 | alias = __lookup_file_hash(f->file_name); | |
89 | if (!alias) { | |
90 | f->flags |= FIO_FILE_HASHED; | |
91 | list_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]); | |
92 | } | |
93 | ||
94 | fio_mutex_up(hash_lock); | |
95 | return alias; | |
96 | } | |
97 | ||
98 | void file_hash_init(void *ptr) | |
99 | { | |
100 | unsigned int i; | |
101 | ||
102 | file_hash = ptr; | |
103 | for (i = 0; i < HASH_BUCKETS; i++) | |
104 | INIT_LIST_HEAD(&file_hash[i]); | |
105 | ||
106 | hash_lock = fio_mutex_init(1); | |
107 | } |