-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathGenerateDiskLoad.java
More file actions
135 lines (119 loc) · 5.52 KB
/
GenerateDiskLoad.java
File metadata and controls
135 lines (119 loc) · 5.52 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
import java.util.*;
import java.util.concurrent.*;
import java.io.*;
import java.text.*;
/**
*GenerateDiskLoad is used to simulate heavy to low disk writes
*It has throttling feature, but throttling applies only to writes which happens to page cache
*write(..) ----speedInMBPerSec---->PageCache ----Kernel Speed---->Disk
*Nevertheless, avg speed which you will demand from command line argument, will be provided by end of run.
*/
class GenerateDiskLoad {
/**
* JVM will enter here
*/
public static void main(String[] args) throws IOException{
Map cmdLineArgs = validateAndGetArguments(args);//Command line arguments are stored as key value in a map
System.out.println("Printing command line arguments or their default values: "+cmdLineArgs);
for (int i = 0; i < Integer.parseInt((String)cmdLineArgs.get("iterations")); i++){
testFileWrite(i,(Integer.parseInt((String)cmdLineArgs.get("fileSizeInMB")))*1024,Integer.parseInt((String)cmdLineArgs.get("speedInMBPerSec")),(String)cmdLineArgs.get("createTmpFileInDir"));
}
}
/**
*Function
* a)To create a test.txt of size *fileSizeinBytes* and get deleted after program ends
* b)To write with *speedInMBPerSec* speed
*
*/
private static void testFileWrite(int iteration, int fileSizeinBytes, int speedInMBPerSec, String filePath) throws IOException{
File file = File.createTempFile("test", ".txt",new File(filePath)); file.deleteOnExit();
char[] chars = new char[1024]; Arrays.fill(chars, 'A');String longLine = new String(chars); //String of length 1KB
long start = System.nanoTime();
long printNextTime = start;
FileWriter pw = new FileWriter(file);
for (int i = 0; i < fileSizeinBytes; i++){
pw.write(longLine);
printNextTime = printProgress(i,longLine.length(),printNextTime);
if(i%(speedInMBPerSec*2) == 0) try { TimeUnit.NANOSECONDS.sleep(1); } catch (InterruptedException e) { } //Check after 1MB is written
}
pw.close();
long end = System.nanoTime() - start;
System.out.printf("Iteration %d Took %.3f seconds to write to a %d MB, file rate: %.1f MB/s%n",iteration, end / 1e9, file.length() >> 20, file.length() * 1000.0 / end);
}
/**
*printProgress function prints how much of the file is currently being written.
*/
private static long printProgress(int counter, int payloadSize, long printNextTime){
long currTime = System.nanoTime();//Get current time
if (currTime > printNextTime){
long totalSizeWritten = (long) ((long)counter * (long)payloadSize);
VMStatReader vm = new VMStatReader("/proc/vmstat");Map map = vm.getVMStatusRecord();
System.out.println((new Date())+" - Total data written to file: "+readableFileSize(totalSizeWritten)+ ", Dirty pages waiting to be written to disk:"+(String)map.get("nr_dirty")+ ", Dirty pages actively being written:"+(String)map.get("nr_writeback"));
printNextTime += (long)1000000000;//Add 1 sec, so that next message is printed after 1 sec
}
return printNextTime;
}
/**
* readableFileSize function converts number into human readable format of MB, GB
*/
public static String readableFileSize(long size) {
if(size <= 0) return "0";
final String[] units = new String[] { "B", "kB", "MB", "GB", "TB" };
int digitGroups = (int) (Math.log10(size)/Math.log10(1024));
return new DecimalFormat("#,##0.#").format(size/Math.pow(1024, digitGroups)) + " " + units[digitGroups];
}
/**
* Function to validate input parameters to this class file
* At the end it will generate a hashmap of key value store of command line input arguments
*/
public static Map validateAndGetArguments(String[] args){
boolean allArgumentsExists = true;
HashMap<String,Object> hm = new HashMap();
if(args.length > 0){
for(int i = 0; i < args.length;i++){
if(args[i].equalsIgnoreCase("-h") || args[i].equalsIgnoreCase("--help")){
allArgumentsExists = false;
break;
}
}
if(allArgumentsExists){
for(int i = 0; i < args.length;i++){
for (String retval: args[i].split(" ")){
String[] keyval = retval.split("=");
keyval[0] = keyval[0].replace("-","");
hm.put(keyval[0],keyval[1]);
}
}
}
}
if(!allArgumentsExists){
System.out.println("\u001B[33m"+"GenerateDiskLoad is used to simulate disk load.\n Ex, java GenerateDiskLoad; GenerateDiskLoad command also take custom parameters.\n speedInMBPerSec is used to specify speed of disk write.\n fileSizeInMB is used to specify size of the file being written to disk.\n iterations is used to loop through file creation multiple times.\n Ex, java GenerateDiskLoad --speedInMBPerSec=100 --fileSizeInMB=1000 --iterations=2"+"\u001B[0m");
System.exit(1);
}
if(hm.get("fileSizeInMB") == null) hm.put("fileSizeInMB","5000");
if(hm.get("speedInMBPerSec") == null) hm.put("speedInMBPerSec","100");
if(hm.get("iterations") == null) hm.put("iterations","1");
if(hm.get("createTmpFileInDir") == null) hm.put("createTmpFileInDir",System.getProperty("user.dir"));
return hm;
}
}
class VMStatReader {
private String vmStatFile = null;
public VMStatReader(String vmStatFile){
this.vmStatFile = vmStatFile;
}
public Map getVMStatusRecord(){
String line = null;
Map<String, String> map = new HashMap<String, String>();
try{
BufferedReader bfr = new BufferedReader(new FileReader(this.vmStatFile));
while ((line = bfr.readLine()) != null) {
String parts[] = line.split(" ");
map.put(parts[0], parts[1]);
}
}catch(IOException e){
e.printStackTrace();
}
return map;
}
}