monotone

monotone Mtn Source Tree

Root/randomfile.hh

1#ifndef __RANDOMFILE_HH__
2#define __RANDOMFILE_HH__
3
4// Copyright (C) 2002 Graydon Hoare <graydon@pobox.com>
5//
6// This program is made available under the GNU GPL version 2.0 or
7// greater. See the accompanying file COPYING for details.
8//
9// This program is distributed WITHOUT ANY WARRANTY; without even the
10// implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
11// PURPOSE.
12
13#include <string>
14#include <vector>
15#include <boost/lexical_cast.hpp>
16
17#include "randomizer.hh"
18
19struct file_randomizer
20{
21 std::vector<std::string> lines;
22 std::string prefix;
23
24 size_t random_index(bool last_line_ok = true)
25 {
26 if (last_line_ok)
27 return static_cast<size_t>(randomizer::uniform(lines.size()));
28 else
29 {
30 if (lines.size() == 0)
31 return 0;
32 else
33 return static_cast<size_t>(randomizer::uniform(lines.size() - 1));
34 }
35 }
36
37 void set_prefix(std::string const & p)
38 {
39 prefix = p;
40 }
41
42 void append_to(std::vector<std::string> & other)
43 {
44 for (std::vector<std::string>::const_iterator i = lines.begin();
45 i != lines.end(); ++i)
46 other.push_back(prefix + *i);
47 }
48
49 void initial_sequential_lines(int num_lines = 100) {
50 lines.clear();
51 for (int i = 0; i < num_lines; ++i)
52 {
53 lines.push_back(std::string("initial ") + boost::lexical_cast<std::string>(i));
54 }
55 }
56
57 void append_sequential_lines(int num_lines = 10) {
58 lines.clear();
59 for (int i = 0; i < num_lines; ++i)
60 {
61 lines.push_back(std::string("append ") + boost::lexical_cast<std::string>(i));
62 }
63 }
64
65 void prepend_sequential_lines(int num_lines = 10) {
66 lines.clear();
67 for (int i = 0; i < num_lines; ++i)
68 {
69 lines.push_back(std::string("prepend ") + boost::lexical_cast<std::string>(i));
70 }
71 }
72
73 void delete_percent_of_lines_randomly(int percent = 50) {
74 double scale = static_cast<double>(percent) / 100.0;
75 double nlines_d = static_cast<double>(lines.size()) * scale;
76 int nlines = static_cast<int>(nlines_d);
77 for (int i = 0; i < nlines; ++i)
78 lines.erase(lines.begin() + random_index(false));
79 }
80
81 void insert_sequential_percent_of_lines_randomly(int percent = 50) {
82 double scale = static_cast<double>(percent) / 100.0;
83 double nlines_d = static_cast<double>(lines.size()) * scale;
84 int nlines = static_cast<int>(nlines_d);
85 for (int i = 0; i < nlines; ++i)
86 {
87 lines.insert(lines.begin() + random_index(),
88 std::string("insert ") + boost::lexical_cast<std::string>(i));
89 }
90 }
91
92 static void build_random_fork(std::vector<std::string> & ancestor,
93 std::vector<std::string> & left,
94 std::vector<std::string> & right,
95 std::vector<std::string> & merged,
96 int n_hunks = 10)
97 {
98 bool last_was_insert = false;
99 bool last_insert_was_left = false;
100
101 file_randomizer fr;
102 // maybe prepend something to one side or the other
103 if (randomizer::flip())
104 {
105 last_was_insert = true;
106 fr.prepend_sequential_lines();
107 last_insert_was_left = randomizer::flip();
108 if (last_insert_was_left)
109 fr.append_to(left);
110 else
111 fr.append_to(right);
112 fr.append_to(merged);
113 }
114 fr.lines.clear();
115
116 for (int h = 0; h < n_hunks; ++h)
117 {
118 file_randomizer hr;
119 hr.set_prefix(std::string("hunk ") + boost::lexical_cast<std::string>(h) + " -- ");
120 hr.initial_sequential_lines(10);
121 if (randomizer::flip())
122 {
123 bool this_insert_is_left = randomizer::flip();
124 if (last_was_insert && (this_insert_is_left != last_insert_was_left))
125 {
126 fr.set_prefix("spacer ");
127 fr.initial_sequential_lines(3);
128 fr.append_to(left);
129 fr.append_to(right);
130 fr.append_to(ancestor);
131 fr.append_to(merged);
132 fr.set_prefix("");
133 }
134 last_insert_was_left = this_insert_is_left;
135 // doing an insert
136 hr.append_to(ancestor);
137 if (this_insert_is_left)
138 {
139 // inserting in left
140 hr.append_to(right);
141 hr.insert_sequential_percent_of_lines_randomly();
142 hr.append_to(left);
143 }
144 else
145 {
146 // inserting in right
147 hr.append_to(left);
148 hr.insert_sequential_percent_of_lines_randomly();
149 hr.append_to(right);
150 }
151 hr.append_to(merged);
152 last_was_insert = true;
153 }
154 else
155 {
156 // doing a delete
157 hr.append_to(ancestor);
158 if (randomizer::flip())
159 {
160 // deleting in left
161 hr.append_to(right);
162 hr.delete_percent_of_lines_randomly();
163 hr.append_to(left);
164 }
165 else
166 {
167 // deleting in right
168 hr.append_to(left);
169 hr.delete_percent_of_lines_randomly();
170 hr.append_to(right);
171 }
172 hr.append_to(merged);
173 last_was_insert = false;
174 }
175 }
176
177 // maybe append something to one side or the other
178 if (randomizer::flip())
179 {
180 bool this_insert_is_left = randomizer::flip();
181 if (last_was_insert && (this_insert_is_left != last_insert_was_left))
182 {
183 fr.set_prefix("spacer ");
184 fr.initial_sequential_lines(3);
185 fr.append_to(left);
186 fr.append_to(right);
187 fr.append_to(ancestor);
188 fr.append_to(merged);
189 fr.set_prefix("");
190 }
191 fr.append_sequential_lines();
192 if (this_insert_is_left)
193 fr.append_to(left);
194 else
195 fr.append_to(right);
196 fr.append_to(merged);
197 }
198 }
199};
200
201// Local Variables:
202// mode: C++
203// fill-column: 76
204// c-file-style: "gnu"
205// indent-tabs-mode: nil
206// End:
207// vim: et:sw=2:sts=2:ts=2:cino=>2s,{s,\:s,+s,t0,g0,^-2,e-2,n-2,p2s,(0,=s:
208
209#endif // __RANDOMFILE_HH__

Archive Download this file

Branches

Tags

Quick Links:     www.monotone.ca    -     Downloads    -     Documentation    -     Wiki    -     Code Forge    -     Build Status