Question : Design issue, storing date from /proc

Hi,

This is more to get some feedback of my design then an actual problem to solve. I thought I would give it a try since you guys have been so helpful earlier.

Ok here it is. I am trying to write a C++ program that is going to take a snapshot of the /proc filesystem. So far I have written a parser to parse each pid dir. The snapshot will then be a class inclosing the proc structure that I am trying to design.

[ProcInfo]
  |-----1312--[Dir]
  |                   |
  |                   |---smap--[File]
  |                   |                   |--RSS--[Data]
  |                   |                   |--USS--[Data]
  |                   |                   |--PSS--[Data]
  |                   |---cmdline--[File]
  |                   |                    |--cmd--[Data]
  |                   |---net--[Dir]
  |                                  |---sockstat6--[File]
  |                                  |                         |--TCP6--[Data]
  |---meminfo--[File]
                         |---memtotal--[Data]

[ProcInfo]=A class representing proc which should inherit the virtual snapshot class
[Dir]=A class representing a dir in proc which should inherit the virtual snapshot class
[File]=A class representing a file in proc which should inherit the virtual snapshot class
[Data]=A class representing the data that the parser returns.

class Snapshot
{
  virtual void append(Snapshot*) = 0;
};

class Dir : public Snapshot
{
 ...
...
....
 private:
  std:map<std:string, snapshot*> *mpData;
};

class File : public Snapshot
{
 ...
...
....
 private:
  std:map<std:string, proctData*> *mpData;
};


class ProcInfo : public Dir
{
 ...
....
};

I would then like to use this in a thread run every 10 sec and taking a snapshot of /ptoc

ProcHandler proc;
ProcInfo *procInfo = proc.snapshot();

Dir pidSnapshot = procInfo->getPid(1312);
Data data = pidSnapshot.get(ProcInfo::RSS);
int rss = data.toInt();
string sRss = data.toString();

File memSnapshot = procInfo->getSystem(ProcInfo::MEM);
Data data = memSnapshot.get(ProcInfo::MEMTOTAL);
int mem = data.toInt();
string sMem = data.toString();

delete procInfo;

Any comments on this design would be much appreciated even small ones I just need to get some feed back. I have been staring at this design to long and I think that I have locked my self in to this the design. I need some new eyes to take a look at it and maybe they can see some problems or maybe a much better design.


Answer : Design issue, storing date from /proc


Seems ok to me, but since you asked for new ideas, here goes --

- As a matter of pref/taste I would much rather keep the conversions non-members like, so I don't have to polute the interface and let any new conversion be added to the system easily. But as I said, thats a matter of taste maybe.

Convert<int>(Data d);
Convert<MyWeirdClass>(d);

- Since you talked about minimizing server trips and bandwidth and coincidently used the "snapshot" phrase, it is natural to think also of "differential snapshots". So the idea is that you take a primary snapshot.

Dir pidSnapshot = procInfo->getPid(1312);
SnapShot* difference = pidSnapshot->difference();

Snapshot::difference();
Snapshot::applyDifferential(Snapshot* d)

So that way, only values that have change since last capture will be returned and that may cause huge savings in terms of performance.

- Are you sure the proc filesystem does not have symbolic links (I mean the same entity appearing under multiple hives)? If yes, then is it ok to keep two copies of the same datum. I guess it doesnt matter much, as long as the snapshot's just a value object.

- Rather than having the getPid() etc kind of very specific accessors, it would be more worthwhile if you could have in the base class a generic set of find() methods like say

virtual Snapshot* Snapshot::find(string child) {
}

Also how about Snapshot base that has children

class SnapshotContainer : public Snapshot
{
virtual Snapshot* Snapshot::find(string child) {
}
private:
  std:map<std:string, Snapshot*> *mpData;
};

- Would be helpful, if you also provide a slight but important variation for find(), call it locate() that takes a path (rather than a name) and does the dirty job of doing the traversing.

// path is in this form, /root/net/sockstats/tcpip6
Snapshot* Snapshot::locate(string path) {
}

- The most important change that I would make would be to make the snapshot a reference counted object and returned a smart/refptr to the snapshot rather than raw pointers. That really give a lot of power, especially when you want to be able to fetch children and keep them around (maybe)

class Snapshot : public RefCounted // See Poco::RefCounted for ref.
{
}

typedef RefCountedPtr<Snapshot> RefSnapshot;

Hope these help ...
Random Solutions  
 
programming4us programming4us