t/nvmept_trim: increase transfer size for some tests
[fio.git] / dedupe.c
1 #include "fio.h"
2
3 /**
4  * initializes the global dedup workset.
5  * this needs to be called after all jobs' seeds
6  * have been initialized
7  */
8 int init_global_dedupe_working_set_seeds(void)
9 {
10         for_each_td(td) {
11                 if (!td->o.dedupe_global)
12                         continue;
13
14                 if (init_dedupe_working_set_seeds(td, 1))
15                         return 1;
16         } end_for_each();
17
18         return 0;
19 }
20
21 int init_dedupe_working_set_seeds(struct thread_data *td, bool global_dedup)
22 {
23         int tindex;
24         struct thread_data *td_seed;
25         unsigned long long i, j, num_seed_advancements, pages_per_seed;
26         struct frand_state dedupe_working_set_state = {0};
27
28         if (!td->o.dedupe_percentage || !(td->o.dedupe_mode == DEDUPE_MODE_WORKING_SET))
29                 return 0;
30
31         tindex = td->thread_number - 1;
32         num_seed_advancements = td->o.min_bs[DDIR_WRITE] /
33                 min_not_zero(td->o.min_bs[DDIR_WRITE], (unsigned long long) td->o.compress_chunk);
34         /*
35          * The dedupe working set keeps seeds of unique data (generated by buf_state).
36          * Dedupe-ed pages will be generated using those seeds.
37          */
38         td->num_unique_pages = (td->o.size * (unsigned long long)td->o.dedupe_working_set_percentage / 100) / td->o.min_bs[DDIR_WRITE];
39         td->dedupe_working_set_states = malloc(sizeof(struct frand_state) * td->num_unique_pages);
40         if (!td->dedupe_working_set_states) {
41                 log_err("fio: could not allocate dedupe working set\n");
42                 return 1;
43         }
44
45         frand_copy(&dedupe_working_set_state, &td->buf_state);
46         frand_copy(&td->dedupe_working_set_states[0], &dedupe_working_set_state);
47         pages_per_seed = max(td->num_unique_pages / thread_number, 1ull);
48         for (i = 1; i < td->num_unique_pages; i++) {
49                 /*
50                  * When compression is used the seed is advanced multiple times to
51                  * generate the buffer. We want to regenerate the same buffer when
52                  * deduping against this page
53                  */
54                 for (j = 0; j < num_seed_advancements; j++)
55                         __get_next_seed(&dedupe_working_set_state);
56
57                 /*
58                  * When global dedup is used, we rotate the seeds to allow
59                  * generating same buffers across different jobs. Deduplication buffers
60                  * are spread evenly across jobs participating in global dedupe
61                  */
62                 if (global_dedup && i % pages_per_seed == 0) {
63                         td_seed = tnumber_to_td(++tindex % thread_number);
64                         frand_copy(&dedupe_working_set_state, &td_seed->buf_state);
65                 }
66
67                 frand_copy(&td->dedupe_working_set_states[i], &dedupe_working_set_state);
68         }
69
70         return 0;
71 }