1/* Copyright (C) 2021 Free Software Foundation, Inc.
2   Contributed by Oracle.
3
4   This file is part of GNU Binutils.
5
6   This program is free software; you can redistribute it and/or modify
7   it under the terms of the GNU General Public License as published by
8   the Free Software Foundation; either version 3, or (at your option)
9   any later version.
10
11   This program is distributed in the hope that it will be useful,
12   but WITHOUT ANY WARRANTY; without even the implied warranty of
13   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14   GNU General Public License for more details.
15
16   You should have received a copy of the GNU General Public License
17   along with this program; if not, write to the Free Software
18   Foundation, 51 Franklin Street - Fifth Floor, Boston,
19   MA 02110-1301, USA.  */
20
21#include "config.h"
22#include <assert.h>
23#include <string.h>
24
25#include "util.h"
26#include "FileData.h"
27
28void
29FileData::init ()
30{
31  readTime = 0;
32  writeTime = 0;
33  otherTime = 0;
34  errorTime = 0;
35  readBytes = 0;
36  writeBytes = 0;
37  readCnt = 0;
38  writeCnt = 0;
39  otherCnt = 0;
40  errorCnt = 0;
41  wSlowestBytes = 0;
42  wSmallestBytes = _10TB;
43  wLargestBytes = 0;
44  w0KB1KBCnt = 0;
45  w1KB8KBCnt = 0;
46  w8KB32KBCnt = 0;
47  w32KB128KBCnt = 0;
48  w128KB256KBCnt = 0;
49  w256KB512KBCnt = 0;
50  w512KB1000KBCnt = 0;
51  w1000KB10MBCnt = 0;
52  w10MB100MBCnt = 0;
53  w100MB1GBCnt = 0;
54  w1GB10GBCnt = 0;
55  w10GB100GBCnt = 0;
56  w100GB1TBCnt = 0;
57  w1TB10TBCnt = 0;
58  rSlowestBytes = 0;
59  rSmallestBytes = _10TB;
60  rLargestBytes = 0;
61  r0KB1KBCnt = 0;
62  r1KB8KBCnt = 0;
63  r8KB32KBCnt = 0;
64  r32KB128KBCnt = 0;
65  r128KB256KBCnt = 0;
66  r256KB512KBCnt = 0;
67  r512KB1000KBCnt = 0;
68  r1000KB10MBCnt = 0;
69  r10MB100MBCnt = 0;
70  r100MB1GBCnt = 0;
71  r1GB10GBCnt = 0;
72  r10GB100GBCnt = 0;
73  r100GB1TBCnt = 0;
74  r1TB10TBCnt = 0;
75}
76
77FileData::FileData (const char *fName)
78{
79  fileName = dbe_strdup (fName);
80  fileDesList = new Vector<int>;
81  virtualFds = new Vector<int64_t>;
82  virtualFd = -1;
83  fileDes = -1;
84  fsType[0] = '\0';
85  histType = Histable::IOACTVFD;
86  init ();
87}
88
89FileData::FileData (FileData *fData)
90{
91  fileName = dbe_strdup (fData->fileName);
92  fileDesList = new Vector<int>;
93  Vector<int> *fdList = fData->fileDesList;
94  int fd;
95  if (fdList != NULL)
96    for (int i = 0; i < fdList->size (); i++)
97      if ((fd = fdList->fetch (i)) == -1)
98	fileDesList->append (fd);
99
100  virtualFds = new Vector<int64_t>;
101  Vector<int64_t> *vfds = fData->virtualFds;
102  int64_t vfd;
103  if (vfds != NULL)
104    for (int i = 0; i < vfds->size (); i++)
105      if ((vfd = vfds->fetch (i)) == -1)
106	virtualFds->append (vfd);
107  virtualFd = fData->virtualFd;
108  fileDes = fData->fileDes;
109  histType = fData->histType;
110
111  for (int i = 0; i < FSTYPESZ; i++)
112    fsType[i] = fData->fsType[i];
113
114  readTime = fData->readTime;
115  writeTime = fData->writeTime;
116  otherTime = fData->otherTime;
117  errorTime = fData->errorTime;
118  readBytes = fData->readBytes;
119  writeBytes = fData->writeBytes;
120  readCnt = fData->readCnt;
121  writeCnt = fData->writeCnt;
122  otherCnt = fData->otherCnt;
123  errorCnt = fData->errorCnt;
124  wSlowestBytes = fData->wSlowestBytes;
125  wSmallestBytes = fData->wSmallestBytes;
126  wLargestBytes = fData->wLargestBytes;
127  w0KB1KBCnt = fData->w0KB1KBCnt;
128  w1KB8KBCnt = fData->w1KB8KBCnt;
129  w8KB32KBCnt = fData->w8KB32KBCnt;
130  w32KB128KBCnt = fData->w32KB128KBCnt;
131  w128KB256KBCnt = fData->w128KB256KBCnt;
132  w256KB512KBCnt = fData->w256KB512KBCnt;
133  w512KB1000KBCnt = fData->w512KB1000KBCnt;
134  w1000KB10MBCnt = fData->w1000KB10MBCnt;
135  w10MB100MBCnt = fData->w10MB100MBCnt;
136  w100MB1GBCnt = fData->w100MB1GBCnt;
137  w1GB10GBCnt = fData->w1GB10GBCnt;
138  w10GB100GBCnt = fData->w10GB100GBCnt;
139  w100GB1TBCnt = fData->w100GB1TBCnt;
140  w1TB10TBCnt = fData->w1TB10TBCnt;
141  rSlowestBytes = fData->rSlowestBytes;
142  rSmallestBytes = fData->rSmallestBytes;
143  rLargestBytes = fData->rLargestBytes;
144  r0KB1KBCnt = fData->r0KB1KBCnt;
145  r1KB8KBCnt = fData->r1KB8KBCnt;
146  r8KB32KBCnt = fData->r8KB32KBCnt;
147  r32KB128KBCnt = fData->r32KB128KBCnt;
148  r128KB256KBCnt = fData->r128KB256KBCnt;
149  r256KB512KBCnt = fData->r256KB512KBCnt;
150  r512KB1000KBCnt = fData->r512KB1000KBCnt;
151  r1000KB10MBCnt = fData->r1000KB10MBCnt;
152  r10MB100MBCnt = fData->r10MB100MBCnt;
153  r100MB1GBCnt = fData->r100MB1GBCnt;
154  r1GB10GBCnt = fData->r1GB10GBCnt;
155  r10GB100GBCnt = fData->r10GB100GBCnt;
156  r100GB1TBCnt = fData->r100GB1TBCnt;
157  r1TB10TBCnt = fData->r1TB10TBCnt;
158}
159
160FileData::~FileData ()
161{
162  free (fileName);
163  delete fileDesList;
164  delete virtualFds;
165}
166
167void
168FileData::setVirtualFds (int64_t vfd)
169{
170  for (int i = 0; i < virtualFds->size (); i++)
171    if (vfd == virtualFds->fetch (i))
172      return;
173  virtualFds->append (vfd);
174}
175
176void
177FileData::setFileDesList (int fd)
178{
179  for (int i = 0; i < fileDesList->size (); i++)
180    if (fd == fileDesList->fetch (i))
181      return;
182  fileDesList->append (fd);
183}
184
185void
186FileData::setFsType (const char* fst)
187{
188  size_t len = strlen (fst);
189  if (len > 0 && len < FSTYPESZ)
190    snprintf (fsType, sizeof (fsType), NTXT ("%s"), fst);
191  else
192    snprintf (fsType, sizeof (fsType), GTXT ("error"));
193}
194
195Histable*
196FileData::convertto (Histable_type type, Histable*)
197{
198  return (type == histType ? this : NULL);
199}
200
201char*
202FileData::get_name (Histable::NameFormat /*_nfmt*/)
203{
204  if (histType == Histable::IOACTVFD)
205    {
206      if (!streq (fileName, NTXT ("<Total>")))
207	{
208	  if (fileDes >= 0)
209	    return dbe_sprintf (GTXT ("%s (IOVFD=%lld, FD=%d)"), fileName,
210				(long long) virtualFd, (int) fileDes);
211	  return dbe_sprintf (GTXT ("%s (IOVFD=%lld)"), fileName,
212			      (long long) virtualFd);
213	}
214      else
215	return fileName;
216    }
217  else if (histType == Histable::IOACTFILE)
218    {
219      if (!streq (fileName, NTXT ("<Total>")))
220	{
221	  if (!streq (fsType, NTXT ("N/A")))
222	    return dbe_sprintf (GTXT ("%s (FS=%s)"), fileName, fsType);
223	  return fileName;
224	}
225      return fileName;
226    }
227  return fileName;
228}
229
230char*
231FileData::get_raw_name (Histable::NameFormat /*_nfmt*/)
232{
233  return fileName;
234}
235
236void
237FileData::setFsType (FileSystem_type fst)
238{
239  const char *fsName;
240  switch (fst)
241    {
242    case ZFS_TYPE:
243      fsName = "zfs";
244      break;
245    case NFS_TYPE:
246      fsName = "nfs";
247      break;
248    case UFS_TYPE:
249      fsName = "ufs";
250      break;
251    case UDFS_TYPE:
252      fsName = "udfs";
253      break;
254    case LOFS_TYPE:
255      fsName = "lofs";
256      break;
257    case VXFS_TYPE:
258      fsName = "vxfs";
259      break;
260    case TMPFS_TYPE:
261      fsName = "tmpfs";
262      break;
263    case PCFS_TYPE:
264      fsName = "pcfs";
265      break;
266    case HSFS_TYPE:
267      fsName = "hsfs";
268      break;
269    case PROCFS_TYPE:
270      fsName = "procfs";
271      break;
272    case FIFOFS_TYPE:
273      fsName = "fifofs";
274      break;
275    case SWAPFS_TYPE:
276      fsName = "swapfs";
277      break;
278    case CACHEFS_TYPE:
279      fsName = "cachefs";
280      break;
281    case AUTOFS_TYPE:
282      fsName = "autofs";
283      break;
284    case SPECFS_TYPE:
285      fsName = "specfs";
286      break;
287    case SOCKFS_TYPE:
288      fsName = "sockfs";
289      break;
290    case FDFS_TYPE:
291      fsName = "fdfs";
292      break;
293    case MNTFS_TYPE:
294      fsName = "mntfs";
295      break;
296    case NAMEFS_TYPE:
297      fsName = "namefs";
298      break;
299    case OBJFS_TYPE:
300      fsName = "objfs";
301      break;
302    case SHAREFS_TYPE:
303      fsName = "sharefs";
304      break;
305    case EXT2FS_TYPE:
306      fsName = "ext2";
307      break;
308    case EXT3FS_TYPE:
309      fsName = "ext3";
310      break;
311    case EXT4FS_TYPE:
312      fsName = "ext4";
313      break;
314    case UNKNOWNFS_TYPE:
315      fsName = "N/A";
316      break;
317    default:
318      fsName = "N/A";
319      break;
320    }
321  setFsType (fsName);
322}
323
324void
325FileData::setWriteStat (hrtime_t wt, int64_t nb)
326{
327  if (wSlowestBytes < wt)
328    wSlowestBytes = wt;
329  if (nb != 0 && wSmallestBytes > nb)
330    wSmallestBytes = nb;
331  if (wLargestBytes < nb)
332    wLargestBytes = nb;
333  if (nb >= 0 && nb <= _1KB)
334    w0KB1KBCnt++;
335  else if (nb <= _8KB)
336    w1KB8KBCnt++;
337  else if (nb <= _32KB)
338    w8KB32KBCnt++;
339  else if (nb <= _128KB)
340    w32KB128KBCnt++;
341  else if (nb <= _256KB)
342    w128KB256KBCnt++;
343  else if (nb <= _512KB)
344    w256KB512KBCnt++;
345  else if (nb <= _1000KB)
346    w512KB1000KBCnt++;
347  else if (nb <= _10MB)
348    w1000KB10MBCnt++;
349  else if (nb <= _100MB)
350    w10MB100MBCnt++;
351  else if (nb <= _1GB)
352    w100MB1GBCnt++;
353  else if (nb <= _10GB)
354    w1GB10GBCnt++;
355  else if (nb <= _100GB)
356    w10GB100GBCnt++;
357  else if (nb <= _1TB)
358    w100GB1TBCnt++;
359  else if (nb <= _10TB)
360    w1TB10TBCnt++;
361}
362
363void
364FileData::setReadStat (hrtime_t rt, int64_t nb)
365{
366  if (rSlowestBytes < rt)
367    rSlowestBytes = rt;
368  if (nb != 0 && rSmallestBytes > nb)
369    rSmallestBytes = nb;
370  if (rLargestBytes < nb)
371    rLargestBytes = nb;
372  if (nb >= 0 && nb <= _1KB)
373    r0KB1KBCnt++;
374  else if (nb <= _8KB)
375    r1KB8KBCnt++;
376  else if (nb <= _32KB)
377    r8KB32KBCnt++;
378  else if (nb <= _128KB)
379    r32KB128KBCnt++;
380  else if (nb <= _256KB)
381    r128KB256KBCnt++;
382  else if (nb <= _512KB)
383    r256KB512KBCnt++;
384  else if (nb <= _1000KB)
385    r512KB1000KBCnt++;
386  else if (nb <= _10MB)
387    r1000KB10MBCnt++;
388  else if (nb <= _100MB)
389    r10MB100MBCnt++;
390  else if (nb <= _1GB)
391    r100MB1GBCnt++;
392  else if (nb <= _10GB)
393    r1GB10GBCnt++;
394  else if (nb <= _100GB)
395    r10GB100GBCnt++;
396  else if (nb <= _1TB)
397    r100GB1TBCnt++;
398  else if (nb <= _10TB)
399    r1TB10TBCnt++;
400}
401