-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcollect.cpp
More file actions
128 lines (117 loc) · 5.29 KB
/
Copy pathcollect.cpp
File metadata and controls
128 lines (117 loc) · 5.29 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
#include <cmath>
#include <algorithm>
#include "collect.h"
#include <random>
#include <chrono>
#include <string>
#include <climits>
#include <utility>
#define NUM 2
void Collector::update_object_info(int object_id, int disk_id, int pre_unit,int cur_unit) {
if (object_id == 0) return; // Return immediately if object is empty
Object& obj = data_.object[object_id];
for (int r = 0; r < RepNum; ++r) {
if (obj.replica[r] == disk_id) {
for(int i = 1 ;i <= obj.size ; i++){
if(obj.unit[r][i] == pre_unit) { // Found the updated object block
obj.unit[r][i] = cur_unit; // Update the position of the object block on the disk
break;
}
}
}
}
}
std::pair<int,int> Collector::get_partition_index(int tag){
//////// Get partition tag ////////
int index;
for (index = 1; index <= data_.M; index++) {
if (data_.label_assignment[index] == tag) break;
}
///// Partition range //////
int a = data_.disk_partition[(index -1 + data_.M) % data_.M];
int b = data_.disk_partition[(index + data_.M) % data_.M];
return {a, b};
}
void Collector::gc_action()
{
///////////////////////////
scanf("%*s %*s");
printf("GARBAGE COLLECTION\n");
///////////////////////
/////////// Initialize swap operation records for each disk
std::vector<std::vector<std::pair<int, int>>> swap_operations(data_.N + 1);
/////// Calculate read counts for current slice labels //////
std::vector<std::pair<int, int>> label_read_counts; // {Read count, label index}
for (int i = 0; i < data_.M; ++i) {
label_read_counts.emplace_back(data_.fre_read[i][data_.timestamp / FrePerSlicing], i + 1);
}
//////// Sort by read count in descending order ////////
std::sort(label_read_counts.rbegin(), label_read_counts.rend());
///////// Select top NUM labels ////////
std::vector<int> target_labels;
for(int i = 0; i < NUM ; i++){
target_labels.push_back(label_read_counts[i].second);
}
bool flag = true;
///////// Iterate through each disk partition to perform swaps //////////
for(int i = 0; i < data_.N; i++ ){
int num_swap = 0; // Number of swaps for the current disk
for (int label : target_labels) {
std::pair<int, int> partition_index = get_partition_index(label);
int a = partition_index.first;
int b = partition_index.second;
for (int point = a; point <= b;) {
int object_id = data_.disk[i][point];
if (object_id == 0) {
point++; // Skip empty units
continue;
}
Object& obj = data_.object[object_id];
// If not in target label group, try to swap out
if (obj.tag != label) {
// Prioritize finding objects of the target label group from obj.tag
auto [obj_a, obj_b] = get_partition_index(obj.tag);
for (int j = obj_a; j <= obj_b; j++) {
int swap_object_id = data_.disk[i][j];
if (swap_object_id == 0) continue; // Skip empty units
Object& swap_obj = data_.object[swap_object_id];
// If swap_obj.tag belongs to target label group and size is same, swap
if (swap_obj.tag == label && obj.size == swap_obj.size) {
// Swap operation
int rep_id = get_replica_id(object_id, i);
int swap_rep_id = get_replica_id(swap_object_id, i);
std::swap(data_.disk[i][point], data_.disk[i][j]);
for (int u = 1; u <= obj.size; u++) {
int& x = data_.object[object_id].unit[rep_id][u];
int& y = data_.object[swap_object_id].unit[swap_rep_id][u];
std::swap(x, y);
std::swap(data_.disk[i][x], data_.disk[i][y]); // Update position on disk
swap_operations[i].emplace_back(x, y); // Record swap operation
num_swap++;
if (num_swap == data_.K) {
flag = false; // Reached swap limit
break;
}
}
// update_object_info(object_id, i, point, j);
// update_object_info(swap_object_id, i, j, point);
}
if (!flag) break; // Reached swap limit
}
}
point += obj.size; // Skip swapped objects
}
}
}
//////////////////////////////////
// for (int i = 1; i <= data_.N; i++) {
// printf("0\n");
// }
for (int i = 0; i < data_.N; i++) {
printf("%d\n", (int)swap_operations[i].size()); // Output number of swap operations for current disk
for (const auto& op : swap_operations[i]) {
printf("%d %d\n", op.first, op.second); // Output storage unit numbers for swap operations
}
}
fflush(stdout);
}