-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathwrite.cpp
More file actions
157 lines (131 loc) · 6.02 KB
/
write.cpp
File metadata and controls
157 lines (131 loc) · 6.02 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
#include "write.h"
#include <random>
bool Writer::is_disk_space_sufficient(const std::vector<int> &disk_unit, int size) {// Check if disk space is sufficient
int free_space = 0;
// Iterate through disk storage units to count free space
for (int i = 1; i <= data_.V; i++) {
if (disk_unit[i] == 0) { // Free block
free_space++;
}
if (free_space >= size) { // If free space is sufficient
return true;
}
}
return false; // Insufficient free space
}
int getRandomNumber(int a, int b) {
return a + std::rand() % (b - a + 1);
}
void Writer::do_object_write(std::vector<int> &object_unit, std::vector<int> &disk_unit, int size, int tag, int object_id) {
int current_write_point = 0; // Current write position
// Area range corresponding to this tag
int index;
for (index = 1; index <= data_.M; index++) {
if (data_.label_assignment[index] == tag) break;
}
// int a = data_.disk_partition[index -1];
// int b = data_.disk_partition[index];
// int a = (data_.disk_partition[(index -1 + data_.M) % data_.M] + data_.vec[(index -1 + data_.M) % data_.M] )% data_.V;
// int b = ( data_.disk_partition[(index + data_.M) % data_.M]+ data_.vec[(index + data_.M) % data_.M] )% data_.V;
int a = data_.disk_partition[(index -1 + data_.M) % data_.M];
int b = data_.disk_partition[(index + data_.M) % data_.M];
int bf = data_.disk_partition[data_.M];
// Use do_segregated_fit function to implement segregated fit allocation
do_segregated_fit(object_unit, disk_unit, size, object_id, a, b, ¤t_write_point);
// int neighbor = 1;
// if (index == data_.M) neighbor = -1;
// while (current_write_point < size) {
// int idx = index + neighbor;
// int a = data_.disk_partition[idx - 1];
// int b = data_.disk_partition[idx];
// do_segregated_fit(object_unit, disk_unit, size, object_id, a, b, ¤t_write_point);
// if (current_write_point == size) break;
// if (neighbor > 0 && index - neighbor < 1) neighbor++;
// else if (neighbor > 0) neighbor *= -1;
// else if (neighbor < 0 && index - neighbor > data_.M) neighbor--;
// else neighbor = neighbor * (-1) + 1;
// }
if(current_write_point < size) {
do_segregated_fit(object_unit, disk_unit, size, object_id, 1, data_.V, ¤t_write_point);
}
if(current_write_point == size){// Storage successful
change_disk = false;
change_count = 0;
return;
}
if(current_write_point < size && change_count != data_.N) {// Current disk does not have enough continuous space to store this object
change_disk=true;
change_count++;
return;
}
assert(current_write_point == size);
}
void Writer::write_action() {
int n_write;
scanf("%d", &n_write);
for (int i = 1; i <= n_write; i++) {
int id, size, tag;
scanf("%d%d%d", &id, &size,&tag); // Skip reading obj_tag, id starts from 1, increments by 1
// if (id > 0.9 * data_.object.size()) {
// data_.object.resize(data_.object.size() * 2);
// }
data_.object.at(id).last_request_point = 0; // First object has no previous request
data_.object.at(id).size = size;
data_.object.at(id).tag = tag;
data_.object.at(id).is_delete = false;
std::vector<int> disk_used(data_.N + 1 , 0); // Mark if disk has been used
// Allocate space for each replica of the object, j: replica index
// // First store one on the disk closest to label
// int min_dist = data_.V, disk_id = 0;
// int index;
// for (index = 1; index <= data_.M; index++) {
// if (data_.label_assignment[index] == tag) break;
// }
// int a = data_.disk_partition[index - 1];
// for (int i = 1; i <= data_.N; i++) {
// int distance, disk_point = data_.disk_point[i];
// if (disk_point <= a) distance = a - disk_point;
// else distance = data_.V - disk_point + a;
// if (distance < min_dist) {
// min_dist = distance;
// disk_id = i;
// }
// }
// disk_used[disk_id] = 1;
// if (is_disk_space_sufficient(data_.disk.at(disk_id), size)) {// 检查硬盘剩余容量是否足够
// // 分配空间
// data_.object.at(id).replica[3] = disk_id;
// data_.object.at(id).unit[3].resize(size + 1, 0);
// do_object_write(data_.object.at(id).unit[3], data_.disk.at(disk_id), size, tag, id);
// }
for (int j = 1; j <= RepNum; j++) {
do {
for (int n = 0; n < data_.N; n++) {
int try_disk_id = (id + j + n) % data_.N + 1; // Disk selection strategy (sequential)
if(!disk_used[try_disk_id]) {// Current disk has not been used by replica
if (!is_disk_space_sufficient(data_.disk.at(try_disk_id), size)) {// Check if remaining disk capacity is sufficient
continue; // If disk space is insufficient, try next disk
}
// Allocate space
data_.object.at(id).replica[j] = try_disk_id;
data_.object.at(id).unit[j].resize(size + 1, 0);
do_object_write(data_.object.at(id).unit[j], data_.disk.at(try_disk_id), size, tag, id);
if(!change_disk) {
disk_used[try_disk_id] = 1;
break;
}
}
}
}while(change_disk);
}
printf("%d\n", id);
for (int j = 1; j <= RepNum; j++) {
printf("%d", data_.object.at(id).replica[j]);
for (int k = 1; k <= size; k++) {
printf(" %d", data_.object.at(id).unit[j][k]);
}
printf("\n");
}
}
fflush(stdout);
}