ewmscp  ..
fileopstest.cpp
Go to the documentation of this file.
1 #include <thread>
2 #include <mutex>
3 #include <condition_variable>
4 #include <string>
5 #include <vector>
6 #include <deque>
7 #include <iostream>
8 #include <iomanip>
9 #include <system_error>
10 #include <sstream>
11 #include <chrono>
12 #include <algorithm>
13 #include <random>
14 #include <map>
15 #include <cstdlib>
16 #include <list>
17 
18 #include <Options.h>
19 #include "throwcall.h"
20 
21 #include <sys/types.h>
22 #include <sys/stat.h>
23 #include <sys/statvfs.h>
24 #include <fcntl.h>
25 #include <unistd.h>
26 #include <string.h>
27 typedef std::chrono::system_clock clock_type;
28 //typedef std::chrono::high_resolution_clock clock_type;
29 
30 
31 
32 
33 class testFile {
34  public:
35  std::string name;
36  clock_type::duration deltaTCreate;
37  clock_type::duration deltaTWrite;
38  clock_type::duration deltaTClose1;
39  clock_type::duration deltaTOpen;
40  clock_type::duration deltaTRead;
41  clock_type::duration deltaTClose2;
42  clock_type::duration deltaTUnlink;
43  clock_type::duration deltaTQueue;
44  clock_type::time_point tCreate;
45  clock_type::time_point tOpen;
46  clock_type::time_point tClose1;
47  clock_type::time_point tClose2;
48  size_t bytes;
49 };
50 
51 class buffqueue {
52  private:
53  std::deque<testFile*> queue;
54  std::mutex queue_mutex;
55  std::condition_variable cv;
57  public:
59  void enqueue(testFile *f) {
60  std::unique_lock<decltype(queue_mutex)> lock(queue_mutex);
61  queue.emplace_back(f);
62  cv.notify_all();
63  }
65  std::unique_lock<decltype(queue_mutex)> lock(queue_mutex);
66 
67  while (queue.empty()) {
68  if (!expectingInput) {
69  return nullptr;
70  }
71 
72  cv.wait(lock);
73  }
74 
75  auto f = queue.front();
76  queue.pop_front();
77  return f;
78  }
79  decltype(queue.size()) size() {
80  return queue.size();
81  }
82  void endOfInput() {
83  expectingInput = false;
84  cv.notify_all();
85  }
86 };
87 
88 
89 class buffstuff {
90  public:
91  buffstuff(unsigned int aBlockSize): blockSize(aBlockSize) {
92  writeBuffer.reserve(blockSize / sizeof(int));
93  readBuffer.reserve(blockSize / sizeof(int));
94 
95  for (unsigned int i = 0; i < writeBuffer.capacity(); i++) {
96  writeBuffer.emplace_back(~writeBuffer.capacity() - i);
97  }
98  }
99  std::vector<int> writeBuffer;
101  unsigned int blockSize;
102 };
103 
104 testFile* createFile(const char *workdir, unsigned int index, buffstuff& buffer, size_t size, std::chrono::system_clock::time_point& stat_time) {
105  testFile* f = new testFile();
106  std::ostringstream name;
107  name << workdir
108  << "/testfile_"
109  << std::this_thread::get_id()
110  << "_"
111  << index;
112  f->name = name.str();
113  f->bytes = size;
114  f->tCreate = clock_type::now();
115  auto fd = throwcall::badval(open(f->name.c_str(), O_CREAT | O_WRONLY, 0755), -1,
116  "can't open ", f->name);
117  auto now = clock_type::now();
118  f->deltaTCreate = now - f->tCreate;
119  {
120  struct stat newstat;
121  throwcall::good0(fstat(fd, &newstat), "can't stat file");
122  stat_time = std::chrono::time_point<std::chrono::system_clock>(std::chrono::nanoseconds(newstat.st_mtim.tv_sec * 1000000000 + newstat.st_mtim.tv_nsec));
123  }
124  auto before = clock_type::now();
125  throwcall::badval(write(fd, buffer.writeBuffer.data(), f->bytes), -1,
126  "write ", f->name);
127  now = clock_type::now();
128  f->deltaTWrite = now - before;
129  before = now;
130  throwcall::good0(close(fd), "can't close ", f->name);
131  f->tClose1 = clock_type::now();
132  f->deltaTClose1 = f->tClose1 - before;
133  return f;
134 }
136  f->tOpen = clock_type::now();
137  auto fd = throwcall::badval(open(f->name.c_str(), O_RDONLY), -1,
138  "can't open fotr read", f->name);
139  auto now = clock_type::now();
140  f->deltaTOpen = now - f->tOpen;
141  f->deltaTQueue = f->tOpen - f->tClose1;
142  auto before = now;
143  throwcall::badval(read(fd, buffer.readBuffer.data(), f->bytes), -1,
144  "can't read from ", f->name);
145  now = clock_type::now();
146  f->deltaTRead = now - before;
147 
148  if (memcmp(buffer.writeBuffer.data(), buffer.readBuffer.data(), f->bytes) != 0) {
149  throw std::runtime_error("values in file " + f->name);
150  }
151 
152  before = clock_type::now();
153  throwcall::good0(close(fd), "can't close after reading ", f->name);
154  now = clock_type::now();
155  f->tClose2 = now;
156  f->deltaTClose2 = now - before;
157  before = now;
158  throwcall::good0(unlink(f->name.c_str()), "can't unlink ", f->name);
159  now = clock_type::now();
160  f->deltaTUnlink = now - before;
161 }
162 
163 
164 void bunch_wait(long int bunchTime) {
165  if (bunchTime > 0) {
166  auto now = std::chrono::system_clock::now();
167  auto seconds = std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch()).count();
168  auto divresult = std::div(seconds, bunchTime);
169  auto then = std::chrono::system_clock::time_point(std::chrono::seconds(divresult.quot * bunchTime + bunchTime));
170  std::this_thread::sleep_until(then);
171  }
172 }
173 
174 static options::single<int>bunchTime('B', "bunchTime", "bunching time for requests (seconds)", 0);
175 static options::single<int>bunchStart('s', "startTime", "bunching time for starts (seconds)", 0);
176 
177 class timeRecords {
178  typedef std::chrono::time_point<std::chrono::system_clock, std::chrono::milliseconds> mapTimeType;
179  std::mutex recordMutex;
180  std::map<mapTimeType, unsigned int> timeMap;
181  public:
182  template <typename InputIt> void record(InputIt begin, InputIt end) {
183  for (auto it = begin; it != end; ++it) {
184  record(*it);
185  }
186  }
187  void record(std::chrono::system_clock::time_point when) {
188  std::unique_lock<decltype(recordMutex)> lock(recordMutex);
189  ++(timeMap[std::chrono::time_point_cast<mapTimeType::duration>(when)]);
190  }
191  void print(const std::string& prefix) {
192  for (const auto& it : timeMap) {
193  auto then = std::chrono::system_clock::to_time_t(it.first);
194  auto milliseconds = std::chrono::duration_cast<std::chrono::milliseconds>(it.first.time_since_epoch()).count() % 1000;
195  std::cout << prefix <<
196  //std::put_time(std::localtime(&then), "%F %T")
197  then
198  << "." << std::setw(3) << std::setfill('0') << milliseconds << " " << it.second << "\n";
199  }
200  }
201 };
202 
206 
207 
209  public:
215  };
216  private:
217  std::mt19937 generator;
218  std::geometric_distribution<size_t> geometric_dist;
219  std::uniform_int_distribution<size_t> uniform_dist;
220  std::normal_distribution<double> normal_dist;
222  size_t parameter1;
223  size_t parameter2;
224  size_t maxFileSize;
225  public:
226  fileSizeGenerator(const std::string& aDistribution,
227  size_t size_parameter1,
228  size_t size_parameter2,
229  size_t max_size) :
230  parameter1(size_parameter1),
231  parameter2(size_parameter2),
232  maxFileSize(max_size) {
233  static std::random_device rd;
234  generator.seed(rd());
235 
236  if (aDistribution == "constant") {
238  } else if (aDistribution == "uniform") {
240  uniform_dist.param(decltype(uniform_dist)::param_type(parameter1, parameter2));
241  } else if (aDistribution == "geometric") {
243  geometric_dist.param(decltype(geometric_dist)::param_type(1. / parameter1));
244  } else if (aDistribution == "gauss") {
246  normal_dist.param(decltype(normal_dist)::param_type(static_cast<double>(parameter1),
247  static_cast<double>(parameter2)));
248  } else {
249  throw std::runtime_error("bad distribution parameter");
250  }
251  }
252  size_t getNumber() {
253  size_t result;
254 
255  switch (distribution) {
256  case constant:
257  result = parameter1;
258  break;
259 
260  case uniform:
261  result = uniform_dist(generator);
262  break;
263 
264  case geometric:
265  result = geometric_dist(generator);
266  break;
267 
268  case gauss:
269  result = normal_dist(generator);
270  break;
271 
272  default:
273  return 0;
274  }
275 
276  if (result > maxFileSize) {
277  result = maxFileSize;
278  }
279 
280  return result;
281  }
282 };
283 
284 static options::single<std::string> distribution('d', "distribution", "distribution type", "constant",
285 {"constant", "uniform", "geometric", "gauss"});
286 static options::single<size_t> parameter1('\0', "parameter1", "1st distribution paramater, avg/min file size", 1024);
287 static options::single<size_t> parameter2('\0', "parameter2", "2nd distribution paramater, sigma/max file size", 2048);
288 
289 
290 void creator(buffqueue* queue, const char *workdir, unsigned int repeat, unsigned long blockSize, unsigned int maxQueueDepth) {
291  buffstuff buffer(blockSize);
292  fileSizeGenerator generator(distribution, parameter1, parameter2, blockSize);
293 
294  std::list<std::chrono::system_clock::time_point> startTimes;
295  std::list<std::chrono::system_clock::time_point> statTimes;
296 
298 
299  for (decltype(repeat) index = 0; index < repeat; index++) {
300  while (queue->size() > maxQueueDepth) {
301  std::this_thread::yield();
302  }
303 
304  auto size = generator.getNumber();
306  startTimes.emplace_back(std::chrono::system_clock::now());
307  std::chrono::system_clock::time_point stat_time;
308  auto f = createFile(workdir, index, buffer, size, stat_time);
309  statTimes.emplace_back(stat_time);
310  queue->enqueue(f);
311  }
312 
313  creationRecords.record(startTimes.begin(), startTimes.end());
314  mtimeRecords.record(statTimes.begin(), statTimes.end());
315 }
316 
317 void consumer(buffqueue* queue, buffqueue* results, unsigned long blockSize) {
318  buffstuff buffer(blockSize);
319  std::list<std::chrono::system_clock::time_point> startTimes;
320 
322 
323  while (true) {
324  auto f = queue->dequeue();
325 
326  if (f == nullptr) {
327  break;
328  }
329 
331  startTimes.emplace_back(std::chrono::system_clock::now());
332  readAndDeleteFile(f, buffer);
333  results->enqueue(f);
334  }
335 
336  consumptionRecords.record(startTimes.begin(), startTimes.end());
337 }
338 template <typename TC> class statCollectionBase {
339  private:
340  std::string name;
341  std::string unit;
342  public:
343  statCollectionBase(const std::string& aName,
344  const std::string& aUnit = "s") : name(aName), unit(aUnit) {};
345  virtual void print(unsigned long n) = 0;
346  virtual void add(TC* /*what*/) {};
347  const std::string& getName() const {
348  return name;
349  };
350  const std::string& getUnit() const {
351  return unit;
352  };
353 };
354 class dummyMember {};
355 template <typename T, typename TC = testFile> class statCollection: public statCollectionBase<TC> {
356  public:
357  typename std::conditional<std::is_void<TC>::value, dummyMember, T TC::*>::type sourceMember;
358  T sum;
359  T min;
360  T max;
361  void addValue(T value) {
362  sum += value;
363 
364  if (value < min) {
365  min = value;
366  }
367 
368  if (value > max) {
369  max = value;
370  }
371  };
372  void add(TC* what) {
373  addValue(what->*sourceMember);
374  }
375  template < typename TT = T, typename TCC = TC, typename std::enable_if < std::is_arithmetic<TT>::value && ! std::is_void<TCC>::value >::type..., class ... Types >
376  statCollection(decltype(sourceMember) aSourceMember, Types ... args) :
377  statCollectionBase<TC>(args...),
378  sourceMember(aSourceMember),
379  sum(0),
380  min(std::numeric_limits<T>::max()),
381  max(std::numeric_limits<T>::lowest()) {
382  };
383  template <typename TT = T, typename std::enable_if <std::is_arithmetic<TT>::value>::type..., class ... Types>
384  statCollection(Types ... args) :
385  statCollectionBase<TC>(args...),
386  sum(0),
387  min(std::numeric_limits<T>::max()),
388  max(std::numeric_limits<T>::lowest()) {
389  };
390  template < typename TT = T, typename std::enable_if < !std::is_arithmetic<TT>::value >::type..., class ... Types >
391  statCollection(decltype(sourceMember) aSourceMember, Types ... args) :
392  statCollectionBase<TC>(args...),
393  sourceMember(aSourceMember),
394  sum(T::zero()),
395  min(T::max()),
396  max(T::min()) {
397  };
398  template<typename TT = T>
399  typename std::enable_if < !std::is_arithmetic<TT>::value >::type
400  _print(unsigned long n) {
401  std::cout << this->getName() << " avg: " << std::scientific
402  << std::chrono::duration_cast<std::chrono::duration<double>>(sum / n).count()
403  << this->getUnit() << ", min: "
404  << std::chrono::duration_cast<std::chrono::duration<double>>(min).count()
405  << this->getUnit() << ", max: "
406  << std::chrono::duration_cast<std::chrono::duration<double>>(max).count()
407  << this->getUnit() << "\n";
408  }
409  template<typename TT = T>
410  typename std::enable_if <std::is_arithmetic<TT>::value>::type
411  _print(unsigned long n) {
412  std::cout << this->getName() << " avg: "
413  << sum / n
414  << this->getUnit() << ", min: "
415  << min
416  << this->getUnit() << ", max: "
417  << max
418  << this->getUnit() << "\n";
419  }
420  void print(unsigned long n) override {
421  _print(n);
422  }
423 };
424 template <typename T, typename TC, class ... Types> statCollection<T, TC>*
425 statCollectionFactory(T TC::* member, Types...args) {
426  return new typename statCollection<T, TC>::statCollection(member, args...);
427 }
428 
429 class timeSpan {
430  clock_type::time_point start;
431  clock_type::time_point stop;
432  public:
433  timeSpan(): start(clock_type::time_point::max()),
434  stop(clock_type::time_point::min()) {
435  }
436  void update(clock_type::time_point aStart,
437  clock_type::time_point aStop) {
438  if (aStart < start) {
439  start = aStart;
440  }
441 
442  if (aStop > stop) {
443  stop = aStop;
444  }
445  }
446  void update(clock_type::time_point aTime) {
447  if (aTime < start) {
448  start = aTime;
449  }
450 
451  if (aTime > stop) {
452  stop = aTime;
453  }
454  }
455  std::chrono::duration<double> span() {
456  return std::chrono::duration_cast<std::chrono::duration<double>>(stop - start);
457  }
458 };
459 
460 void collectStats(buffqueue* results) {
461  unsigned long n(0);
462  statCollection<double> writeSpeed("write speed ", "MiB/s");
463  statCollection<double> readSpeed("read speed ", "MiB/s");
464  std::vector<statCollectionBase<testFile>*> stats;
465  stats.emplace_back(statCollectionFactory(&testFile::deltaTCreate, "File creation"));
466  stats.emplace_back(statCollectionFactory(&testFile::deltaTWrite, "Write to file"));
467  stats.emplace_back(statCollectionFactory(&testFile::deltaTClose1, "Close file 1 "));
468  stats.emplace_back(statCollectionFactory(&testFile::deltaTOpen, "Open for read"));
469  stats.emplace_back(statCollectionFactory(&testFile::deltaTRead, "Read fr. file"));
470  stats.emplace_back(statCollectionFactory(&testFile::deltaTClose2, "Close file 2 "));
471  stats.emplace_back(statCollectionFactory(&testFile::deltaTUnlink, "Unlink file "));
472  stats.emplace_back(statCollectionFactory(&testFile::deltaTQueue, "Wait wr/rd "));
473  auto fileSize = statCollectionFactory(&testFile::bytes, "file size ", "Bytes");
474  stats.emplace_back(fileSize);
475 
476  timeSpan tWrite;
477  timeSpan tRead;
478  timeSpan tCreations;
479  timeSpan tOpens;
480 
481 
482  std::map<size_t, unsigned int> sizeHisto;
483 
484  while (true) {
485  auto f = results->dequeue();
486 
487  if (f == nullptr) {
488  break;
489  }
490 
491  n++;
492  tWrite.update(f->tCreate, f->tClose1);
493  tRead.update(f->tOpen, f->tClose2);
494  tCreations.update(f->tCreate);
495  tOpens.update(f->tOpen);
496  {
497  unsigned int i = 1;
498 
499  while (i < f->bytes) {
500  i <<= 1;
501  }
502 
503  ++sizeHisto[i];
504  }
505 
506  for (auto stat : stats) {
507  stat->add(f);
508  }
509 
510  writeSpeed.addValue(f->bytes / (1024 * 1024 *
511  std::chrono::duration_cast<std::chrono::duration<double>>(f->deltaTWrite).count()));
512  readSpeed.addValue(f->bytes / (1024 * 1024 *
513  std::chrono::duration_cast<std::chrono::duration<double>>(f->deltaTRead).count()));
514  /*
515  std::cout << f->name
516  << " cr: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTCreate).count()
517  << " wr: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTWrite).count()
518  << " cl: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTClose1).count()
519  << " op: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTOpen).count()
520  << " rd: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTRead).count()
521  << " cl: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTClose2).count()
522  << " rm: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTUnlink).count()
523  << " qu: " << std::chrono::duration_cast<std::chrono::nanoseconds>(f->deltaTQueue).count()
524  << "\n";
525  */
526  }
527 
528  std::cout << "file sizes in bytes:\n";
529  size_t from = 0;
530 
531  for (auto bin : sizeHisto) {
532  std::cout << std::setw(10) << std::right << from << " to " << bin.first << "\t" << bin.second << "\n";
533  from = bin.first;
534  }
535 
536  stats.push_back(&writeSpeed);
537  stats.push_back(&readSpeed);
538 
539  for (auto stat : stats) {
540  stat->print(n);
541  }
542 
543  auto deltaTWrite = tWrite.span().count();
544  std::cout << "total time spent writing: "
545  << deltaTWrite
546  << "s, with "
547  << fileSize->sum / (1024 * 1024 * deltaTWrite)
548  << "MB/s \n";
549  auto deltaTRead = tRead.span().count();
550  std::cout << "total time spent reading: "
551  << deltaTRead
552  << "s, with "
553  << fileSize->sum / (1024 * 1024 * deltaTRead)
554  << "MB/s \n";
555  auto deltaTCreate = tCreations.span().count();
556  auto deltaTOpen = tOpens.span().count();
557  std::cout << n << " files created in " << deltaTCreate << "s: " << n / deltaTCreate << "Creations/s\n";
558  std::cout << n << " files opene in " << deltaTOpen << "s: " << n / deltaTOpen << "Opens/s\n";
559 }
560 
561 
562 int main(int argc, const char *argv[]) {
563  options::parser parser("fileopstest", "", {});
564  options::single<unsigned>nCreators('w', "nCreators", "number of creator threads", sysconf(_SC_NPROCESSORS_ONLN));
565  options::single<unsigned>nConsumers('r', "nConsumers", "number of consumer threads", sysconf(_SC_NPROCESSORS_ONLN));
566  options::single<unsigned>nRepeat('c', "nRepeat", "number of files per thread", 1);
567  options::single<unsigned>maxQueueDepth('q', "maxQueueDepth", "maximum depth of file queue", 100);
568  options::positional<options::single<std::string>>workdir(10, "workdir", "directory to work in");
569  options::single<size_t>blockSize('b', "blockSize", "block size: 0 fs native block size", 0);
570  options::single<int>consumerDelay('D', "consumerDelay", "consumer delay", 0);
571 
572  parser.fParse(argc, argv);
573 
574  if (blockSize == 0) {
575  struct statvfs statbuf;
576  throwcall::good0(statvfs(workdir.c_str(), &statbuf), "can't stat workdir fs");
577  size_t& bla = blockSize;
578  bla = statbuf.f_bsize;
579  }
580 
581  std::cout << "Will create " << nRepeat << " files in " << nCreators << " threads with " << blockSize << std::hex << " (0x" << blockSize << ", " << std::dec << blockSize / 1024 << "k, " << blockSize / (1024 * 1024) << "M) blocks," << std::endl;
582  std::cout << "Consuming them with " << nConsumers << " threads, the queue should not grow above " << maxQueueDepth << std::endl;
583 
584  buffqueue queue;
585  buffqueue results;
586  std::vector<std::thread> creators;
587  std::vector<std::thread> consumers;
588 
589  for (unsigned index = 0; index < nCreators; index++) {
590  creators.emplace_back(std::thread(creator, &queue, workdir.c_str(), nRepeat, blockSize, maxQueueDepth));
591  }
592 
593  std::this_thread::sleep_for(std::chrono::seconds(consumerDelay.fGetValue()));
594 
595  for (unsigned index = 0; index < nConsumers; index++) {
596  consumers.emplace_back(std::thread(consumer, &queue, &results, blockSize));
597  }
598 
599  auto collector = std::thread(collectStats, &results);
600 
601  for (auto & tr : creators) {
602  tr.join();
603  }
604 
605  queue.endOfInput();
606 
607  for (auto & tr : consumers) {
608  tr.join();
609  }
610 
611  results.endOfInput();
612  collector.join();
613  std::cout << "creation times:\n";
614  creationRecords.print("file creation time: ");
615  std::cout << "\nstat times:\n";
616  mtimeRecords.print("file stat time: ");
617  std::cout << "\nconsumption times:\n";
618  consumptionRecords.print("file consumption time: ");
619  return 0;
620 }
fileSizeGenerator::maxFileSize
size_t maxFileSize
Definition: fileopstest.cpp:224
statCollectionBase::add
virtual void add(TC *)
Definition: fileopstest.cpp:346
statCollectionBase::getUnit
const std::string & getUnit() const
Definition: fileopstest.cpp:350
bunchStart
static options::single< int > bunchStart('s', "startTime", "bunching time for starts (seconds)", 0)
options::parser
class that contains the parser, i.e. does that option handling
Definition: Options.h:363
testFile
Definition: fileopstest.cpp:33
options::single< int >
timeRecords
Definition: fileopstest.cpp:177
main
int main(int argc, const char *argv[])
Definition: fileopstest.cpp:562
statCollection::_print
std::enable_if< std::is_arithmetic< TT >::value >::type _print(unsigned long n)
Definition: fileopstest.cpp:411
fileSizeGenerator::parameter1
size_t parameter1
Definition: fileopstest.cpp:222
fileSizeGenerator::distribution
distributionType distribution
Definition: fileopstest.cpp:221
buffstuff::buffstuff
buffstuff(unsigned int aBlockSize)
Definition: fileopstest.cpp:91
testFile::deltaTClose2
clock_type::duration deltaTClose2
Definition: fileopstest.cpp:41
statCollection::sum
T sum
Definition: fileopstest.cpp:358
testFile::deltaTCreate
clock_type::duration deltaTCreate
Definition: fileopstest.cpp:36
readAndDeleteFile
void readAndDeleteFile(testFile *f, buffstuff &buffer)
Definition: fileopstest.cpp:135
buffqueue::buffqueue
buffqueue()
Definition: fileopstest.cpp:58
buffqueue
Definition: fileopstest.cpp:51
testFile::deltaTUnlink
clock_type::duration deltaTUnlink
Definition: fileopstest.cpp:42
throwcall::badval
T badval(T call, t badvalue, const Args &... args)
template function to wrap system calls that return a special bad value on failure
Definition: throwcall.h:54
timeRecords::timeMap
std::map< mapTimeType, unsigned int > timeMap
Definition: fileopstest.cpp:180
testFile::deltaTWrite
clock_type::duration deltaTWrite
Definition: fileopstest.cpp:37
testFile::bytes
size_t bytes
Definition: fileopstest.cpp:48
statCollectionBase::unit
std::string unit
Definition: fileopstest.cpp:341
buffstuff::readBuffer
decltype(writeBuffer) readBuffer
Definition: fileopstest.cpp:100
timeRecords::record
void record(std::chrono::system_clock::time_point when)
Definition: fileopstest.cpp:187
buffqueue::cv
std::condition_variable cv
Definition: fileopstest.cpp:55
statCollection::addValue
void addValue(T value)
Definition: fileopstest.cpp:361
statCollection
Definition: fileopstest.cpp:355
fileSizeGenerator::distributionType
distributionType
Definition: fileopstest.cpp:210
testFile::tClose2
clock_type::time_point tClose2
Definition: fileopstest.cpp:47
statCollectionBase
Definition: fileopstest.cpp:338
timeRecords::print
void print(const std::string &prefix)
Definition: fileopstest.cpp:191
timeSpan::update
void update(clock_type::time_point aTime)
Definition: fileopstest.cpp:446
testFile::deltaTQueue
clock_type::duration deltaTQueue
Definition: fileopstest.cpp:43
fileSizeGenerator::uniform
@ uniform
Definition: fileopstest.cpp:212
fileSizeGenerator
Definition: fileopstest.cpp:208
mtimeRecords
static timeRecords mtimeRecords
Definition: fileopstest.cpp:204
testFile::tCreate
clock_type::time_point tCreate
Definition: fileopstest.cpp:44
Options.h
testFile::deltaTRead
clock_type::duration deltaTRead
Definition: fileopstest.cpp:40
buffstuff
Definition: fileopstest.cpp:89
bunch_wait
void bunch_wait(long int bunchTime)
Definition: fileopstest.cpp:164
statCollection::print
void print(unsigned long n) override
Definition: fileopstest.cpp:420
fileSizeGenerator::uniform_dist
std::uniform_int_distribution< size_t > uniform_dist
Definition: fileopstest.cpp:219
parameter2
static options::single< size_t > parameter2('\0', "parameter2", "2nd distribution paramater, sigma/max file size", 2048)
testFile::name
std::string name
Definition: fileopstest.cpp:35
timeRecords::mapTimeType
std::chrono::time_point< std::chrono::system_clock, std::chrono::milliseconds > mapTimeType
Definition: fileopstest.cpp:178
timeSpan::update
void update(clock_type::time_point aStart, clock_type::time_point aStop)
Definition: fileopstest.cpp:436
statCollectionBase::statCollectionBase
statCollectionBase(const std::string &aName, const std::string &aUnit="s")
Definition: fileopstest.cpp:343
timeRecords::record
void record(InputIt begin, InputIt end)
Definition: fileopstest.cpp:182
testFile::deltaTOpen
clock_type::duration deltaTOpen
Definition: fileopstest.cpp:39
bunchTime
static options::single< int > bunchTime('B', "bunchTime", "bunching time for requests (seconds)", 0)
fileSizeGenerator::parameter2
size_t parameter2
Definition: fileopstest.cpp:223
throwcall.h
statCollection::_print
std::enable_if< !std::is_arithmetic< TT >::value >::type _print(unsigned long n)
Definition: fileopstest.cpp:400
options::single::fGetValue
const T & fGetValue() const
Definition: Options.h:589
timeSpan
Definition: fileopstest.cpp:429
fileSizeGenerator::getNumber
size_t getNumber()
Definition: fileopstest.cpp:252
buffqueue::queue
std::deque< testFile * > queue
Definition: fileopstest.cpp:53
fileSizeGenerator::normal_dist
std::normal_distribution< double > normal_dist
Definition: fileopstest.cpp:220
timeSpan::start
clock_type::time_point start
Definition: fileopstest.cpp:430
statCollection::sourceMember
std::conditional< std::is_void< TC >::value, dummyMember, T TC::* >::type sourceMember
Definition: fileopstest.cpp:357
statCollectionFactory
statCollection< T, TC > * statCollectionFactory(T TC::*member, Types...args)
Definition: fileopstest.cpp:425
statCollectionBase::name
std::string name
Definition: fileopstest.cpp:340
buffqueue::enqueue
void enqueue(testFile *f)
Definition: fileopstest.cpp:59
fileSizeGenerator::constant
@ constant
Definition: fileopstest.cpp:211
fileSizeGenerator::gauss
@ gauss
Definition: fileopstest.cpp:214
fileSizeGenerator::generator
std::mt19937 generator
Definition: fileopstest.cpp:217
buffstuff::writeBuffer
std::vector< int > writeBuffer
Definition: fileopstest.cpp:99
consumer
void consumer(buffqueue *queue, buffqueue *results, unsigned long blockSize)
Definition: fileopstest.cpp:317
collectStats
void collectStats(buffqueue *results)
Definition: fileopstest.cpp:460
parameter1
static options::single< size_t > parameter1('\0', "parameter1", "1st distribution paramater, avg/min file size", 1024)
dummyMember
Definition: fileopstest.cpp:354
testFile::tOpen
clock_type::time_point tOpen
Definition: fileopstest.cpp:45
timeRecords::recordMutex
std::mutex recordMutex
Definition: fileopstest.cpp:179
creationRecords
static timeRecords creationRecords
Definition: fileopstest.cpp:203
statCollection::min
T min
Definition: fileopstest.cpp:359
createFile
testFile * createFile(const char *workdir, unsigned int index, buffstuff &buffer, size_t size, std::chrono::system_clock::time_point &stat_time)
Definition: fileopstest.cpp:104
testFile::tClose1
clock_type::time_point tClose1
Definition: fileopstest.cpp:46
buffqueue::expectingInput
bool expectingInput
Definition: fileopstest.cpp:56
creator
void creator(buffqueue *queue, const char *workdir, unsigned int repeat, unsigned long blockSize, unsigned int maxQueueDepth)
Definition: fileopstest.cpp:290
options::positional
Definition: Options.h:876
buffqueue::size
decltype(queue.size()) size()
Definition: fileopstest.cpp:79
buffqueue::queue_mutex
std::mutex queue_mutex
Definition: fileopstest.cpp:54
fileSizeGenerator::geometric_dist
std::geometric_distribution< size_t > geometric_dist
Definition: fileopstest.cpp:218
testFile::deltaTClose1
clock_type::duration deltaTClose1
Definition: fileopstest.cpp:38
clock_type
std::chrono::system_clock clock_type
Definition: dateTest.cpp:4
timeSpan::stop
clock_type::time_point stop
Definition: fileopstest.cpp:431
fileSizeGenerator::geometric
@ geometric
Definition: fileopstest.cpp:213
timeSpan::timeSpan
timeSpan()
Definition: fileopstest.cpp:433
statCollectionBase::print
virtual void print(unsigned long n)=0
consumptionRecords
static timeRecords consumptionRecords
Definition: fileopstest.cpp:205
statCollection::max
T max
Definition: fileopstest.cpp:360
throwcall::good0
void good0(T call, const Args &... args)
template function to wrap system calls that return 0 on success
Definition: throwcall.h:40
statCollection::add
void add(TC *what)
Definition: fileopstest.cpp:372
f
int f(int a, int line)
Definition: cctest.cpp:4
fileSizeGenerator::fileSizeGenerator
fileSizeGenerator(const std::string &aDistribution, size_t size_parameter1, size_t size_parameter2, size_t max_size)
Definition: fileopstest.cpp:226
distribution
static options::single< std::string > distribution('d', "distribution", "distribution type", "constant", {"constant", "uniform", "geometric", "gauss"})
statCollectionBase::getName
const std::string & getName() const
Definition: fileopstest.cpp:347
buffqueue::endOfInput
void endOfInput()
Definition: fileopstest.cpp:82
buffstuff::blockSize
unsigned int blockSize
Definition: fileopstest.cpp:101
clock_type
std::chrono::system_clock clock_type
Definition: fileopstest.cpp:27
timeSpan::span
std::chrono::duration< double > span()
Definition: fileopstest.cpp:455
statCollection::statCollection
statCollection(decltype(sourceMember) aSourceMember, Types ... args)
Definition: fileopstest.cpp:376
buffqueue::dequeue
testFile * dequeue()
Definition: fileopstest.cpp:64