blob: 1bb1eb237606096a8d0bbec6b0ec583f34bafc00 [file] [log] [blame]
Jens Axboe380065a2008-03-01 18:56:24 +01001#include <stdlib.h>
2#include <assert.h>
3
4#include "fio.h"
Jens Axboe01743ee2008-06-02 12:19:19 +02005#include "flist.h"
Jens Axboedadf66c2011-10-06 12:37:10 +02006#include "hash.h"
Jens Axboe380065a2008-03-01 18:56:24 +01007
8#define HASH_BUCKETS 512
9#define HASH_MASK (HASH_BUCKETS - 1)
10
Jens Axboe01743ee2008-06-02 12:19:19 +020011unsigned int file_hash_size = HASH_BUCKETS * sizeof(struct flist_head);
Jens Axboe380065a2008-03-01 18:56:24 +010012
Jens Axboe01743ee2008-06-02 12:19:19 +020013static struct flist_head *file_hash;
Jens Axboeb9507812008-06-13 08:38:25 +020014static struct fio_mutex *hash_lock;
Jens Axboe380065a2008-03-01 18:56:24 +010015
Jens Axboe380065a2008-03-01 18:56:24 +010016static unsigned short hash(const char *name)
17{
Jens Axboedadf66c2011-10-06 12:37:10 +020018 return jhash(name, strlen(name), 0) & HASH_MASK;
Jens Axboe380065a2008-03-01 18:56:24 +010019}
20
21void remove_file_hash(struct fio_file *f)
22{
Jens Axboeb9507812008-06-13 08:38:25 +020023 fio_mutex_down(hash_lock);
Jens Axboe380065a2008-03-01 18:56:24 +010024
Jens Axboed6aed792009-06-03 08:41:15 +020025 if (fio_file_hashed(f)) {
Jens Axboe01743ee2008-06-02 12:19:19 +020026 assert(!flist_empty(&f->hash_list));
27 flist_del_init(&f->hash_list);
Jens Axboed6aed792009-06-03 08:41:15 +020028 fio_file_clear_hashed(f);
Jens Axboe380065a2008-03-01 18:56:24 +010029 }
30
Jens Axboeb9507812008-06-13 08:38:25 +020031 fio_mutex_up(hash_lock);
Jens Axboe380065a2008-03-01 18:56:24 +010032}
33
34static struct fio_file *__lookup_file_hash(const char *name)
35{
Jens Axboe01743ee2008-06-02 12:19:19 +020036 struct flist_head *bucket = &file_hash[hash(name)];
37 struct flist_head *n;
Jens Axboe380065a2008-03-01 18:56:24 +010038
Jens Axboe01743ee2008-06-02 12:19:19 +020039 flist_for_each(n, bucket) {
40 struct fio_file *f = flist_entry(n, struct fio_file, hash_list);
Jens Axboe380065a2008-03-01 18:56:24 +010041
Jens Axboe89541102008-09-10 09:07:55 +020042 if (!f->file_name)
43 continue;
44
Jens Axboe380065a2008-03-01 18:56:24 +010045 if (!strcmp(f->file_name, name)) {
46 assert(f->fd != -1);
47 return f;
48 }
49 }
50
Jens Axboe380065a2008-03-01 18:56:24 +010051 return NULL;
52}
53
54struct fio_file *lookup_file_hash(const char *name)
55{
56 struct fio_file *f;
57
Jens Axboeb9507812008-06-13 08:38:25 +020058 fio_mutex_down(hash_lock);
Jens Axboe380065a2008-03-01 18:56:24 +010059 f = __lookup_file_hash(name);
Jens Axboeb9507812008-06-13 08:38:25 +020060 fio_mutex_up(hash_lock);
Jens Axboe380065a2008-03-01 18:56:24 +010061 return f;
62}
63
64struct fio_file *add_file_hash(struct fio_file *f)
65{
66 struct fio_file *alias;
67
Jens Axboed6aed792009-06-03 08:41:15 +020068 if (fio_file_hashed(f))
Jens Axboe380065a2008-03-01 18:56:24 +010069 return NULL;
70
Jens Axboe01743ee2008-06-02 12:19:19 +020071 INIT_FLIST_HEAD(&f->hash_list);
Jens Axboe380065a2008-03-01 18:56:24 +010072
Jens Axboeb9507812008-06-13 08:38:25 +020073 fio_mutex_down(hash_lock);
Jens Axboe380065a2008-03-01 18:56:24 +010074
75 alias = __lookup_file_hash(f->file_name);
76 if (!alias) {
Jens Axboed6aed792009-06-03 08:41:15 +020077 fio_file_set_hashed(f);
Jens Axboe01743ee2008-06-02 12:19:19 +020078 flist_add_tail(&f->hash_list, &file_hash[hash(f->file_name)]);
Jens Axboe380065a2008-03-01 18:56:24 +010079 }
80
Jens Axboeb9507812008-06-13 08:38:25 +020081 fio_mutex_up(hash_lock);
Jens Axboe380065a2008-03-01 18:56:24 +010082 return alias;
83}
84
Jens Axboe5e1d3062008-05-23 11:55:53 +020085void file_hash_exit(void)
86{
87 unsigned int i, has_entries = 0;
88
Jens Axboeb9507812008-06-13 08:38:25 +020089 fio_mutex_down(hash_lock);
Jens Axboe5e1d3062008-05-23 11:55:53 +020090 for (i = 0; i < HASH_BUCKETS; i++)
Jens Axboe01743ee2008-06-02 12:19:19 +020091 has_entries += !flist_empty(&file_hash[i]);
Jens Axboeb9507812008-06-13 08:38:25 +020092 fio_mutex_up(hash_lock);
Jens Axboe5e1d3062008-05-23 11:55:53 +020093
94 if (has_entries)
95 log_err("fio: file hash not empty on exit\n");
96
Jens Axboeb9507812008-06-13 08:38:25 +020097 file_hash = NULL;
98 fio_mutex_remove(hash_lock);
Jens Axboe5e1d3062008-05-23 11:55:53 +020099 hash_lock = NULL;
100}
101
Jens Axboe380065a2008-03-01 18:56:24 +0100102void file_hash_init(void *ptr)
103{
104 unsigned int i;
105
106 file_hash = ptr;
107 for (i = 0; i < HASH_BUCKETS; i++)
Jens Axboe01743ee2008-06-02 12:19:19 +0200108 INIT_FLIST_HEAD(&file_hash[i]);
Jens Axboe380065a2008-03-01 18:56:24 +0100109
Jens Axboeb9507812008-06-13 08:38:25 +0200110 hash_lock = fio_mutex_init(1);
Jens Axboe380065a2008-03-01 18:56:24 +0100111}