-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlong_files_1.cpp
143 lines (124 loc) · 4.43 KB
/
long_files_1.cpp
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
#include "basiccreator.h"
#include "codeelement.h"
#include "editcounter.h"
#include "editmutator.h"
#include "interfaces.h"
#include "projectfile.h"
#include "projectstate.h"
#include <cmath>
#include <cstdlib>
#include <iomanip>
#include <iostream>
#include <map>
#include <memory>
std::vector<id_t> parseCommandLine(int argc, char* argv[])
{
if (argc <= 1)
return std::vector<id_t> {25, 50, 100, 250, 500, 1000, 2500, 5000, 10000, 20000};
bool printHelp = false;
std::vector<id_t> meanFileLength;
for (int i = 1; i < argc; ++i) {
id_t num = std::atoi(argv[i]);
if (num > 0) {
meanFileLength.push_back(num);
} else {
printHelp = true;
std::cerr << "Error: couldn't parse argument '" << argv[i]
<< "' as a number." << std::endl;
}
}
// Handle early-abort cases (help, version, ....)
if (printHelp) {
std::cout << "Usage: " << argv[0] << " [number of files in project]+"
<< std::endl;
exit(EXIT_FAILURE);
}
return meanFileLength;
}
int main(int argc, char *argv[])
{
// Configuration variables and defaults
double fraction = 0.02; // Fraction of elements changed during an edit
id_t nElements = 200000;
id_t nRounds = 45;
int verbose=1;
std::vector<id_t> meanFileLength = parseCommandLine(argc, argv);
// Initialize the behaviors we're going to test
const auto mutator = std::make_unique<EditMutator>(nElements*fraction);
const auto counter = std::make_unique<EditCounter>();
// Main results: mean file length vs mean number of manual merge actions
std::map<double, double> results;
for (const auto length : meanFileLength)
{
// Creation behavior depend on the number of project
const auto creator = std::make_unique<BasicCreator>(nElements / length,
nElements);
// Global bookkeeping storage
ConflictCount total;
// Core simulation loop
std::cerr << "Length" << std::setw(6) << length << ":";
for (id_t i = 0; i < nRounds; ++i)
{
std::cerr << ".";
const auto base = creator->create();
const auto left = mutator->mutate(base);
const auto right = mutator->mutate(base);
if (verbose > 1)
{
std::cerr << "Iteration " << i << ":" << std::endl;
std::cerr << "\tBase " << base.size() << " files." << std::endl;
std::cerr << "\t\t[" << base.fileSizeLimits().first
<< "," << base.fileSizeLimits().second << "]"
<< std::endl;
std::cerr << "\tLeft " << left.size() << " files." << std::endl;
std::cerr << "\tRight " << right.size() << " files." << std::endl;
}
// score and accumulate
ConflictCount cc = counter->count(base, left, right);
if (verbose > 1)
{
std::cerr << "\t" << "Counted: " << cc.elementChanges
<< " total changes." << std::endl;
std::cerr << "\t" << " " << cc.elementConflicts
<< " conflicted changes." << std::endl;
std::cerr << "\t"
<< " " << cc.fileConflicts
<< " out of " << cc.baseFiles
<< " files with conflicts." << std::endl;
std::cerr << "\t" << " " << cc.manualResolutions
<< " manual merge actions required." << std::endl;
}
total += cc;
}
std::cout << std::endl;
if (verbose > 0)
{
std::cerr << "\t" << "Counted: " << total.elementChanges
<< " total changes." << std::endl;
std::cerr << "\t" << " " << total.elementConflicts
<< " conflicted changes." << std::endl;
std::cerr << "\t"
<< " " << total.fileConflicts
<< " out of " << total.baseFiles
<< " files with conflicts." << std::endl;
std::cerr << "\t" << " " << total.manualResolutions
<< " manual merge actions required." << std::endl;
std::cerr << "\t" << " " << total.maxFileSize
<< " maximum file size." << std::endl;
}
std::cerr << std::endl;
results[length]
= total.manualResolutions/static_cast<double>(total.elementChanges);
}
std::cout << "# Length" << "\t" << "% manual" << std::endl;
for (const auto& [length, rate] : results)
{
std::cout << std::setw(8) << std::fixed << std::setprecision(1)
<< length
<< "\t"
<< std::setw(8) << std::fixed << std::setprecision(2)
<< rate*100
<< std::endl;
}
return EXIT_SUCCESS;
}