ROOT logo
#include "hdiskspace.h"

#include "TRegexp.h"
#include "TDatime.h"
#include "TStyle.h"
#include "TH2D.h"
#include "TLegend.h"

#include <algorithm>
#include <ctype.h>

#include "TStreamer.h"
#include "TDirectory.h"

//_HADES_CLASS_DESCRIPTION
////////////////////////////////////////////////////////////////////////////////
//
//
// HDiskFile,HDiskDir,HDiskCatalog,HFileSys
//
// tool set to build a catalog of a full filesystem including all
// meta information of files and dirs. The catalog can be updated
// incremental by rescanning only dirs which have been modfied since
// last scan.
//
////////////////////////////////////////////////////////////////////////////////

ClassImp(HFileSys)
ClassImp(HDiskFile)
ClassImp(HDiskDir)
ClassImp(HDiskCatalog)
ClassImp(HDiskStat)


HDiskCatalog* gHDiskCatalog;
ULong64_t          HFileSys::unitK        = 1024L;
ULong64_t          HFileSys::unitM        = 1024L*1024L;
ULong64_t          HFileSys::unitG        = 1024L*1024L*1024L;
ULong64_t          HFileSys::unitT        = 1024L*1024L*1024L*1024L;
ULong64_t          HFileSys::SmallerLimit = 1024L*1024L;   // 1Mb

map<uid_t,TString> HFileSys::musers  =  initUsers();
map<uid_t,TString> HFileSys::mgroups =  initGroups();

void HFileSys::getUsers(map<uid_t,TString>& musers)
{
    // gather all user known by the system
    musers.clear();
    setpwent();
    struct passwd* entry = 0;

    while( (entry = getpwent() ) != 0){
	if(musers.find(entry->pw_uid) == musers.end()) musers[entry->pw_uid] = entry->pw_name;    }
    endpwent();
}

void HFileSys::getGroups(map<gid_t,TString>& mgroups)
{
    // gather all groups known by the system
    mgroups.clear();
    setgrent();
    struct group* entry =0;

    while( (entry = getgrent() ) != 0){
	if(mgroups.find(entry->gr_gid) == mgroups.end()) mgroups[entry->gr_gid] = entry->gr_name;
    }
    endgrent();
}

map<uid_t,TString> HFileSys::initUsers()
{
    // helper function to init static maps
    map<uid_t,TString> m;
    return m;
}

map<gid_t,TString> HFileSys::initGroups()
{
    // helper function to init static maps
    map<gid_t,TString> m;
    return m;
}

void HFileSys::fillSysInfo()
{
    // gather user and group infos from the
    // system
    getUsers (musers);
    getGroups(mgroups);
}

Bool_t HFileSys::getUser(uid_t uid,TString& name)
{
    // lookup of user uid in the map of
    // known users. if the user can not be
    // found the the user name will be unknown_uid
    name = Form("unknown_%i",uid);
    map<uid_t,TString>::iterator it = musers.find(uid);
    if(it!=musers.end()) { name = it->second; return kTRUE;}
    return kFALSE;
}

Bool_t HFileSys::getGroup(gid_t gid,TString& name)
{
    // lookup of group gid in the map of
    // known groups. if the group can not be
    // found the the group name will be unknown_gid
    name = Form("unknown_%i",gid);
    map<gid_t,TString>::iterator it = mgroups.find(gid);
    if(it!=mgroups.end()) { name = it->second; return kTRUE;}
    return kFALSE;
}

void HFileSys::getModTime(time_t lastmod,TString& modtime)
{
    // translates time_t lastmod into string
    // witrhout trailing \n
    modtime = ctime(&lastmod);
    modtime.ReplaceAll('\n',"");
}

void HFileSys::getFileSize(ULong64_t size, TString& out)
{
    // returns human readable file size (K,M,G,T units)
    out="";
    Float_t c = unitK;   // kB
    TString s = "K";

    if (size>unitM && size <= unitG){
	c=unitM;
        s = "M";
    } else if (size>unitG){
	c=unitG;
	s="G";
	if(size>unitT){
	    c=unitT;
	    s="T";
	}
    }
    Float_t val=size/c;
    if     (s=="K")   out= Form("%9.0fK",val);
    else if(s=="M")   out= Form("%9.3fM",val);
    else if(s=="G")   out= Form("%9.3fG",val);
    else              out= Form("%9.3fT",val);
}

void HFileSys::lsFiles(TString directory, vector<TString>& fileList,Bool_t clear,Bool_t fullpath)
{
    // fill all file names of directory to vector.
    // uses readdir()
    if(clear)fileList.clear();
    DIR *dir;
    struct dirent *ent = NULL;
    if ((dir=opendir(directory.Data())) != NULL)   // open a directory
    {
	while((ent=readdir(dir)) != NULL) { // loop until last entry
	    if(ent->d_type == DT_REG) {
		if(!fullpath)fileList.push_back(ent->d_name); // push filename to the list
                else         fileList.push_back(Form("%s/%s",directory.Data(),ent->d_name));
	    }
	}
	closedir(dir);
    }
}

void  HFileSys::lsFilesRecursive(TString directory, vector<TString>&fullList)
{
    // fill all dir names of directory rekursively to vector.
    // uses readdir()

    if(directory.EndsWith("/")) directory.Replace(directory.Length()-1,1,"");
    vector<TString> fileList;
    lsDirectory(directory,fileList);  // get the "root" directory's directories

    lsFiles(directory,fullList,kFALSE,kTRUE);

    for(vector<TString>::iterator i = fileList.begin(); i != fileList.end(); ++i) // loop thru the list
    {
	if (strcmp((*i).Data(), ".") &&     // skip . and ..
	    strcmp((*i).Data(), ".."))
	{
	    stringstream fullname;
	    fullname << directory << "/" << (*i);
	    lsFilesRecursive(fullname.str(), fullList);
	}
    }
}

void HFileSys::lsDirectory(TString directory, vector<TString>& fileList)
{
    // fill all dir names of directory to vector.
    // uses readdir()
    fileList.clear();
    DIR *dir;
    struct dirent *ent=NULL;
    if ((dir=opendir(directory.Data())) != NULL) // open a directory
    {
	while((ent=readdir(dir)) != NULL) { // loop until last entry
	    if (strcmp(ent->d_name, ".") &&     // skip . and ..
		strcmp(ent->d_name, ".."))
	    {
		if(ent->d_type == DT_DIR)fileList.push_back(ent->d_name); // push directory to the list
	    }
	}
	closedir(dir); // close up
    }
}

void  HFileSys::lsDirectoryRecursive(TString directory, vector<TString>&fullList)
{
    // fill all dir names of directory rekursively to vector.
    // uses readdir()
    vector<TString> fileList;
    lsDirectory(directory,fileList);  // get the "root" directory's directories

    for(vector<TString>::iterator i = fileList.begin(); i != fileList.end(); ++i) // loop thru the list
    {
	if (strcmp((*i).Data(), ".") &&     // skip . and ..
	    strcmp((*i).Data(), ".."))
	{
	    stringstream fullname;
	    fullname << directory << "/" << (*i);
	    fullList.push_back(fullname.str());
	    lsDirectoryRecursive(fullname.str(), fullList);
	}
    }
}


//----------------------------------------------------------------------------



HDiskFile::HDiskFile(TString name)
{
    SetName(name.Data());
    size   = 0;
    group  = 0;
    owner  = 0;
    lastmod= 0;
}

HDiskFile::~HDiskFile()
{

}
void HDiskFile::print(Int_t sp)
{
    // prints the file info. if sp!=0
    // the info will be printed with sp leading spaces.
    TString modtime ;
    TString sowner;
    TString sgroup;
    TString fsize;
    HFileSys::getModTime (lastmod,modtime);
    HFileSys::getUser    (owner,sowner);
    HFileSys::getGroup   (group,sgroup);
    HFileSys::getFileSize(size,fsize);
    if(sp==0){
	cout<<setw(8)                     <<fsize.Data()
	    <<" "<<modtime.Data()
	    <<" "<<setw(15)<<sowner
	    <<" "<<setw(15)<<sgroup
	    <<" "<<GetName()
	    <<endl;
    } else {
	cout<<setw(8)<<std::string(sp,' ')<<fsize.Data()
	    <<" "<<modtime.Data()
	    <<" "<<setw(15)<<sowner
	    <<" "<<setw(15)<<sgroup
	    <<" "<<GetName()
	    <<endl;
    }
}

//----------------------------------------------------------------------------

HDiskDir::HDiskDir(TString name)
{
    SetName(name.Data());
    size                    = 0;
    group                   = 0;
    owner                   = 0;
    lastmod                 = 0;
    nFilesSmallerLimit      = 0;
    nFilesSmallerLimitTotal = 0;
    nFilesTotal             = 0;
    level                   = 0;
    nEmptyDirs              = 0;
    nDirsTotal              = 0;
    nEmptyDirsTotal         = 0;
    //files.reserve(100);
    if(gHDiskCatalog) {
	name.ReplaceAll(gHDiskCatalog->getDiskName().Data(),"");
	level = name.CountChar('/');
    }
}
HDiskDir::~HDiskDir()
{
}
void HDiskDir::update()
{
    // update the summray info of this
    // directopry rekursively
    nFilesSmallerLimitTotal = 0;
    nFilesTotal             = 0;
    size                    = 0;
    nEmptyDirsTotal         = 0;
    nDirsTotal              = 0;

    updateRecursive(this,this);
}

void HDiskDir::update(HDiskDir* mother)
{
    // add stats of dauhgter to stats of mother
    mother->addNSmallFilesTotal(nFilesSmallerLimit);
    mother->addNFilesTotal(files.size());
    mother->addNDirsTotal(dirs.size());
    mother->addNEmptyDirsTotal(nEmptyDirs);

    for(UInt_t i=0;i<files.size(); ++i){ // loop thru the list
       mother->addSize(files[i].getSize());
    }
}

void  HDiskDir::updateRecursive(HDiskDir* daughter,HDiskDir* mother)
{
    // fill stats of subdirs rekursively to mother
    if(!gHDiskCatalog) {
	cout<<"ERROR: HDiskDir::updateRecursive() : gHDiskCatatlog==NULL! "<<endl;
	return ;
    }
    daughter->update(mother);

    for(UInt_t i=0;i<daughter->getDirs().size(); ++i) // loop thru the list
    {
	HDiskDir* d = (HDiskDir*)gHDiskCatalog->getList()->At(daughter->getDirs()[i]);
	if(!d) {
	    cout<<"ERROR: HDiskDir::updateRecursive() : index wrong, retrived NULL! "<<endl;
	    return ;
	}
	updateRecursive(d,mother);
    }
}



void HDiskDir::print(Int_t sp, TString base)
{
    // prints the dir info. if sp!=0
    // the info will be printed with sp leading spaces.
    // if base!="" base will be replaced in dirname by ""
    TString modtime ;
    TString sowner;
    TString sgroup;
    TString fsize;
    TString name = GetName();
    if(base != "") name.ReplaceAll(base.Data(),"");
    HFileSys::getModTime (lastmod,modtime);
    HFileSys::getUser    (owner,sowner);
    HFileSys::getGroup   (group,sgroup);
    HFileSys::getFileSize(size,fsize) ;

    if(sp==0){
	cout                     <<setw(8)<<fsize.Data()
	    <<" "<<modtime.Data()
	    <<" "<<setw(12)<<sowner
	    <<" "<<setw(10)<<sgroup
	    <<" "<<setw(9)<<nFilesTotal
	    <<" "<<setw(9)<<nFilesSmallerLimitTotal
	    <<" "<<setw(9)<<nDirsTotal
	    <<" "<<setw(9)<<nEmptyDirsTotal
	    <<" "<<name
	    <<endl;
    } else {
	cout<<std::string(sp,'-')<<setw(8)<<fsize.Data()
	    <<" "<<modtime.Data()
	    <<" "<<setw(12)<<sowner
	    <<" "<<setw(10)<<sgroup
	    <<" "<<setw(9)<<nFilesTotal
	    <<" "<<setw(9)<<nFilesSmallerLimitTotal
	    <<" "<<setw(9)<<nDirsTotal
	    <<" "<<setw(9)<<nEmptyDirsTotal
	    <<" "<<name
	    <<endl;
    }
}

void HDiskDir::printFiles(Int_t sp)
{
    // prints all file infos of the dir
    for(UInt_t i = 0; i < files.size(); i++){
	files[i].print(sp);
    }
}

void HDiskDir::printDirs(Int_t sp, TString base)
{
    // prints all subdirs of dir
    if(!gHDiskCatalog) {
	cout<<"ERROR: HDiskDir::printDirs() : gHDiskCatatlog==NULL! "<<endl;
	return ;
    }

    for(UInt_t i = 0; i < dirs.size(); i++){
	HDiskDir* d = (HDiskDir*)gHDiskCatalog->getList()->At(dirs[i]);
	if(!d) {
	    cout<<"ERROR: HDiskDir::printDirs() : index wrong, retrived NULL! "<<endl;
	    continue ;
	}
	d->print(sp,base);
    }
}

Bool_t HDiskDir::scan(UInt_t index)
{
    // Scans the files inside the directory
    // and gather the file size and the number
    // of files smaller than the limit

    Bool_t problem = kFALSE;
    files.clear();
    struct stat status;
    if(stat(GetName(),&status) == 0)
    {
	lastmod            = status.st_mtime;
	owner              = status.st_uid;
	group              = status.st_gid;
	size               = status.st_size;
	nFilesSmallerLimit = 0;

	vector<TString> fileList;
	HFileSys::lsFiles(GetName(),fileList);
	TString fullname;
	for(UInt_t i = 0; i < fileList.size(); i++){
	    fullname = Form("%s/%s",GetName() ,fileList[i].Data());
	    if(stat(fullname.Data() ,&status) == 0)
	    {
		HDiskFile newfile(fileList[i]);
		newfile.setSize   (status.st_size);
		newfile.setGroup  (status.st_gid);
		newfile.setOwner  (status.st_uid);
		newfile.setLastMod(status.st_mtime);
                newfile.setDir(index);
		if(newfile.isToSmall()) nFilesSmallerLimit++;
		files.push_back(newfile);

	    } else {
		cout<<"ERROR : HDiskDir:scan() : Could not stat file = "<<fileList[i].Data()<<endl;
		problem=kTRUE;
	    }
	}

    } else {
	cout<<"ERROR : HDiskDir:scan() : Could not stat dir = "<<GetName()<<endl;
	problem = kTRUE;
    }
    return problem;
}

Bool_t HDiskDir::scan(struct stat& status, UInt_t index,vector<TString>& dirList)
{
    // Scans the files inside the directory
    // and gather the file size and the number
    // of files smaller than the limit

    Bool_t problem = kFALSE;
    files.clear();
    dirList.clear();

    lastmod            = status.st_mtime;
    owner              = status.st_uid;
    group              = status.st_gid;
    size               = status.st_size;
    nFilesSmallerLimit = 0;

    TString fullname;
    DIR *dir;
    struct dirent *ent = NULL;

    if ((dir=opendir(GetName())) != NULL)   // open a directory
    {
	while((ent=readdir(dir)) != NULL) { // loop until last entry
	    if(ent->d_type == DT_DIR) {
		if (strcmp(ent->d_name, ".") &&     // skip . and ..
		    strcmp(ent->d_name, "..")){
		    dirList.push_back(Form("%s/%s",GetName() ,ent->d_name)); // push filename to the list
		}
	    }
	    else if(ent->d_type == DT_REG)
	    {
		fullname = Form("%s/%s",GetName() ,ent->d_name);
		if(stat(fullname.Data() ,&status) == 0)
		{
		    HDiskFile newfile(ent->d_name);
		    newfile.setSize   (status.st_size);
		    newfile.setGroup  (status.st_gid);
		    newfile.setOwner  (status.st_uid);
		    newfile.setLastMod(status.st_mtime);
		    newfile.setDir(index);
		    if(newfile.isToSmall()) nFilesSmallerLimit++;
		    files.push_back(newfile);

		} else {
		    cout<<"ERROR : HDiskDir:scan() : Could not stat file = "<<ent->d_name<<endl;
		    problem=kTRUE;
		}
	    }
	}
	closedir(dir);
    }
    return problem;
}

void  HDiskDir::setDirToFiles(UInt_t index)
{
    for(UInt_t i = 0; i < files.size(); i++){
         files[i].setDir(index);
    }
}

Bool_t HDiskDir::isDaughter(HDiskDir* mother)
{
    // returns kTRUE if this dir is a daughter of mother
    // evaluation is done by path name.
    if(!mother) return kFALSE;
    if(strncmp(GetName(),mother->GetName(),strlen(mother->GetName())) == 0) return kTRUE;
    else return kFALSE;

}

//----------------------------------------------------------------------------


HDiskCatalog::HDiskCatalog(TString name)
{
    diskname=name;
    if(diskname.EndsWith("/")) {
	diskname.Replace(diskname.Length()-1,1,"");
    }

    list = new TObjArray();

    HFileSys::fillSysInfo();
    musers  = HFileSys::getUserMap();
    mgroups = HFileSys::getGroupMap();
    nSplit = 0;
    setCurrentCatalog();
}

HDiskCatalog::~HDiskCatalog()
{

    for(Int_t i=0;i<list->GetEntries();i++){
	HDiskDir* d = (HDiskDir*)list->At(i);
	delete d;
    }

    delete list;
    list=0;
}

Bool_t HDiskCatalog::cmpName(HDiskDir* a,HDiskDir* b)
{
    // compare function for sorting dirs alphabetically by
    // owner name
    TString usera;  HFileSys::getUser((uid_t)a->getOwner(),usera);
    TString userb;  HFileSys::getUser((uid_t)b->getOwner(),userb);

    string first (usera.Data());
    string second(userb.Data());

    UInt_t i = 0;
    while ( (i<first.length()) && (i<second.length()) )
    {
	if      (tolower(first[i]) < tolower(second[i])) return kTRUE;
	else if (tolower(first[i]) > tolower(second[i])) return kFALSE;
	++i;
    }
    return ( first.length() < second.length() );
}

Bool_t HDiskCatalog::cmpSize(HDiskDir* a,HDiskDir* b)
{
    // compare function for sorting dirs by size descending
    return ( a->getSize() > b->getSize() );
}

Bool_t HDiskCatalog::cmpNFiles(HDiskDir* a,HDiskDir* b)
{
    // compare function for sorting dirs by number of files descending
    return ( a->getNFilesTotal() > b->getNFilesTotal() );
}

Bool_t HDiskCatalog::cmpNSmallFiles(HDiskDir* a,HDiskDir* b)
{
    // compare function for sorting dirs by number of small files descending
    return ( a->getNSmallFilesTotal() > b->getNSmallFilesTotal() );
}

Bool_t HDiskCatalog::cmpNFilesRatio(HDiskDir* a,HDiskDir* b)
{
    // compare function for sorting dirs by number of small files descending
    Float_t ratioa = 0;
    Float_t ratiob = 0;
    if(a->getNFilesTotal()>0) ratioa= a->getNSmallFilesTotal()/(Float_t)a->getNFilesTotal();
    if(b->getNFilesTotal()>0) ratiob= b->getNSmallFilesTotal()/(Float_t)b->getNFilesTotal();

    return ( ratioa > ratiob );
}


HDiskDir* HDiskCatalog::getDir(TString name, Int_t* ind)
{
    // returns HDiskDir* p from index by name.
    // pointer is NULL if not found
    Int_t i = getDirMap(name);
    if(i>-1){
	if(ind!=0) *ind = i ;
	return (HDiskDir*) list->At(i);

    } else return NULL;
}

HDiskDir* HDiskCatalog::getDir(TString name,TObjArray* listtmp,Int_t* ind)
{
    // returns HDiskDir* p from index by name.
    // pointer is NULL if not found
    for(Int_t i = 0; i < listtmp->GetEntries(); i++){
	HDiskDir* dir = (HDiskDir*) listtmp->At(i);
	if(strcmp(dir->GetName(),name.Data()) == 0 ) {
	    if(ind!=0) *ind = i ;
	    return dir;
	}
    }
    return NULL;
}


void HDiskCatalog::print(UChar_t maxlevel)
{
    // prints all dirs (up to maxlevel, default is all)
    for(Int_t i=0; i< list->GetEntries();i++){
	HDiskDir* dir = ((HDiskDir*)list->At(i));
        if(dir->getLevel() > maxlevel) continue;
	dir->print();
    }
    printExecution();
}




void HDiskCatalog::loopDirectory(TString directory, vector<TString>& dirList)
{
    // fill all dir names of directory to vector.
    // uses readdir()
    dirList.clear();
    if(stat(directory.Data(),&status)==0)
    {
	HDiskDir* mydir  = 0;
	HDiskDir* olddir = getDirMapOld(directory.Data());
	Bool_t changed = kFALSE;

	if(olddir && olddir->getLastMod() != status.st_mtime) changed = kTRUE;
        Int_t index = -1;
	//-----------------------------------------------------------------
	// found a new dir to scan
	if(changed || !olddir) {
	    mydir = new HDiskDir(directory.Data());
	    flisttmp->AddLast(mydir);
	    index = flisttmp->GetEntries() -1;
	    mydir->scan(status,index,dirList);

	    cout<<"new : "<<setw(8)<<mydir->getNFiles()<<" files "<<mydir->GetName()<<endl;
	    fnfiles      += mydir->getNFiles();
	    fnfilestotal += mydir->getNFiles();
	    fndirs       ++;
	    addDir(mydir->GetName(),index);
	}
	//-----------------------------------------------------------------

	//-----------------------------------------------------------------
	// found an old unchanged dir
	if (olddir && !changed){   // copy old directory
	    mydir  = new HDiskDir(*olddir);
	    flisttmp->AddLast(mydir);
            index = flisttmp->GetEntries() -1;

	    mydir->setDirToFiles(index);

	    vector<Int_t>& dirs = mydir->getDirs();
	    for(UInt_t i = 0; i < dirs.size(); i++){
		HDiskDir* d = (HDiskDir*)list->At(dirs[i]);
                if(d) dirList.push_back(d->GetName());
                else  cout<<"ERROR : HDiskCatalog:loopDirectory() : Could not dir from old index "<<mydir->GetName()<<endl;
	    }
	    mydir->resetDirs(); // clear old indices

	    // missing recurse set ind files
	    fnfiles      += mydir->getNFiles();
	    fnfilestotal += mydir->getNFiles();
	    fndirs       ++;
	    addDir(mydir->GetName(),index);
	}
	//-----------------------------------------------------------------

	//-----------------------------------------------------------------
	// add dir to list of dirs of the mother dir

	HDiskDir* motherdir = 0 ;
	TString mothername  = gSystem->DirName(mydir->GetName());
	Int_t ind = getDirMap(mothername);
	if(ind >-1){
	    motherdir = (HDiskDir*)flisttmp->At(ind);
	}
	if(motherdir) {
	    motherdir->addDir(index);
	    mydir    ->setMother(ind);
	} else {
	    cout<<"ERROR : HDiskCatalog:loopDirectory() : Could not find mother dir of "<<mydir->GetName()<<" ("<<mothername<<" ?)"<<endl;
	}
	//-----------------------------------------------------------------
    } else {
	// TODO :  set timestamp of mother dir = 0 to froce rescan next time!

	cout<<"ERROR : HDiskCatalog:loopDirectory() : Could not stat dir "<<directory<<endl;

    }
}

void  HDiskCatalog::loopDirectoryRecursive(TString directory)
{
    // fill all dir names of directory rekursively to vector.
    // uses readdir()
    vector<TString> dirList;
    loopDirectory(directory,dirList);  // get the "root" directory's directories

    for(UInt_t i = 0; i < dirList.size(); ++i) // loop thru the list
    {
	loopDirectoryRecursive(dirList[i]);
    }
}

Bool_t HDiskCatalog::scan()
{
    // scans the disk and rescans dirs
    // which have been modified since last scan
    lastScanStart = time(&lastScanStart);
    TString mytime;
    HFileSys::getModTime(lastScanStart,mytime);
    cout<<"HDiskCatalog:scan() : disk is "<<diskname<<endl;
    cout<<"HDiskCatalog:scan() : start scannning  at "<<mytime<<endl;

    setCurrentCatalog();
    flisttmp = new TObjArray() ;
    mDirToInd.clear();

    //-----------------------------------------------------------------
    // for faster access remap old catalog
    mDirOld.clear();
    for(Int_t i = 0; i < list->GetEntries(); i++){
	HDiskDir* dir = (HDiskDir*)list->At(i);
        mDirOld[dir->GetName()] = dir;
    }
    //-----------------------------------------------------------------

    vector<TString>listofentries;
    vector<TString>listsubdirs;

    Int_t index        = -1;
    fnfilestotal       =  0;
    HDiskDir* base     =  0;

    //-----------------------------------------------------------------
    // create base dir
    if(stat(diskname.Data(),&status) == 0)
    {
	base = new HDiskDir(diskname.Data());
	flisttmp->AddLast(base);
	index = flisttmp->GetEntries()-1;
	base->scan(index);
	fnfilestotal += base->getNFiles();
        addDir(base->GetName(),index);

    } else {
	cout<<"ERROR : HDiskCatalog:scan() : Could not stat dir = "<<diskname.Data()<<endl;
        return kFALSE;
    }
    //-----------------------------------------------------------------

    //-----------------------------------------------------------------
    // get all 1st level subdirs of base
    HFileSys::lsDirectory(diskname,listsubdirs);

    for(UInt_t j = 0; j < listsubdirs.size(); j++)
    {
	fnfiles= 0;
        fndirs = 0;
	TString actdir=Form("%s/%s",diskname.Data(),listsubdirs[j].Data());

	//-----------------------------------------------------------------
        // create 1st level subdirs
	if(stat(actdir.Data(),&status) == 0)
	{
	    HDiskDir* level1 = new HDiskDir(actdir);
	    flisttmp->AddLast(level1);
	    index = flisttmp->GetEntries()-1;
            level1->scan(index);
	    base  ->addDir(index);
	    level1->setMother(0);
	    fnfilestotal +=level1->getNFiles();
	    fnfiles      +=level1->getNFiles();
	    fndirs      ++;
	    addDir(level1->GetName(),index);
 	} else {
	    cout<<"ERROR : HDiskCatalog:scan() : Could not stat dir = "<<diskname.Data()<<endl;
	    return kFALSE;
	}
	//-----------------------------------------------------------------

	//-----------------------------------------------------------------
        // now check all subdirs of each 1st level dir

	vector<TString>listofentries;
	HFileSys::lsDirectory(actdir, listofentries);
	cout<<"Scanning list of directories for "<<actdir<<endl;
	for(UInt_t i = 0; i < listofentries.size(); i++)
	{
	    loopDirectoryRecursive(Form("%s/%s",actdir.Data(),listofentries[i].Data()));
	}
	cout<<"Scanned "<<setw(8)<<fndirs<<" directories with "<<setw(8)<<fnfiles<<" files"<<endl;
    } // end loop level1 dirs
    //-----------------------------------------------------------------

    cout<<"Total Scanned "<<setw(8)<<index<<" directories with "<<setw(8)<<fnfilestotal<<" files"<<endl;

    //-----------------------------------------------------------------
    // exchange catalog
    for(Int_t i = 0; i < list->GetEntries(); i++){
	HDiskDir* dir = (HDiskDir*)list->At(i);
	delete dir;
    }
    delete list;

    list = flisttmp;
    //-----------------------------------------------------------------

    //-----------------------------------------------------------------
    // update the summary infos rekursively for each dir
    // and its subdirs
    cout<<"Updating list of directories "<<endl;
    for(Int_t i = 0; i < list->GetEntries(); i++){  // calulate sums of subdirs
	HDiskDir* dir = (HDiskDir*)list->At(i);
	vector<Int_t>& dirs = dir->getDirs();
        UInt_t n = 0;
	for(UInt_t j = 0;j < dirs.size(); j++){
	    if( ((HDiskDir*)list->At(dirs[j]))->isEmpty()) n++;
	}
        dir->setNEmptyDirs(n);
    }

    for(Int_t i = 0; i < list->GetEntries(); i++){  // calulate sums of subdirs
	HDiskDir* dir = (HDiskDir*)list->At(i);
	dir->update();
    }
    //-----------------------------------------------------------------


    lastScanStop = time(&lastScanStop);

    printExecution();
    return kTRUE;
}


void  HDiskCatalog::updateDirIndices()
{
    // set indices of daughter dirs
    // does not change nFilesTotal etc.
    TString mothername;
    Int_t indexMoth;
    for(Int_t i = 0; i < list->GetEntries(); i++){
	HDiskDir* dir = (HDiskDir*)list->At(i);
	mothername = gSystem->DirName(dir->GetName());
	HDiskDir* dmother =  getDir(mothername,&indexMoth);
        if(dmother) dmother->addDir(i);
    }


}


Int_t HDiskCatalog::addDir(HDiskDir* dir)
{
    // use this to produce super catalogs (new empty base,
    // than add dirs, last call updateDirIndices())
    Int_t   index        = -1;
    Int_t   indexMoth    = -1;
    TString  mothname = gSystem->DirName(dir->GetName());
    HDiskDir* dmother =  getDir(mothname,&indexMoth);

    HDiskDir* mydir  = new HDiskDir(*dir);
    list->AddLast(mydir);
    index = list->GetEntries()-1;
    mydir->setDirToFiles(index);     // correct index for file -> dir
    mydir->setLevel(mydir->getLevel()+1);
    addDir(mydir->GetName(),index);  // to map
    mydir->getDirs().clear();        // will be set in updateDirIndices()

    if(dmother)
    {
	if(indexMoth == 0)
	{
	    // adding summary infos for base
	    // all other levels are assumed to be correct
	    // already
	    dmother->addSize(mydir->getSize());
	    dmother->addNFilesTotal     (dir->getNFilesTotal());
	    dmother->addNSmallFilesTotal(dir->getNSmallFilesTotal());
	    dmother->addNDirsTotal      (dir->getNDirsTotal()+1);  // plus self
	    dmother->addNEmptyDirsTotal (dir->getNEmptyDirsTotal());
	}
    }
    return index;
}

void HDiskCatalog::getDaughterDirs(HDiskDir* dir, vector<HDiskDir*>& daughters)
{
    // get all daughters of dir by index
    daughters.clear();
    for(UInt_t i = 0; i < dir->getNDirs(); i++){
	HDiskDir* d = (HDiskDir*)list->At(dir->getDirs()[i]);
	if(d) {
	    daughters.push_back(d);
	}
    }
}

void HDiskCatalog::getDaughterDirsRecursive(HDiskDir* dir, vector<HDiskDir*>& list)
{
    // get all daughters of dir rekursively by index
    vector<HDiskDir*> daughters;
    getDaughterDirs(dir,daughters);

    for(UInt_t i = 0; i < daughters.size(); i++)
    {
	HDiskDir* d = daughters[i];
        list.push_back(d);
	getDaughterDirsRecursive(d,list);
    }
}

void HDiskCatalog::sortDirs(HDiskDir* dir,vector<HDiskDir*>& daughters,TString option)
{
    // sort daughters of dir by option
    // option: name        (name of owner)
    //         size        (size of directory)
    //         nfiles      (number of files in directory (rekursively))
    //         nsmallfiles (number of small files in directory(rekursively))
    //         filesratio  (number of small files in directory / number of total files)
    getDaughterDirs(dir,daughters);
    if(daughters.size()==0) return;
    if(option=="name")        { sort(daughters.begin(),daughters.end(),cmpName);       }
    if(option=="size")        { sort(daughters.begin(),daughters.end(),cmpSize);       }
    if(option=="nfiles")      { sort(daughters.begin(),daughters.end(),cmpNFiles);     }
    if(option=="nsmallfiles") { sort(daughters.begin(),daughters.end(),cmpNSmallFiles);}
    if(option=="filesratio")  { sort(daughters.begin(),daughters.end(),cmpNFilesRatio);}

}

void HDiskCatalog::sortDirsRecursive(HDiskDir* dir, vector<HDiskDir*>& dlist,TString option)
{
    // sort daughters of dir rekursively by option
    // option: name        (name of owner)
    //         size        (size of directory)
    //         nfiles      (number of files in directory (rekursively))
    //         nsmallfiles (number of small files in directory(rekursively))
    //         filesratio  (number of small files in directory / number of total files)
    vector<HDiskDir*> daughters;
    sortDirs(dir,daughters,option);

    for(UInt_t i = 0; i < daughters.size(); i ++) {
	HDiskDir* d = daughters[i];
	dlist.push_back(d);
        sortDirsRecursive(d,dlist,option);
    }
}

void HDiskCatalog::printDisk(UChar_t maxlevel,TString option ,Int_t nfill,TString filler)
{
    // prints the catalog of the disk
    // maxlevel : number of subdir levels to be shown
    // sort option: name        (name of owner)
    //              size        (size of directory)
    //              nfiles      (number of files in directory (rekursively))
    //              nsmallfiles (number of small files in directory(rekursively))
    //              filesratio  (number of small files / number of total files (rekursively))
    // nfill      :  number of character to be inserted in front for each level of subdirs
    // filler     :  character to be inserted in front for each level of subdirs
    TString replace = diskname ;
    replace +="/";
    Int_t maxreplace = 36;

    if(nfill==0) {
	if(replace.Length()<maxreplace) maxreplace = replace.Length();

	cout<<replace<<std::string(10+26-maxreplace,' ')
	    <<setw(8)<<""
	    <<" "<<""
	    <<" "<<setw(12)<<"uid"
	    <<" "<<setw(10)<<"gid"
	    <<" "<<setw(9)<<"files"
	    <<" "<<setw(9)<<"small f"
	    <<" "<<setw(9)<<"dirs"
	    <<" "<<setw(9)<<"empty d"
	    <<endl;
    } else {

	if(replace.Length()<maxlevel*nfill+26) maxreplace = replace.Length();
        else                                   maxreplace = maxlevel*nfill+26;

	cout<<replace<<std::string(maxlevel*nfill+26-maxreplace,' ')
	    <<setw(8)<<""
	    <<" "<<""
	    <<" "<<setw(12)<<"uid"
	    <<" "<<setw(10)<<"gid"
	    <<" "<<setw(9)<<"files"
	    <<" "<<setw(9)<<"small f"
	    <<" "<<setw(9)<<"dirs"
	    <<" "<<setw(9)<<"empty d"
	    <<endl;
    }


    HDiskDir* base = (HDiskDir*) list->At(0);
    vector<HDiskDir*> level1;
    vector<HDiskDir*> full;
    full.push_back(base);
    if(base){
	for(UInt_t i = 0; i < base->getNDirs(); i ++) {
            HDiskDir* lvl1 = (HDiskDir*) list->At(base->getDirs()[i]);
	    if(lvl1){
		level1.push_back(lvl1);
	    }
	}
    }


    if(option=="name")        { sort(level1.begin(),level1.end(),cmpName);       }
    if(option=="size")        { sort(level1.begin(),level1.end(),cmpSize);       }
    if(option=="nfiles")      { sort(level1.begin(),level1.end(),cmpNFiles);     }
    if(option=="nsmallfiles") { sort(level1.begin(),level1.end(),cmpNSmallFiles);}


    for(UInt_t i = 0; i < level1.size(); i ++) {
	full.push_back(level1[i]);
	sortDirsRecursive(level1[i],full,option);
    }

    for(UInt_t i=0;i<full.size();i++)
    {
	HDiskDir* dir = full[i];
	if(dir->getLevel() > maxlevel) continue;

	TString dirname = dir->GetName();
	dirname.ReplaceAll(replace.Data(),"");

	TString modtime ;
	TString sowner;
	TString sgroup;
	TString fsize;
	HFileSys::getModTime (dir->getLastMod(),modtime);
	HFileSys::getUser    (dir->getOwner(),sowner);
	HFileSys::getGroup   (dir->getGroup(),sgroup);
	HFileSys::getFileSize(dir->getSize(),fsize);


	if(nfill==0) {
	    cout<<std::string(10,' ')
		<<setw(8)<<fsize.Data()
		<<" "<<modtime.Data()
		<<" "<<setw(12)<<sowner
		<<" "<<setw(10)<<sgroup
		<<" "<<setw(9)<<dir->getNFilesTotal()
		<<" "<<setw(9)<<dir->getNSmallFilesTotal()
		<<" "<<setw(9)<<dir->getNDirsTotal()
		<<" "<<setw(9)<<dir->getNEmptyDirsTotal()
		<<" "<<dirname
		<<endl;
	} else {
	    cout<<std::string(dir->getLevel()*nfill,*filler.Data())
		<<setw(8)<<fsize.Data()
		<<std::string((maxlevel-dir->getLevel())*nfill,' ')
		<<" "<<modtime.Data()
		<<" "<<setw(12)<<sowner
		<<" "<<setw(10)<<sgroup
		<<" "<<setw(9)<<dir->getNFilesTotal()
		<<" "<<setw(9)<<dir->getNSmallFilesTotal()
		<<" "<<setw(9)<<dir->getNDirsTotal()
		<<" "<<setw(9)<<dir->getNEmptyDirsTotal()
		<<" "<<dirname<<endl;
	}
    }
    printExecution();
}

void HDiskCatalog::printExecution()
{
    // prints the execution start and stop time and the duration
    TString mytime;
    HFileSys::getModTime(lastScanStart,mytime);
    cout<<"scan started  at "<<mytime<<endl;
    HFileSys::getModTime(lastScanStop,mytime);
    cout<<"scan finished at "<<mytime<<" ("<<(lastScanStop-lastScanStart)/60.<<" minutes)"<<endl;
}

UInt_t HDiskCatalog::filterDirs(TString regexp,vector<HDiskDir*>& dirs,TString range1S,TString range2S,Long64_t size1)
{
    // filters all dirs fitting the regular expression regexp
    // TRegexp is used, read about the limitations
    // dirs cand be filtered by last modification range1 to range2
    // (format yyyy-mm-dd hh:mm:ss). default is no filter
   ULong64_t range1=0;
   ULong64_t range2=kMaxULong64-1;;

   TDatime damin;
   TDatime damax;

   struct tm t_min;
   struct tm t_max;


   ULong64_t size = abs(size1);

   if(range1S.CompareTo("")!=0) {
       damin.Set(range1S.Data());
       range1 = damin.Convert();
       localtime_r((time_t*)(&range1),&t_min);
   }


   if(range2S.CompareTo("")!=0) {
       damax.Set(range2S.Data());
       range2 = damax.Convert();
       localtime_r((time_t*)(&range2),&t_max);
   }
   TRegexp expr(regexp);
   dirs.clear();
   for(Int_t i=0;i< list->GetEntries();i++){
       HDiskDir* dir = (HDiskDir*)list->At(i);
       TString name = dir->GetName();
       if((ULong64_t)dir->getLastMod() < range1 || (ULong64_t)dir->getLastMod() > range2 ) continue;
       if     (size1 > 0 && dir->getSize()<size) continue;
       else if(size1 < 0 && dir->getSize()>size) continue;

       if(name(expr) != "") dirs.push_back(dir);
   }
   return dirs.size();
}

UInt_t HDiskCatalog::filterFiles(TString regexpdir,TString regexpfile,vector<HDiskFile*>& files,TString range1S,TString range2S,Long64_t size1)
{
    // filter all files fitting the regular expression regexpdir for
    // the path and regexpfile for the file name
    // TRegexp is used, read about the limitations
    // files cand be filtered by last modification range1 to range2
    // (format yyyy-mm-dd hh:mm:ss). default is no filter
   files.clear();

   ULong64_t range1=0;
   ULong64_t range2=kMaxULong64-1;
   ULong64_t size = abs(size1);

   TDatime damin;
   TDatime damax;

   struct tm t_min;
   struct tm t_max;

   if(range1S.CompareTo("")!=0) {
       damin.Set(range1S.Data());
       range1 = damin.Convert();
       localtime_r((time_t*)(&range1),&t_min);
   }


   if(range2S.CompareTo("")!=0) {
       damax.Set(range2S.Data());
       range2 = damax.Convert();
       localtime_r((time_t*)(&range2),&t_max);
   }

    TRegexp exprdir (regexpdir);
    TRegexp exprfile(regexpfile);
    TString modtime;
    TString sowner;
    TString sgroup;
    TString fsize;
    TString name;
    TString fname;
    for(Int_t i=0;i< list->GetEntries();i++){
	HDiskDir* dir = (HDiskDir*)list->At(i);
	name = dir->GetName();
	if(name(exprdir) != "") {
	    for(UInt_t j=0;j<dir->getNFiles();j++){
		HDiskFile& f = dir->getFiles()[j];
		fname = f.GetName();
		if((ULong64_t)f.getLastMod() < range1 || (ULong64_t)f.getLastMod() > range2 ) continue;
		if     (size1 > 0 && f.getSize()<size) continue;
		else if(size1 < 0 && f.getSize()>size) continue;

		if(fname(exprfile) != "") {
                   files.push_back(&f);
		}
	    }
	}
    }

    return files.size();
}

void HDiskCatalog::printDirs(TString regexp,TString range1S,TString range2S,Long64_t size)
{
    // prints all dirs fitting the regular expression regexp
    // TRegexp is used, read about the limitations
    // dirs cand be filtered by last modification range1 to range2
    // (format yyyy-mm-dd hh:mm:ss). default is no filter
   vector<HDiskDir*> dirs;
   filterDirs(regexp,dirs,range1S,range2S,size);
   for(UInt_t i=0;i < dirs.size();i++){
       HDiskDir* dir = dirs[i];
       dir->print();
   }
}

void HDiskCatalog::printFiles(TString regexpdir,TString regexpfile,TString range1S,TString range2S,Long64_t size)
{
    // prints all files fitting the regular expression regexpdir for
    // the path and regexpfile for the file name
    // TRegexp is used, read about the limitations
    // files cand be filtered by last modification range1 to range2
    // (format yyyy-mm-dd hh:mm:ss). default is no filter
    vector<HDiskFile*> files;
    filterFiles(regexpdir,regexpfile,files,range1S,range2S,size);
    TString modtime;
    TString sowner;
    TString sgroup;
    TString fsize;
    for(UInt_t i=0;i < files.size();i++){
	HDiskFile* f = files[i];
	HFileSys::getModTime (f->getLastMod(),modtime);
	HFileSys::getUser    (f->getOwner(),sowner);
	HFileSys::getGroup   (f->getGroup(),sgroup);
	HFileSys::getFileSize(f->getSize(),fsize);
        HDiskDir* dir = (HDiskDir*)list->At(f->getDir());
	cout<<setw(8) <<fsize.Data()
	    <<" "<<modtime.Data()
	    <<" "<<setw(15)<<sowner
	    <<" "<<setw(15)<<sgroup
	    <<" "<<dir->GetName()
	    <<"/"<<f->GetName()<<endl;
    }
}

Bool_t HDiskCatalog::getUser(uid_t uid,TString& name)
{
    // lookup of user uid in the map of
    // known users. if the user can not be
    // found the the user name will be unknown_uid
    name = Form("unknown_%i",uid);
    map<uid_t,TString>::iterator it = musers.find(uid);
    if(it!=musers.end()) { name = it->second; return kTRUE;}
    return kFALSE;
}

Bool_t HDiskCatalog::getGroup(gid_t gid,TString& name)
{
    // lookup of group gid in the map of
    // known groups. if the group can not be
    // found the the group name will be unknown_gid
    name = Form("unknown_%i",gid);
    map<gid_t,TString>::iterator it = mgroups.find(gid);
    if(it!=mgroups.end()) { name = it->second; return kTRUE;}
    return kFALSE;
}

void HDiskCatalog::Streamer(TBuffer &R__b)
{
   // Stream an object of class HDiskCatalog.

   UInt_t R__s, R__c;
   if (R__b.IsReading()) {
      Version_t R__v = R__b.ReadVersion(&R__s, &R__c); if (R__v) { }
      TNamed::Streamer(R__b);
      diskname.Streamer(R__b);
      //R__b >> list;


      {
         map<uid_t,TString> &R__stl =  musers;
         R__stl.clear();
         int R__i, R__n;
         R__b >> R__n;
         for (R__i = 0; R__i < R__n; R__i++) {
            unsigned int R__t;
            R__b >> R__t;
            TString R__t2;
            R__t2.Streamer(R__b);
            typedef unsigned int Value_t;
            std::pair<Value_t const, TString > R__t3(R__t,R__t2);
            R__stl.insert(R__t3);
         }
      }
      {
         map<gid_t,TString> &R__stl =  mgroups;
         R__stl.clear();
         int R__i, R__n;
         R__b >> R__n;
         for (R__i = 0; R__i < R__n; R__i++) {
            unsigned int R__t;
            R__b >> R__t;
            TString R__t2;
            R__t2.Streamer(R__b);
            typedef unsigned int Value_t;
            std::pair<Value_t const, TString > R__t3(R__t,R__t2);
            R__stl.insert(R__t3);
         }
      }
      R__b >> lastScanStart;
      R__b >> lastScanStop;
      {
         map<TString,Int_t> &R__stl =  mDirToInd;
         R__stl.clear();
         int R__i, R__n;
         R__b >> R__n;
         for (R__i = 0; R__i < R__n; R__i++) {
            TString R__t;
            R__t.Streamer(R__b);
            int R__t2;
            R__b >> R__t2;
            typedef TString Value_t;
            std::pair<Value_t const, int > R__t3(R__t,R__t2);
            R__stl.insert(R__t3);
         }
      }


      //--------------------------------------------------------------
      // read smaller objects into list
      R__b >> nSplit;

      for(Int_t i = 0; i < nSplit; i++)
      {
	  TObjArray* a = (TObjArray*) gDirectory->Get(Form("aList_%i",i));
	  if(a){
	      for(Int_t j = 0 ; j < a->GetEntries(); j++ ){
		  HDiskDir* d = (HDiskDir*)a->At(j);
		  list ->AddLast(d);
	      }
	      delete a;

	  } else {
	      Error("Streamer()","Could not retrieve TObjArray aList_%i",i);
	  }
      }
      //--------------------------------------------------------------



      R__b.CheckByteCount(R__s, R__c, HDiskCatalog::IsA());
   } else {
      R__c = R__b.WriteVersion(HDiskCatalog::IsA(), kTRUE);
      TNamed::Streamer(R__b);
      diskname.Streamer(R__b);
      //R__b << list;


      {
         map<uid_t,TString> &R__stl =  musers;
         int R__n=(true) ? int(R__stl.size()) : 0;
         R__b << R__n;
         if(R__n) {
            map<uid_t,TString>::iterator R__k;
            for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
            R__b << ((*R__k).first );
            ((TString&)((*R__k).second)).Streamer(R__b);
            }
         }
      }
      {
         map<gid_t,TString> &R__stl =  mgroups;
         int R__n=(true) ? int(R__stl.size()) : 0;
         R__b << R__n;
         if(R__n) {
            map<gid_t,TString>::iterator R__k;
            for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
            R__b << ((*R__k).first );
            ((TString&)((*R__k).second)).Streamer(R__b);
            }
         }
      }
      R__b << lastScanStart;
      R__b << lastScanStop;
      {
         map<TString,Int_t> &R__stl =  mDirToInd;
         int R__n=(true) ? int(R__stl.size()) : 0;
         R__b << R__n;
         if(R__n) {
            map<TString,Int_t>::iterator R__k;
            for (R__k = R__stl.begin(); R__k != R__stl.end(); ++R__k) {
            ((TString&)((*R__k).first )).Streamer(R__b);
            R__b << ((*R__k).second);
            }
         }
      }

      //--------------------------------------------------------------
      // split list into smaller objects
      nSplit       = 0;
      Int_t nPart  = 1000000;
      Int_t nF     = 0;
      TObjArray* a = new TObjArray();

      for(Int_t i = 0 ; i < list->GetEntries(); i++)
      {

	  HDiskDir* d = (HDiskDir*)list->At(i);
	  Int_t n = d->getNFiles();
	  if(nF+n >= nPart){
	      a->SetOwner(kFALSE);
	      a->Write(Form("aList_%i",nSplit),TObject::kSingleKey);
	      delete a;
	      a = new TObjArray();
              nF = 0;
	      nSplit++;
	  }
	  a ->AddLast(d);
          nF += n;
      }

      a->SetOwner(kFALSE);
      a->Write(Form("aList_%i",nSplit),TObject::kSingleKey);
      delete a;
      nSplit++;
      //--------------------------------------------------------------

      R__b << nSplit;
      R__b.SetByteCount(R__c, kTRUE);
   }
}

//----------------------------------------------------------------------------

HDiskStat::HDiskStat(TString name)
{
    diskname = name;

    Int_t colors[]=
    {
	kRed  ,kMagenta  ,kBlue  ,kCyan  ,kGreen  ,kOrange,
	kRed-6,kMagenta-6,kBlue-6,kCyan-6,kGreen-6,kOrange-6,
	kRed-7,kMagenta-7,kBlue-7,kCyan-7,kGreen-7,kOrange-7,
	kRed-2,kMagenta-2,kBlue-2,kCyan-2,kGreen-2,kOrange-2,kBlack
    };
   Int_t markers[]={
       20,21,22,23,24,25,26,27,28
   };

   Int_t styles[]={
       1,2
   };

   vcolors .assign(colors ,colors + sizeof(colors)  /sizeof(Int_t));
   vmarkers.assign(markers,markers + sizeof(markers)/sizeof(Int_t));
   vstyles .assign(styles ,styles  + sizeof(styles) /sizeof(Int_t));
   unit =  HFileSys::getUnitG() ;
}

HDiskStat::~HDiskStat()
{
    ;
}

Int_t HDiskStat::evalOpt(TString opt)
{
    Int_t index =-1;
    if     (opt=="size")        index = 0;
    else if(opt=="nfiles")      index = 1;
    else if(opt=="nsmallfiles") index = 2;
    else {
	cout<<"ERROR: HDiskStat::evalOpt(): Unknown option ="<<opt<<endl;
    }
    return index;
}

Bool_t HDiskStat::findMinMaxGraph(Double_t& xmin,Double_t& xmax,Double_t& ymin,Double_t& ymax,TGraph* g)
{
    xmax = 0;
    xmin = 0;
    ymax = 0;
    ymin = 0;
    Double_t x,y;

    for(Int_t i=0; i<g->GetN();i++){
	g->GetPoint(i,x,y);
	if(x<xmin || xmin==0) xmin = x;
	if(x>xmax || xmax==0) xmax = x;
	if(y<ymin || ymin==0) ymin = y;
	if(y>ymax || ymax==0) ymax = y;

    }
    return kTRUE;
}

Bool_t HDiskStat::findMinMaxAll(Double_t& xmin,Double_t& xmax,Double_t& ymin,Double_t& ymax,vector<TGraph*>& vg)
{
    xmax = 0;
    xmin = 0;
    ymax = 0;
    ymin = 0;
    TGraph*g  = 0;
    Double_t x1,x2,y1,y2;
    for(UInt_t i=0; i<vg.size(); i++ ) {
	g  = vg[i];
	findMinMaxGraph(x1,x2,y1,y2,g);

	if(x1<xmin || xmin==0) xmin = x1;
	if(x2>xmax || xmax==0) xmax = x2;

	if(y1<ymin || ymin==0) ymin = y1;
	if(y2>ymax || ymax==0) ymax = y2;
    }

    if(ymin==ymax && ymin!=0)   ymin=0;
    if(ymin==ymax && ymin==0) { ymin=0; ymax = 10;}

    return kTRUE;
}

Bool_t HDiskStat::findMinMaxAll(Double_t& xmin,Double_t& xmax,Double_t& ymin,Double_t& ymax,TString opt)
{
    Int_t index = 0 ;
    xmax = 0;
    xmin = 0;
    ymax = 0;
    ymin = 0;
    index=evalOpt(opt);
    if(index < 0 ) return kFALSE;
    TGraph*g  = 0;
    Double_t x1,x2,y1,y2;
    for(map<TString,vector<TGraph> >::iterator iter = mDirToVal.begin(); iter != mDirToVal.end(); ++iter ) {
	g  = &(iter->second[index]);
	findMinMaxGraph(x1,x2,y1,y2,g);

	if(x1<xmin || xmin==0) xmin = x1;
	if(x2>xmax || xmax==0) xmax = x2;

	if(y1<ymin || ymin==0) ymin = y1;
	if(y2>ymax || ymax==0) ymax = y2;
    }

    if(ymin==ymax && ymin!=0)   ymin=0;
    if(ymin==ymax && ymin==0) { ymin=0; ymax = 10;}

    return kTRUE;
}

TGraph* HDiskStat::getDir(TString dirname,TString opt)
{
    Int_t index = evalOpt(opt);
    if(index<0) return NULL;

    map<TString, vector<TGraph> >::iterator it = mDirToVal.find(dirname);
    if(it != mDirToVal.end()) {
	return &it->second[index];
    } else return NULL;
}

vector<TGraph>* HDiskStat::getDirVec(TString dirname)
{
    map<TString, vector<TGraph> >::iterator it = mDirToVal.find(dirname);
    if(it != mDirToVal.end()) {
	return &(it->second);
    }
    else return NULL;
}

void HDiskStat::addEntry(time_t scanstart,HDiskDir* dir)
{

    map<TString, vector<TGraph> >::iterator it = mDirToVal.find(dir->GetName());

    if(it != mDirToVal.end()) { // directory found, add entry
	it->second[0].SetPoint(it->second[0].GetN(),scanstart,dir->getSize());
        it->second[1].SetPoint(it->second[1].GetN(),scanstart,dir->getNFilesTotal());
        it->second[2].SetPoint(it->second[2].GetN(),scanstart,dir->getNSmallFilesTotal());

    } else { // new dir added, create all graphs
	vector<TGraph> v;

	TGraph gsize;
	gsize.SetName (Form("%s_size",dir->GetName()));
	gsize.SetPoint(gsize.GetN(),scanstart,dir->getSize());
	gsize.SetLineColor  (vcolors [(mDirToVal.size()+1)%vcolors .size()]);
	gsize.SetMarkerColor(vcolors [(mDirToVal.size()+1)%vcolors .size()]);
	gsize.SetMarkerStyle(vmarkers[(mDirToVal.size()+1)%vmarkers.size()]);
	gsize.SetLineStyle  (vstyles [(mDirToVal.size()+1)%vstyles .size()]);
	v.push_back(gsize);

	TGraph gnfiles;
	gnfiles.SetName (Form("%s_nfiles",dir->GetName()));
	gnfiles.SetPoint(gnfiles.GetN(),scanstart,dir->getNFilesTotal());
	gnfiles.SetLineColor  (vcolors [(mDirToVal.size()+1)%vcolors .size()]);
	gnfiles.SetMarkerColor(vcolors [(mDirToVal.size()+1)%vcolors .size()]);
	gnfiles.SetMarkerStyle(vmarkers[(mDirToVal.size()+1)%vmarkers.size()]);
	gnfiles.SetLineStyle  (vstyles [(mDirToVal.size()+1)%vstyles .size()]);
        v.push_back(gnfiles);

	TGraph gnsmallfiles;
	gnsmallfiles.SetName (Form("%s_nsmallfiles",dir->GetName()));
	gnsmallfiles.SetPoint(gnsmallfiles.GetN(),scanstart,dir->getNSmallFilesTotal());
	gnsmallfiles.SetLineColor  (vcolors [(mDirToVal.size()+1)%vcolors .size()]);
	gnsmallfiles.SetMarkerColor(vcolors [(mDirToVal.size()+1)%vcolors .size()]);
	gnsmallfiles.SetMarkerStyle(vmarkers[(mDirToVal.size()+1)%vmarkers.size()]);
	gnsmallfiles.SetLineStyle  (vstyles [(mDirToVal.size()+1)%vstyles .size()]);
	v.push_back(gnsmallfiles);

        mDirToVal[dir->GetName()] = v;

    }


}

TCanvas* HDiskStat::draw(TString opt,UInt_t lastDays,ULong64_t u,TString select)
{
    // select =  mother draws only mother dir
    //        =  default "daughters"

    Int_t index = evalOpt(opt);
    if (index < 0) return NULL;

    gStyle->SetOptStat(0);
    gStyle->SetPadTopMargin(0.08);
    gStyle->SetPadBottomMargin(0.2);
    gStyle->SetPadRightMargin(0.18);
    gStyle->SetPadLeftMargin(0.12);

    TString timeformat="#splitline{%d}{%b}";

    ULong64_t    U = unit;
    if( u != 0 ) U = u;
    if(opt != "size"  ) U = 1;

    time_t tnow=0;
    tnow=time(&tnow);

    TString timeStamp;
    HFileSys::getModTime(tnow,timeStamp);

    time_t tlowlimit = tnow - lastDays*86400L;   // low limit for range
    Double_t dtlow   = (Double_t)tlowlimit;

    //-----------------------------------------------------------
    // find range of data and convert to used unit
    Double_t xmax = 0;
    Double_t xmin = 0;
    Double_t ymax = 0;
    Double_t ymin = 0;

    findMinMaxAll(xmin,xmax,ymin,ymax,opt);   // full range all graphs
    ymax/=U;                                  // correct units
    ymin/=U;

    //-----------------------------------------------------------

    if(xmin > dtlow) {  // range of data was smaller than used limit
	dtlow     = xmin;
        tlowlimit = (time_t) xmin;
    }
    //-----------------------------------------------------------


    //-----------------------------------------------------------
    // extract the graphs using range
    vector<TGraph*> vg;
    Double_t x,y;
    for (map<TString,vector<TGraph> >::iterator it = mDirToVal.begin(); it != mDirToVal.end(); ++it) {
        TGraph& gin= it->second[index];
	TString name=it->first;
	name.ReplaceAll(diskname.Data(),"");
	if(select != "mother") {
          if(name == "") continue;  // skip base dir
	} else {
            if(name != "") continue;  // skip daughter dirs
	    name=gSystem->BaseName(it->first.Data()); // keep only last dir
	}

	TGraph* g = new TGraph();
	g->SetName(name.Data());
	g->SetLineColor(gin.GetLineColor());
	g->SetLineStyle(gin.GetLineStyle());
	g->SetLineWidth(gin.GetLineWidth());
	g->SetMarkerStyle(gin.GetMarkerStyle());
	g->SetMarkerColor(gin.GetMarkerColor());
	g->SetMarkerSize(gin.GetMarkerSize());
       


        Int_t ct=0;
	for(Int_t i=0;i<gin.GetN();i++){
	    gin.GetPoint(i,x,y);
	    if(x>=dtlow){
		g->SetPoint(ct,x,y/U);
		ct++;
	    }
	}
	if(g->GetN() > 0){             // skip grap with entry in range
	    Double_t x1 = 0;
	    Double_t x2 = 0;
	    Double_t y1 = 0;
	    Double_t y2 = 0;
            findMinMaxGraph(x1,x2,y1,y2,g);
	    if(y2>0) vg.push_back(g);  // skip empty dirs
            else     delete g;
	} else     delete g;
    }
    //-----------------------------------------------------------

    findMinMaxAll(xmin,xmax,ymin,ymax,vg); // range from selected graphs in range of interest


    //-----------------------------------------------------------
    // graphic output
    TCanvas* c = new TCanvas(Form("cuser_%s_%s",opt.Data(),select.Data()),"user stat",1000,800);
    gPad->SetGridy();
    gPad->SetGridx();

    TH2D* h = new TH2D(Form("hdir_%s_%s",opt.Data(),select.Data()),Form("%s : %s ",diskname.Data(),timeStamp.Data()),1000,xmin,xmax,10,ymin == 0 ? 0 : ymin*.9,ymax*1.1);
    h->GetXaxis()->SetTimeDisplay(1);
    h->GetXaxis()->SetTimeFormat(timeformat.Data());
    h->GetXaxis()->SetLabelSize(0.02);
    h->GetXaxis()->LabelsOption("v");
    h->GetXaxis()->SetTickLength(0);

    if     (opt == "size"  )      {
	if(U==HFileSys::getUnitK() ) h->SetYTitle("diskspace [KB]");
	if(U==HFileSys::getUnitM() ) h->SetYTitle("diskspace [MB]");
        if(U==HFileSys::getUnitG() ) h->SetYTitle("diskspace [GB]");
        if(U==HFileSys::getUnitT() ) h->SetYTitle("diskspace [TB]");
    }
    else if(opt == "nfiles")      h->SetYTitle("number of files");
    else if(opt == "nsmallfiles") h->SetYTitle("number of small files");

    h->GetYaxis()->SetTitleOffset(1.7);

    h->Draw();


    TLegend* l = new TLegend(0.83,0.97,0.995,0.03,"","brNDC");
    for(UInt_t i=0;i<vg.size();i++){
        TGraph* g = vg[i];
	l->AddEntry(g,g->GetName(),"lp");
    }
    l->Draw();

    for(UInt_t i=0;i<vg.size();i++){
        TGraph* g = vg[i];
	g->Draw("L");
	g->Draw("Psame");
    }
    //-----------------------------------------------------------

    return c;
}
 hdiskspace.cc:1
 hdiskspace.cc:2
 hdiskspace.cc:3
 hdiskspace.cc:4
 hdiskspace.cc:5
 hdiskspace.cc:6
 hdiskspace.cc:7
 hdiskspace.cc:8
 hdiskspace.cc:9
 hdiskspace.cc:10
 hdiskspace.cc:11
 hdiskspace.cc:12
 hdiskspace.cc:13
 hdiskspace.cc:14
 hdiskspace.cc:15
 hdiskspace.cc:16
 hdiskspace.cc:17
 hdiskspace.cc:18
 hdiskspace.cc:19
 hdiskspace.cc:20
 hdiskspace.cc:21
 hdiskspace.cc:22
 hdiskspace.cc:23
 hdiskspace.cc:24
 hdiskspace.cc:25
 hdiskspace.cc:26
 hdiskspace.cc:27
 hdiskspace.cc:28
 hdiskspace.cc:29
 hdiskspace.cc:30
 hdiskspace.cc:31
 hdiskspace.cc:32
 hdiskspace.cc:33
 hdiskspace.cc:34
 hdiskspace.cc:35
 hdiskspace.cc:36
 hdiskspace.cc:37
 hdiskspace.cc:38
 hdiskspace.cc:39
 hdiskspace.cc:40
 hdiskspace.cc:41
 hdiskspace.cc:42
 hdiskspace.cc:43
 hdiskspace.cc:44
 hdiskspace.cc:45
 hdiskspace.cc:46
 hdiskspace.cc:47
 hdiskspace.cc:48
 hdiskspace.cc:49
 hdiskspace.cc:50
 hdiskspace.cc:51
 hdiskspace.cc:52
 hdiskspace.cc:53
 hdiskspace.cc:54
 hdiskspace.cc:55
 hdiskspace.cc:56
 hdiskspace.cc:57
 hdiskspace.cc:58
 hdiskspace.cc:59
 hdiskspace.cc:60
 hdiskspace.cc:61
 hdiskspace.cc:62
 hdiskspace.cc:63
 hdiskspace.cc:64
 hdiskspace.cc:65
 hdiskspace.cc:66
 hdiskspace.cc:67
 hdiskspace.cc:68
 hdiskspace.cc:69
 hdiskspace.cc:70
 hdiskspace.cc:71
 hdiskspace.cc:72
 hdiskspace.cc:73
 hdiskspace.cc:74
 hdiskspace.cc:75
 hdiskspace.cc:76
 hdiskspace.cc:77
 hdiskspace.cc:78
 hdiskspace.cc:79
 hdiskspace.cc:80
 hdiskspace.cc:81
 hdiskspace.cc:82
 hdiskspace.cc:83
 hdiskspace.cc:84
 hdiskspace.cc:85
 hdiskspace.cc:86
 hdiskspace.cc:87
 hdiskspace.cc:88
 hdiskspace.cc:89
 hdiskspace.cc:90
 hdiskspace.cc:91
 hdiskspace.cc:92
 hdiskspace.cc:93
 hdiskspace.cc:94
 hdiskspace.cc:95
 hdiskspace.cc:96
 hdiskspace.cc:97
 hdiskspace.cc:98
 hdiskspace.cc:99
 hdiskspace.cc:100
 hdiskspace.cc:101
 hdiskspace.cc:102
 hdiskspace.cc:103
 hdiskspace.cc:104
 hdiskspace.cc:105
 hdiskspace.cc:106
 hdiskspace.cc:107
 hdiskspace.cc:108
 hdiskspace.cc:109
 hdiskspace.cc:110
 hdiskspace.cc:111
 hdiskspace.cc:112
 hdiskspace.cc:113
 hdiskspace.cc:114
 hdiskspace.cc:115
 hdiskspace.cc:116
 hdiskspace.cc:117
 hdiskspace.cc:118
 hdiskspace.cc:119
 hdiskspace.cc:120
 hdiskspace.cc:121
 hdiskspace.cc:122
 hdiskspace.cc:123
 hdiskspace.cc:124
 hdiskspace.cc:125
 hdiskspace.cc:126
 hdiskspace.cc:127
 hdiskspace.cc:128
 hdiskspace.cc:129
 hdiskspace.cc:130
 hdiskspace.cc:131
 hdiskspace.cc:132
 hdiskspace.cc:133
 hdiskspace.cc:134
 hdiskspace.cc:135
 hdiskspace.cc:136
 hdiskspace.cc:137
 hdiskspace.cc:138
 hdiskspace.cc:139
 hdiskspace.cc:140
 hdiskspace.cc:141
 hdiskspace.cc:142
 hdiskspace.cc:143
 hdiskspace.cc:144
 hdiskspace.cc:145
 hdiskspace.cc:146
 hdiskspace.cc:147
 hdiskspace.cc:148
 hdiskspace.cc:149
 hdiskspace.cc:150
 hdiskspace.cc:151
 hdiskspace.cc:152
 hdiskspace.cc:153
 hdiskspace.cc:154
 hdiskspace.cc:155
 hdiskspace.cc:156
 hdiskspace.cc:157
 hdiskspace.cc:158
 hdiskspace.cc:159
 hdiskspace.cc:160
 hdiskspace.cc:161
 hdiskspace.cc:162
 hdiskspace.cc:163
 hdiskspace.cc:164
 hdiskspace.cc:165
 hdiskspace.cc:166
 hdiskspace.cc:167
 hdiskspace.cc:168
 hdiskspace.cc:169
 hdiskspace.cc:170
 hdiskspace.cc:171
 hdiskspace.cc:172
 hdiskspace.cc:173
 hdiskspace.cc:174
 hdiskspace.cc:175
 hdiskspace.cc:176
 hdiskspace.cc:177
 hdiskspace.cc:178
 hdiskspace.cc:179
 hdiskspace.cc:180
 hdiskspace.cc:181
 hdiskspace.cc:182
 hdiskspace.cc:183
 hdiskspace.cc:184
 hdiskspace.cc:185
 hdiskspace.cc:186
 hdiskspace.cc:187
 hdiskspace.cc:188
 hdiskspace.cc:189
 hdiskspace.cc:190
 hdiskspace.cc:191
 hdiskspace.cc:192
 hdiskspace.cc:193
 hdiskspace.cc:194
 hdiskspace.cc:195
 hdiskspace.cc:196
 hdiskspace.cc:197
 hdiskspace.cc:198
 hdiskspace.cc:199
 hdiskspace.cc:200
 hdiskspace.cc:201
 hdiskspace.cc:202
 hdiskspace.cc:203
 hdiskspace.cc:204
 hdiskspace.cc:205
 hdiskspace.cc:206
 hdiskspace.cc:207
 hdiskspace.cc:208
 hdiskspace.cc:209
 hdiskspace.cc:210
 hdiskspace.cc:211
 hdiskspace.cc:212
 hdiskspace.cc:213
 hdiskspace.cc:214
 hdiskspace.cc:215
 hdiskspace.cc:216
 hdiskspace.cc:217
 hdiskspace.cc:218
 hdiskspace.cc:219
 hdiskspace.cc:220
 hdiskspace.cc:221
 hdiskspace.cc:222
 hdiskspace.cc:223
 hdiskspace.cc:224
 hdiskspace.cc:225
 hdiskspace.cc:226
 hdiskspace.cc:227
 hdiskspace.cc:228
 hdiskspace.cc:229
 hdiskspace.cc:230
 hdiskspace.cc:231
 hdiskspace.cc:232
 hdiskspace.cc:233
 hdiskspace.cc:234
 hdiskspace.cc:235
 hdiskspace.cc:236
 hdiskspace.cc:237
 hdiskspace.cc:238
 hdiskspace.cc:239
 hdiskspace.cc:240
 hdiskspace.cc:241
 hdiskspace.cc:242
 hdiskspace.cc:243
 hdiskspace.cc:244
 hdiskspace.cc:245
 hdiskspace.cc:246
 hdiskspace.cc:247
 hdiskspace.cc:248
 hdiskspace.cc:249
 hdiskspace.cc:250
 hdiskspace.cc:251
 hdiskspace.cc:252
 hdiskspace.cc:253
 hdiskspace.cc:254
 hdiskspace.cc:255
 hdiskspace.cc:256
 hdiskspace.cc:257
 hdiskspace.cc:258
 hdiskspace.cc:259
 hdiskspace.cc:260
 hdiskspace.cc:261
 hdiskspace.cc:262
 hdiskspace.cc:263
 hdiskspace.cc:264
 hdiskspace.cc:265
 hdiskspace.cc:266
 hdiskspace.cc:267
 hdiskspace.cc:268
 hdiskspace.cc:269
 hdiskspace.cc:270
 hdiskspace.cc:271
 hdiskspace.cc:272
 hdiskspace.cc:273
 hdiskspace.cc:274
 hdiskspace.cc:275
 hdiskspace.cc:276
 hdiskspace.cc:277
 hdiskspace.cc:278
 hdiskspace.cc:279
 hdiskspace.cc:280
 hdiskspace.cc:281
 hdiskspace.cc:282
 hdiskspace.cc:283
 hdiskspace.cc:284
 hdiskspace.cc:285
 hdiskspace.cc:286
 hdiskspace.cc:287
 hdiskspace.cc:288
 hdiskspace.cc:289
 hdiskspace.cc:290
 hdiskspace.cc:291
 hdiskspace.cc:292
 hdiskspace.cc:293
 hdiskspace.cc:294
 hdiskspace.cc:295
 hdiskspace.cc:296
 hdiskspace.cc:297
 hdiskspace.cc:298
 hdiskspace.cc:299
 hdiskspace.cc:300
 hdiskspace.cc:301
 hdiskspace.cc:302
 hdiskspace.cc:303
 hdiskspace.cc:304
 hdiskspace.cc:305
 hdiskspace.cc:306
 hdiskspace.cc:307
 hdiskspace.cc:308
 hdiskspace.cc:309
 hdiskspace.cc:310
 hdiskspace.cc:311
 hdiskspace.cc:312
 hdiskspace.cc:313
 hdiskspace.cc:314
 hdiskspace.cc:315
 hdiskspace.cc:316
 hdiskspace.cc:317
 hdiskspace.cc:318
 hdiskspace.cc:319
 hdiskspace.cc:320
 hdiskspace.cc:321
 hdiskspace.cc:322
 hdiskspace.cc:323
 hdiskspace.cc:324
 hdiskspace.cc:325
 hdiskspace.cc:326
 hdiskspace.cc:327
 hdiskspace.cc:328
 hdiskspace.cc:329
 hdiskspace.cc:330
 hdiskspace.cc:331
 hdiskspace.cc:332
 hdiskspace.cc:333
 hdiskspace.cc:334
 hdiskspace.cc:335
 hdiskspace.cc:336
 hdiskspace.cc:337
 hdiskspace.cc:338
 hdiskspace.cc:339
 hdiskspace.cc:340
 hdiskspace.cc:341
 hdiskspace.cc:342
 hdiskspace.cc:343
 hdiskspace.cc:344
 hdiskspace.cc:345
 hdiskspace.cc:346
 hdiskspace.cc:347
 hdiskspace.cc:348
 hdiskspace.cc:349
 hdiskspace.cc:350
 hdiskspace.cc:351
 hdiskspace.cc:352
 hdiskspace.cc:353
 hdiskspace.cc:354
 hdiskspace.cc:355
 hdiskspace.cc:356
 hdiskspace.cc:357
 hdiskspace.cc:358
 hdiskspace.cc:359
 hdiskspace.cc:360
 hdiskspace.cc:361
 hdiskspace.cc:362
 hdiskspace.cc:363
 hdiskspace.cc:364
 hdiskspace.cc:365
 hdiskspace.cc:366
 hdiskspace.cc:367
 hdiskspace.cc:368
 hdiskspace.cc:369
 hdiskspace.cc:370
 hdiskspace.cc:371
 hdiskspace.cc:372
 hdiskspace.cc:373
 hdiskspace.cc:374
 hdiskspace.cc:375
 hdiskspace.cc:376
 hdiskspace.cc:377
 hdiskspace.cc:378
 hdiskspace.cc:379
 hdiskspace.cc:380
 hdiskspace.cc:381
 hdiskspace.cc:382
 hdiskspace.cc:383
 hdiskspace.cc:384
 hdiskspace.cc:385
 hdiskspace.cc:386
 hdiskspace.cc:387
 hdiskspace.cc:388
 hdiskspace.cc:389
 hdiskspace.cc:390
 hdiskspace.cc:391
 hdiskspace.cc:392
 hdiskspace.cc:393
 hdiskspace.cc:394
 hdiskspace.cc:395
 hdiskspace.cc:396
 hdiskspace.cc:397
 hdiskspace.cc:398
 hdiskspace.cc:399
 hdiskspace.cc:400
 hdiskspace.cc:401
 hdiskspace.cc:402
 hdiskspace.cc:403
 hdiskspace.cc:404
 hdiskspace.cc:405
 hdiskspace.cc:406
 hdiskspace.cc:407
 hdiskspace.cc:408
 hdiskspace.cc:409
 hdiskspace.cc:410
 hdiskspace.cc:411
 hdiskspace.cc:412
 hdiskspace.cc:413
 hdiskspace.cc:414
 hdiskspace.cc:415
 hdiskspace.cc:416
 hdiskspace.cc:417
 hdiskspace.cc:418
 hdiskspace.cc:419
 hdiskspace.cc:420
 hdiskspace.cc:421
 hdiskspace.cc:422
 hdiskspace.cc:423
 hdiskspace.cc:424
 hdiskspace.cc:425
 hdiskspace.cc:426
 hdiskspace.cc:427
 hdiskspace.cc:428
 hdiskspace.cc:429
 hdiskspace.cc:430
 hdiskspace.cc:431
 hdiskspace.cc:432
 hdiskspace.cc:433
 hdiskspace.cc:434
 hdiskspace.cc:435
 hdiskspace.cc:436
 hdiskspace.cc:437
 hdiskspace.cc:438
 hdiskspace.cc:439
 hdiskspace.cc:440
 hdiskspace.cc:441
 hdiskspace.cc:442
 hdiskspace.cc:443
 hdiskspace.cc:444
 hdiskspace.cc:445
 hdiskspace.cc:446
 hdiskspace.cc:447
 hdiskspace.cc:448
 hdiskspace.cc:449
 hdiskspace.cc:450
 hdiskspace.cc:451
 hdiskspace.cc:452
 hdiskspace.cc:453
 hdiskspace.cc:454
 hdiskspace.cc:455
 hdiskspace.cc:456
 hdiskspace.cc:457
 hdiskspace.cc:458
 hdiskspace.cc:459
 hdiskspace.cc:460
 hdiskspace.cc:461
 hdiskspace.cc:462
 hdiskspace.cc:463
 hdiskspace.cc:464
 hdiskspace.cc:465
 hdiskspace.cc:466
 hdiskspace.cc:467
 hdiskspace.cc:468
 hdiskspace.cc:469
 hdiskspace.cc:470
 hdiskspace.cc:471
 hdiskspace.cc:472
 hdiskspace.cc:473
 hdiskspace.cc:474
 hdiskspace.cc:475
 hdiskspace.cc:476
 hdiskspace.cc:477
 hdiskspace.cc:478
 hdiskspace.cc:479
 hdiskspace.cc:480
 hdiskspace.cc:481
 hdiskspace.cc:482
 hdiskspace.cc:483
 hdiskspace.cc:484
 hdiskspace.cc:485
 hdiskspace.cc:486
 hdiskspace.cc:487
 hdiskspace.cc:488
 hdiskspace.cc:489
 hdiskspace.cc:490
 hdiskspace.cc:491
 hdiskspace.cc:492
 hdiskspace.cc:493
 hdiskspace.cc:494
 hdiskspace.cc:495
 hdiskspace.cc:496
 hdiskspace.cc:497
 hdiskspace.cc:498
 hdiskspace.cc:499
 hdiskspace.cc:500
 hdiskspace.cc:501
 hdiskspace.cc:502
 hdiskspace.cc:503
 hdiskspace.cc:504
 hdiskspace.cc:505
 hdiskspace.cc:506
 hdiskspace.cc:507
 hdiskspace.cc:508
 hdiskspace.cc:509
 hdiskspace.cc:510
 hdiskspace.cc:511
 hdiskspace.cc:512
 hdiskspace.cc:513
 hdiskspace.cc:514
 hdiskspace.cc:515
 hdiskspace.cc:516
 hdiskspace.cc:517
 hdiskspace.cc:518
 hdiskspace.cc:519
 hdiskspace.cc:520
 hdiskspace.cc:521
 hdiskspace.cc:522
 hdiskspace.cc:523
 hdiskspace.cc:524
 hdiskspace.cc:525
 hdiskspace.cc:526
 hdiskspace.cc:527
 hdiskspace.cc:528
 hdiskspace.cc:529
 hdiskspace.cc:530
 hdiskspace.cc:531
 hdiskspace.cc:532
 hdiskspace.cc:533
 hdiskspace.cc:534
 hdiskspace.cc:535
 hdiskspace.cc:536
 hdiskspace.cc:537
 hdiskspace.cc:538
 hdiskspace.cc:539
 hdiskspace.cc:540
 hdiskspace.cc:541
 hdiskspace.cc:542
 hdiskspace.cc:543
 hdiskspace.cc:544
 hdiskspace.cc:545
 hdiskspace.cc:546
 hdiskspace.cc:547
 hdiskspace.cc:548
 hdiskspace.cc:549
 hdiskspace.cc:550
 hdiskspace.cc:551
 hdiskspace.cc:552
 hdiskspace.cc:553
 hdiskspace.cc:554
 hdiskspace.cc:555
 hdiskspace.cc:556
 hdiskspace.cc:557
 hdiskspace.cc:558
 hdiskspace.cc:559
 hdiskspace.cc:560
 hdiskspace.cc:561
 hdiskspace.cc:562
 hdiskspace.cc:563
 hdiskspace.cc:564
 hdiskspace.cc:565
 hdiskspace.cc:566
 hdiskspace.cc:567
 hdiskspace.cc:568
 hdiskspace.cc:569
 hdiskspace.cc:570
 hdiskspace.cc:571
 hdiskspace.cc:572
 hdiskspace.cc:573
 hdiskspace.cc:574
 hdiskspace.cc:575
 hdiskspace.cc:576
 hdiskspace.cc:577
 hdiskspace.cc:578
 hdiskspace.cc:579
 hdiskspace.cc:580
 hdiskspace.cc:581
 hdiskspace.cc:582
 hdiskspace.cc:583
 hdiskspace.cc:584
 hdiskspace.cc:585
 hdiskspace.cc:586
 hdiskspace.cc:587
 hdiskspace.cc:588
 hdiskspace.cc:589
 hdiskspace.cc:590
 hdiskspace.cc:591
 hdiskspace.cc:592
 hdiskspace.cc:593
 hdiskspace.cc:594
 hdiskspace.cc:595
 hdiskspace.cc:596
 hdiskspace.cc:597
 hdiskspace.cc:598
 hdiskspace.cc:599
 hdiskspace.cc:600
 hdiskspace.cc:601
 hdiskspace.cc:602
 hdiskspace.cc:603
 hdiskspace.cc:604
 hdiskspace.cc:605
 hdiskspace.cc:606
 hdiskspace.cc:607
 hdiskspace.cc:608
 hdiskspace.cc:609
 hdiskspace.cc:610
 hdiskspace.cc:611
 hdiskspace.cc:612
 hdiskspace.cc:613
 hdiskspace.cc:614
 hdiskspace.cc:615
 hdiskspace.cc:616
 hdiskspace.cc:617
 hdiskspace.cc:618
 hdiskspace.cc:619
 hdiskspace.cc:620
 hdiskspace.cc:621
 hdiskspace.cc:622
 hdiskspace.cc:623
 hdiskspace.cc:624
 hdiskspace.cc:625
 hdiskspace.cc:626
 hdiskspace.cc:627
 hdiskspace.cc:628
 hdiskspace.cc:629
 hdiskspace.cc:630
 hdiskspace.cc:631
 hdiskspace.cc:632
 hdiskspace.cc:633
 hdiskspace.cc:634
 hdiskspace.cc:635
 hdiskspace.cc:636
 hdiskspace.cc:637
 hdiskspace.cc:638
 hdiskspace.cc:639
 hdiskspace.cc:640
 hdiskspace.cc:641
 hdiskspace.cc:642
 hdiskspace.cc:643
 hdiskspace.cc:644
 hdiskspace.cc:645
 hdiskspace.cc:646
 hdiskspace.cc:647
 hdiskspace.cc:648
 hdiskspace.cc:649
 hdiskspace.cc:650
 hdiskspace.cc:651
 hdiskspace.cc:652
 hdiskspace.cc:653
 hdiskspace.cc:654
 hdiskspace.cc:655
 hdiskspace.cc:656
 hdiskspace.cc:657
 hdiskspace.cc:658
 hdiskspace.cc:659
 hdiskspace.cc:660
 hdiskspace.cc:661
 hdiskspace.cc:662
 hdiskspace.cc:663
 hdiskspace.cc:664
 hdiskspace.cc:665
 hdiskspace.cc:666
 hdiskspace.cc:667
 hdiskspace.cc:668
 hdiskspace.cc:669
 hdiskspace.cc:670
 hdiskspace.cc:671
 hdiskspace.cc:672
 hdiskspace.cc:673
 hdiskspace.cc:674
 hdiskspace.cc:675
 hdiskspace.cc:676
 hdiskspace.cc:677
 hdiskspace.cc:678
 hdiskspace.cc:679
 hdiskspace.cc:680
 hdiskspace.cc:681
 hdiskspace.cc:682
 hdiskspace.cc:683
 hdiskspace.cc:684
 hdiskspace.cc:685
 hdiskspace.cc:686
 hdiskspace.cc:687
 hdiskspace.cc:688
 hdiskspace.cc:689
 hdiskspace.cc:690
 hdiskspace.cc:691
 hdiskspace.cc:692
 hdiskspace.cc:693
 hdiskspace.cc:694
 hdiskspace.cc:695
 hdiskspace.cc:696
 hdiskspace.cc:697
 hdiskspace.cc:698
 hdiskspace.cc:699
 hdiskspace.cc:700
 hdiskspace.cc:701
 hdiskspace.cc:702
 hdiskspace.cc:703
 hdiskspace.cc:704
 hdiskspace.cc:705
 hdiskspace.cc:706
 hdiskspace.cc:707
 hdiskspace.cc:708
 hdiskspace.cc:709
 hdiskspace.cc:710
 hdiskspace.cc:711
 hdiskspace.cc:712
 hdiskspace.cc:713
 hdiskspace.cc:714
 hdiskspace.cc:715
 hdiskspace.cc:716
 hdiskspace.cc:717
 hdiskspace.cc:718
 hdiskspace.cc:719
 hdiskspace.cc:720
 hdiskspace.cc:721
 hdiskspace.cc:722
 hdiskspace.cc:723
 hdiskspace.cc:724
 hdiskspace.cc:725
 hdiskspace.cc:726
 hdiskspace.cc:727
 hdiskspace.cc:728
 hdiskspace.cc:729
 hdiskspace.cc:730
 hdiskspace.cc:731
 hdiskspace.cc:732
 hdiskspace.cc:733
 hdiskspace.cc:734
 hdiskspace.cc:735
 hdiskspace.cc:736
 hdiskspace.cc:737
 hdiskspace.cc:738
 hdiskspace.cc:739
 hdiskspace.cc:740
 hdiskspace.cc:741
 hdiskspace.cc:742
 hdiskspace.cc:743
 hdiskspace.cc:744
 hdiskspace.cc:745
 hdiskspace.cc:746
 hdiskspace.cc:747
 hdiskspace.cc:748
 hdiskspace.cc:749
 hdiskspace.cc:750
 hdiskspace.cc:751
 hdiskspace.cc:752
 hdiskspace.cc:753
 hdiskspace.cc:754
 hdiskspace.cc:755
 hdiskspace.cc:756
 hdiskspace.cc:757
 hdiskspace.cc:758
 hdiskspace.cc:759
 hdiskspace.cc:760
 hdiskspace.cc:761
 hdiskspace.cc:762
 hdiskspace.cc:763
 hdiskspace.cc:764
 hdiskspace.cc:765
 hdiskspace.cc:766
 hdiskspace.cc:767
 hdiskspace.cc:768
 hdiskspace.cc:769
 hdiskspace.cc:770
 hdiskspace.cc:771
 hdiskspace.cc:772
 hdiskspace.cc:773
 hdiskspace.cc:774
 hdiskspace.cc:775
 hdiskspace.cc:776
 hdiskspace.cc:777
 hdiskspace.cc:778
 hdiskspace.cc:779
 hdiskspace.cc:780
 hdiskspace.cc:781
 hdiskspace.cc:782
 hdiskspace.cc:783
 hdiskspace.cc:784
 hdiskspace.cc:785
 hdiskspace.cc:786
 hdiskspace.cc:787
 hdiskspace.cc:788
 hdiskspace.cc:789
 hdiskspace.cc:790
 hdiskspace.cc:791
 hdiskspace.cc:792
 hdiskspace.cc:793
 hdiskspace.cc:794
 hdiskspace.cc:795
 hdiskspace.cc:796
 hdiskspace.cc:797
 hdiskspace.cc:798
 hdiskspace.cc:799
 hdiskspace.cc:800
 hdiskspace.cc:801
 hdiskspace.cc:802
 hdiskspace.cc:803
 hdiskspace.cc:804
 hdiskspace.cc:805
 hdiskspace.cc:806
 hdiskspace.cc:807
 hdiskspace.cc:808
 hdiskspace.cc:809
 hdiskspace.cc:810
 hdiskspace.cc:811
 hdiskspace.cc:812
 hdiskspace.cc:813
 hdiskspace.cc:814
 hdiskspace.cc:815
 hdiskspace.cc:816
 hdiskspace.cc:817
 hdiskspace.cc:818
 hdiskspace.cc:819
 hdiskspace.cc:820
 hdiskspace.cc:821
 hdiskspace.cc:822
 hdiskspace.cc:823
 hdiskspace.cc:824
 hdiskspace.cc:825
 hdiskspace.cc:826
 hdiskspace.cc:827
 hdiskspace.cc:828
 hdiskspace.cc:829
 hdiskspace.cc:830
 hdiskspace.cc:831
 hdiskspace.cc:832
 hdiskspace.cc:833
 hdiskspace.cc:834
 hdiskspace.cc:835
 hdiskspace.cc:836
 hdiskspace.cc:837
 hdiskspace.cc:838
 hdiskspace.cc:839
 hdiskspace.cc:840
 hdiskspace.cc:841
 hdiskspace.cc:842
 hdiskspace.cc:843
 hdiskspace.cc:844
 hdiskspace.cc:845
 hdiskspace.cc:846
 hdiskspace.cc:847
 hdiskspace.cc:848
 hdiskspace.cc:849
 hdiskspace.cc:850
 hdiskspace.cc:851
 hdiskspace.cc:852
 hdiskspace.cc:853
 hdiskspace.cc:854
 hdiskspace.cc:855
 hdiskspace.cc:856
 hdiskspace.cc:857
 hdiskspace.cc:858
 hdiskspace.cc:859
 hdiskspace.cc:860
 hdiskspace.cc:861
 hdiskspace.cc:862
 hdiskspace.cc:863
 hdiskspace.cc:864
 hdiskspace.cc:865
 hdiskspace.cc:866
 hdiskspace.cc:867
 hdiskspace.cc:868
 hdiskspace.cc:869
 hdiskspace.cc:870
 hdiskspace.cc:871
 hdiskspace.cc:872
 hdiskspace.cc:873
 hdiskspace.cc:874
 hdiskspace.cc:875
 hdiskspace.cc:876
 hdiskspace.cc:877
 hdiskspace.cc:878
 hdiskspace.cc:879
 hdiskspace.cc:880
 hdiskspace.cc:881
 hdiskspace.cc:882
 hdiskspace.cc:883
 hdiskspace.cc:884
 hdiskspace.cc:885
 hdiskspace.cc:886
 hdiskspace.cc:887
 hdiskspace.cc:888
 hdiskspace.cc:889
 hdiskspace.cc:890
 hdiskspace.cc:891
 hdiskspace.cc:892
 hdiskspace.cc:893
 hdiskspace.cc:894
 hdiskspace.cc:895
 hdiskspace.cc:896
 hdiskspace.cc:897
 hdiskspace.cc:898
 hdiskspace.cc:899
 hdiskspace.cc:900
 hdiskspace.cc:901
 hdiskspace.cc:902
 hdiskspace.cc:903
 hdiskspace.cc:904
 hdiskspace.cc:905
 hdiskspace.cc:906
 hdiskspace.cc:907
 hdiskspace.cc:908
 hdiskspace.cc:909
 hdiskspace.cc:910
 hdiskspace.cc:911
 hdiskspace.cc:912
 hdiskspace.cc:913
 hdiskspace.cc:914
 hdiskspace.cc:915
 hdiskspace.cc:916
 hdiskspace.cc:917
 hdiskspace.cc:918
 hdiskspace.cc:919
 hdiskspace.cc:920
 hdiskspace.cc:921
 hdiskspace.cc:922
 hdiskspace.cc:923
 hdiskspace.cc:924
 hdiskspace.cc:925
 hdiskspace.cc:926
 hdiskspace.cc:927
 hdiskspace.cc:928
 hdiskspace.cc:929
 hdiskspace.cc:930
 hdiskspace.cc:931
 hdiskspace.cc:932
 hdiskspace.cc:933
 hdiskspace.cc:934
 hdiskspace.cc:935
 hdiskspace.cc:936
 hdiskspace.cc:937
 hdiskspace.cc:938
 hdiskspace.cc:939
 hdiskspace.cc:940
 hdiskspace.cc:941
 hdiskspace.cc:942
 hdiskspace.cc:943
 hdiskspace.cc:944
 hdiskspace.cc:945
 hdiskspace.cc:946
 hdiskspace.cc:947
 hdiskspace.cc:948
 hdiskspace.cc:949
 hdiskspace.cc:950
 hdiskspace.cc:951
 hdiskspace.cc:952
 hdiskspace.cc:953
 hdiskspace.cc:954
 hdiskspace.cc:955
 hdiskspace.cc:956
 hdiskspace.cc:957
 hdiskspace.cc:958
 hdiskspace.cc:959
 hdiskspace.cc:960
 hdiskspace.cc:961
 hdiskspace.cc:962
 hdiskspace.cc:963
 hdiskspace.cc:964
 hdiskspace.cc:965
 hdiskspace.cc:966
 hdiskspace.cc:967
 hdiskspace.cc:968
 hdiskspace.cc:969
 hdiskspace.cc:970
 hdiskspace.cc:971
 hdiskspace.cc:972
 hdiskspace.cc:973
 hdiskspace.cc:974
 hdiskspace.cc:975
 hdiskspace.cc:976
 hdiskspace.cc:977
 hdiskspace.cc:978
 hdiskspace.cc:979
 hdiskspace.cc:980
 hdiskspace.cc:981
 hdiskspace.cc:982
 hdiskspace.cc:983
 hdiskspace.cc:984
 hdiskspace.cc:985
 hdiskspace.cc:986
 hdiskspace.cc:987
 hdiskspace.cc:988
 hdiskspace.cc:989
 hdiskspace.cc:990
 hdiskspace.cc:991
 hdiskspace.cc:992
 hdiskspace.cc:993
 hdiskspace.cc:994
 hdiskspace.cc:995
 hdiskspace.cc:996
 hdiskspace.cc:997
 hdiskspace.cc:998
 hdiskspace.cc:999
 hdiskspace.cc:1000
 hdiskspace.cc:1001
 hdiskspace.cc:1002
 hdiskspace.cc:1003
 hdiskspace.cc:1004
 hdiskspace.cc:1005
 hdiskspace.cc:1006
 hdiskspace.cc:1007
 hdiskspace.cc:1008
 hdiskspace.cc:1009
 hdiskspace.cc:1010
 hdiskspace.cc:1011
 hdiskspace.cc:1012
 hdiskspace.cc:1013
 hdiskspace.cc:1014
 hdiskspace.cc:1015
 hdiskspace.cc:1016
 hdiskspace.cc:1017
 hdiskspace.cc:1018
 hdiskspace.cc:1019
 hdiskspace.cc:1020
 hdiskspace.cc:1021
 hdiskspace.cc:1022
 hdiskspace.cc:1023
 hdiskspace.cc:1024
 hdiskspace.cc:1025
 hdiskspace.cc:1026
 hdiskspace.cc:1027
 hdiskspace.cc:1028
 hdiskspace.cc:1029
 hdiskspace.cc:1030
 hdiskspace.cc:1031
 hdiskspace.cc:1032
 hdiskspace.cc:1033
 hdiskspace.cc:1034
 hdiskspace.cc:1035
 hdiskspace.cc:1036
 hdiskspace.cc:1037
 hdiskspace.cc:1038
 hdiskspace.cc:1039
 hdiskspace.cc:1040
 hdiskspace.cc:1041
 hdiskspace.cc:1042
 hdiskspace.cc:1043
 hdiskspace.cc:1044
 hdiskspace.cc:1045
 hdiskspace.cc:1046
 hdiskspace.cc:1047
 hdiskspace.cc:1048
 hdiskspace.cc:1049
 hdiskspace.cc:1050
 hdiskspace.cc:1051
 hdiskspace.cc:1052
 hdiskspace.cc:1053
 hdiskspace.cc:1054
 hdiskspace.cc:1055
 hdiskspace.cc:1056
 hdiskspace.cc:1057
 hdiskspace.cc:1058
 hdiskspace.cc:1059
 hdiskspace.cc:1060
 hdiskspace.cc:1061
 hdiskspace.cc:1062
 hdiskspace.cc:1063
 hdiskspace.cc:1064
 hdiskspace.cc:1065
 hdiskspace.cc:1066
 hdiskspace.cc:1067
 hdiskspace.cc:1068
 hdiskspace.cc:1069
 hdiskspace.cc:1070
 hdiskspace.cc:1071
 hdiskspace.cc:1072
 hdiskspace.cc:1073
 hdiskspace.cc:1074
 hdiskspace.cc:1075
 hdiskspace.cc:1076
 hdiskspace.cc:1077
 hdiskspace.cc:1078
 hdiskspace.cc:1079
 hdiskspace.cc:1080
 hdiskspace.cc:1081
 hdiskspace.cc:1082
 hdiskspace.cc:1083
 hdiskspace.cc:1084
 hdiskspace.cc:1085
 hdiskspace.cc:1086
 hdiskspace.cc:1087
 hdiskspace.cc:1088
 hdiskspace.cc:1089
 hdiskspace.cc:1090
 hdiskspace.cc:1091
 hdiskspace.cc:1092
 hdiskspace.cc:1093
 hdiskspace.cc:1094
 hdiskspace.cc:1095
 hdiskspace.cc:1096
 hdiskspace.cc:1097
 hdiskspace.cc:1098
 hdiskspace.cc:1099
 hdiskspace.cc:1100
 hdiskspace.cc:1101
 hdiskspace.cc:1102
 hdiskspace.cc:1103
 hdiskspace.cc:1104
 hdiskspace.cc:1105
 hdiskspace.cc:1106
 hdiskspace.cc:1107
 hdiskspace.cc:1108
 hdiskspace.cc:1109
 hdiskspace.cc:1110
 hdiskspace.cc:1111
 hdiskspace.cc:1112
 hdiskspace.cc:1113
 hdiskspace.cc:1114
 hdiskspace.cc:1115
 hdiskspace.cc:1116
 hdiskspace.cc:1117
 hdiskspace.cc:1118
 hdiskspace.cc:1119
 hdiskspace.cc:1120
 hdiskspace.cc:1121
 hdiskspace.cc:1122
 hdiskspace.cc:1123
 hdiskspace.cc:1124
 hdiskspace.cc:1125
 hdiskspace.cc:1126
 hdiskspace.cc:1127
 hdiskspace.cc:1128
 hdiskspace.cc:1129
 hdiskspace.cc:1130
 hdiskspace.cc:1131
 hdiskspace.cc:1132
 hdiskspace.cc:1133
 hdiskspace.cc:1134
 hdiskspace.cc:1135
 hdiskspace.cc:1136
 hdiskspace.cc:1137
 hdiskspace.cc:1138
 hdiskspace.cc:1139
 hdiskspace.cc:1140
 hdiskspace.cc:1141
 hdiskspace.cc:1142
 hdiskspace.cc:1143
 hdiskspace.cc:1144
 hdiskspace.cc:1145
 hdiskspace.cc:1146
 hdiskspace.cc:1147
 hdiskspace.cc:1148
 hdiskspace.cc:1149
 hdiskspace.cc:1150
 hdiskspace.cc:1151
 hdiskspace.cc:1152
 hdiskspace.cc:1153
 hdiskspace.cc:1154
 hdiskspace.cc:1155
 hdiskspace.cc:1156
 hdiskspace.cc:1157
 hdiskspace.cc:1158
 hdiskspace.cc:1159
 hdiskspace.cc:1160
 hdiskspace.cc:1161
 hdiskspace.cc:1162
 hdiskspace.cc:1163
 hdiskspace.cc:1164
 hdiskspace.cc:1165
 hdiskspace.cc:1166
 hdiskspace.cc:1167
 hdiskspace.cc:1168
 hdiskspace.cc:1169
 hdiskspace.cc:1170
 hdiskspace.cc:1171
 hdiskspace.cc:1172
 hdiskspace.cc:1173
 hdiskspace.cc:1174
 hdiskspace.cc:1175
 hdiskspace.cc:1176
 hdiskspace.cc:1177
 hdiskspace.cc:1178
 hdiskspace.cc:1179
 hdiskspace.cc:1180
 hdiskspace.cc:1181
 hdiskspace.cc:1182
 hdiskspace.cc:1183
 hdiskspace.cc:1184
 hdiskspace.cc:1185
 hdiskspace.cc:1186
 hdiskspace.cc:1187
 hdiskspace.cc:1188
 hdiskspace.cc:1189
 hdiskspace.cc:1190
 hdiskspace.cc:1191
 hdiskspace.cc:1192
 hdiskspace.cc:1193
 hdiskspace.cc:1194
 hdiskspace.cc:1195
 hdiskspace.cc:1196
 hdiskspace.cc:1197
 hdiskspace.cc:1198
 hdiskspace.cc:1199
 hdiskspace.cc:1200
 hdiskspace.cc:1201
 hdiskspace.cc:1202
 hdiskspace.cc:1203
 hdiskspace.cc:1204
 hdiskspace.cc:1205
 hdiskspace.cc:1206
 hdiskspace.cc:1207
 hdiskspace.cc:1208
 hdiskspace.cc:1209
 hdiskspace.cc:1210
 hdiskspace.cc:1211
 hdiskspace.cc:1212
 hdiskspace.cc:1213
 hdiskspace.cc:1214
 hdiskspace.cc:1215
 hdiskspace.cc:1216
 hdiskspace.cc:1217
 hdiskspace.cc:1218
 hdiskspace.cc:1219
 hdiskspace.cc:1220
 hdiskspace.cc:1221
 hdiskspace.cc:1222
 hdiskspace.cc:1223
 hdiskspace.cc:1224
 hdiskspace.cc:1225
 hdiskspace.cc:1226
 hdiskspace.cc:1227
 hdiskspace.cc:1228
 hdiskspace.cc:1229
 hdiskspace.cc:1230
 hdiskspace.cc:1231
 hdiskspace.cc:1232
 hdiskspace.cc:1233
 hdiskspace.cc:1234
 hdiskspace.cc:1235
 hdiskspace.cc:1236
 hdiskspace.cc:1237
 hdiskspace.cc:1238
 hdiskspace.cc:1239
 hdiskspace.cc:1240
 hdiskspace.cc:1241
 hdiskspace.cc:1242
 hdiskspace.cc:1243
 hdiskspace.cc:1244
 hdiskspace.cc:1245
 hdiskspace.cc:1246
 hdiskspace.cc:1247
 hdiskspace.cc:1248
 hdiskspace.cc:1249
 hdiskspace.cc:1250
 hdiskspace.cc:1251
 hdiskspace.cc:1252
 hdiskspace.cc:1253
 hdiskspace.cc:1254
 hdiskspace.cc:1255
 hdiskspace.cc:1256
 hdiskspace.cc:1257
 hdiskspace.cc:1258
 hdiskspace.cc:1259
 hdiskspace.cc:1260
 hdiskspace.cc:1261
 hdiskspace.cc:1262
 hdiskspace.cc:1263
 hdiskspace.cc:1264
 hdiskspace.cc:1265
 hdiskspace.cc:1266
 hdiskspace.cc:1267
 hdiskspace.cc:1268
 hdiskspace.cc:1269
 hdiskspace.cc:1270
 hdiskspace.cc:1271
 hdiskspace.cc:1272
 hdiskspace.cc:1273
 hdiskspace.cc:1274
 hdiskspace.cc:1275
 hdiskspace.cc:1276
 hdiskspace.cc:1277
 hdiskspace.cc:1278
 hdiskspace.cc:1279
 hdiskspace.cc:1280
 hdiskspace.cc:1281
 hdiskspace.cc:1282
 hdiskspace.cc:1283
 hdiskspace.cc:1284
 hdiskspace.cc:1285
 hdiskspace.cc:1286
 hdiskspace.cc:1287
 hdiskspace.cc:1288
 hdiskspace.cc:1289
 hdiskspace.cc:1290
 hdiskspace.cc:1291
 hdiskspace.cc:1292
 hdiskspace.cc:1293
 hdiskspace.cc:1294
 hdiskspace.cc:1295
 hdiskspace.cc:1296
 hdiskspace.cc:1297
 hdiskspace.cc:1298
 hdiskspace.cc:1299
 hdiskspace.cc:1300
 hdiskspace.cc:1301
 hdiskspace.cc:1302
 hdiskspace.cc:1303
 hdiskspace.cc:1304
 hdiskspace.cc:1305
 hdiskspace.cc:1306
 hdiskspace.cc:1307
 hdiskspace.cc:1308
 hdiskspace.cc:1309
 hdiskspace.cc:1310
 hdiskspace.cc:1311
 hdiskspace.cc:1312
 hdiskspace.cc:1313
 hdiskspace.cc:1314
 hdiskspace.cc:1315
 hdiskspace.cc:1316
 hdiskspace.cc:1317
 hdiskspace.cc:1318
 hdiskspace.cc:1319
 hdiskspace.cc:1320
 hdiskspace.cc:1321
 hdiskspace.cc:1322
 hdiskspace.cc:1323
 hdiskspace.cc:1324
 hdiskspace.cc:1325
 hdiskspace.cc:1326
 hdiskspace.cc:1327
 hdiskspace.cc:1328
 hdiskspace.cc:1329
 hdiskspace.cc:1330
 hdiskspace.cc:1331
 hdiskspace.cc:1332
 hdiskspace.cc:1333
 hdiskspace.cc:1334
 hdiskspace.cc:1335
 hdiskspace.cc:1336
 hdiskspace.cc:1337
 hdiskspace.cc:1338
 hdiskspace.cc:1339
 hdiskspace.cc:1340
 hdiskspace.cc:1341
 hdiskspace.cc:1342
 hdiskspace.cc:1343
 hdiskspace.cc:1344
 hdiskspace.cc:1345
 hdiskspace.cc:1346
 hdiskspace.cc:1347
 hdiskspace.cc:1348
 hdiskspace.cc:1349
 hdiskspace.cc:1350
 hdiskspace.cc:1351
 hdiskspace.cc:1352
 hdiskspace.cc:1353
 hdiskspace.cc:1354
 hdiskspace.cc:1355
 hdiskspace.cc:1356
 hdiskspace.cc:1357
 hdiskspace.cc:1358
 hdiskspace.cc:1359
 hdiskspace.cc:1360
 hdiskspace.cc:1361
 hdiskspace.cc:1362
 hdiskspace.cc:1363
 hdiskspace.cc:1364
 hdiskspace.cc:1365
 hdiskspace.cc:1366
 hdiskspace.cc:1367
 hdiskspace.cc:1368
 hdiskspace.cc:1369
 hdiskspace.cc:1370
 hdiskspace.cc:1371
 hdiskspace.cc:1372
 hdiskspace.cc:1373
 hdiskspace.cc:1374
 hdiskspace.cc:1375
 hdiskspace.cc:1376
 hdiskspace.cc:1377
 hdiskspace.cc:1378
 hdiskspace.cc:1379
 hdiskspace.cc:1380
 hdiskspace.cc:1381
 hdiskspace.cc:1382
 hdiskspace.cc:1383
 hdiskspace.cc:1384
 hdiskspace.cc:1385
 hdiskspace.cc:1386
 hdiskspace.cc:1387
 hdiskspace.cc:1388
 hdiskspace.cc:1389
 hdiskspace.cc:1390
 hdiskspace.cc:1391
 hdiskspace.cc:1392
 hdiskspace.cc:1393
 hdiskspace.cc:1394
 hdiskspace.cc:1395
 hdiskspace.cc:1396
 hdiskspace.cc:1397
 hdiskspace.cc:1398
 hdiskspace.cc:1399
 hdiskspace.cc:1400
 hdiskspace.cc:1401
 hdiskspace.cc:1402
 hdiskspace.cc:1403
 hdiskspace.cc:1404
 hdiskspace.cc:1405
 hdiskspace.cc:1406
 hdiskspace.cc:1407
 hdiskspace.cc:1408
 hdiskspace.cc:1409
 hdiskspace.cc:1410
 hdiskspace.cc:1411
 hdiskspace.cc:1412
 hdiskspace.cc:1413
 hdiskspace.cc:1414
 hdiskspace.cc:1415
 hdiskspace.cc:1416
 hdiskspace.cc:1417
 hdiskspace.cc:1418
 hdiskspace.cc:1419
 hdiskspace.cc:1420
 hdiskspace.cc:1421
 hdiskspace.cc:1422
 hdiskspace.cc:1423
 hdiskspace.cc:1424
 hdiskspace.cc:1425
 hdiskspace.cc:1426
 hdiskspace.cc:1427
 hdiskspace.cc:1428
 hdiskspace.cc:1429
 hdiskspace.cc:1430
 hdiskspace.cc:1431
 hdiskspace.cc:1432
 hdiskspace.cc:1433
 hdiskspace.cc:1434
 hdiskspace.cc:1435
 hdiskspace.cc:1436
 hdiskspace.cc:1437
 hdiskspace.cc:1438
 hdiskspace.cc:1439
 hdiskspace.cc:1440
 hdiskspace.cc:1441
 hdiskspace.cc:1442
 hdiskspace.cc:1443
 hdiskspace.cc:1444
 hdiskspace.cc:1445
 hdiskspace.cc:1446
 hdiskspace.cc:1447
 hdiskspace.cc:1448
 hdiskspace.cc:1449
 hdiskspace.cc:1450
 hdiskspace.cc:1451
 hdiskspace.cc:1452
 hdiskspace.cc:1453
 hdiskspace.cc:1454
 hdiskspace.cc:1455
 hdiskspace.cc:1456
 hdiskspace.cc:1457
 hdiskspace.cc:1458
 hdiskspace.cc:1459
 hdiskspace.cc:1460
 hdiskspace.cc:1461
 hdiskspace.cc:1462
 hdiskspace.cc:1463
 hdiskspace.cc:1464
 hdiskspace.cc:1465
 hdiskspace.cc:1466
 hdiskspace.cc:1467
 hdiskspace.cc:1468
 hdiskspace.cc:1469
 hdiskspace.cc:1470
 hdiskspace.cc:1471
 hdiskspace.cc:1472
 hdiskspace.cc:1473
 hdiskspace.cc:1474
 hdiskspace.cc:1475
 hdiskspace.cc:1476
 hdiskspace.cc:1477
 hdiskspace.cc:1478
 hdiskspace.cc:1479
 hdiskspace.cc:1480
 hdiskspace.cc:1481
 hdiskspace.cc:1482
 hdiskspace.cc:1483
 hdiskspace.cc:1484
 hdiskspace.cc:1485
 hdiskspace.cc:1486
 hdiskspace.cc:1487
 hdiskspace.cc:1488
 hdiskspace.cc:1489
 hdiskspace.cc:1490
 hdiskspace.cc:1491
 hdiskspace.cc:1492
 hdiskspace.cc:1493
 hdiskspace.cc:1494
 hdiskspace.cc:1495
 hdiskspace.cc:1496
 hdiskspace.cc:1497
 hdiskspace.cc:1498
 hdiskspace.cc:1499
 hdiskspace.cc:1500
 hdiskspace.cc:1501
 hdiskspace.cc:1502
 hdiskspace.cc:1503
 hdiskspace.cc:1504
 hdiskspace.cc:1505
 hdiskspace.cc:1506
 hdiskspace.cc:1507
 hdiskspace.cc:1508
 hdiskspace.cc:1509
 hdiskspace.cc:1510
 hdiskspace.cc:1511
 hdiskspace.cc:1512
 hdiskspace.cc:1513
 hdiskspace.cc:1514
 hdiskspace.cc:1515
 hdiskspace.cc:1516
 hdiskspace.cc:1517
 hdiskspace.cc:1518
 hdiskspace.cc:1519
 hdiskspace.cc:1520
 hdiskspace.cc:1521
 hdiskspace.cc:1522
 hdiskspace.cc:1523
 hdiskspace.cc:1524
 hdiskspace.cc:1525
 hdiskspace.cc:1526
 hdiskspace.cc:1527
 hdiskspace.cc:1528
 hdiskspace.cc:1529
 hdiskspace.cc:1530
 hdiskspace.cc:1531
 hdiskspace.cc:1532
 hdiskspace.cc:1533
 hdiskspace.cc:1534
 hdiskspace.cc:1535
 hdiskspace.cc:1536
 hdiskspace.cc:1537
 hdiskspace.cc:1538
 hdiskspace.cc:1539
 hdiskspace.cc:1540
 hdiskspace.cc:1541
 hdiskspace.cc:1542
 hdiskspace.cc:1543
 hdiskspace.cc:1544
 hdiskspace.cc:1545
 hdiskspace.cc:1546
 hdiskspace.cc:1547
 hdiskspace.cc:1548
 hdiskspace.cc:1549
 hdiskspace.cc:1550
 hdiskspace.cc:1551
 hdiskspace.cc:1552
 hdiskspace.cc:1553
 hdiskspace.cc:1554
 hdiskspace.cc:1555
 hdiskspace.cc:1556
 hdiskspace.cc:1557
 hdiskspace.cc:1558
 hdiskspace.cc:1559
 hdiskspace.cc:1560
 hdiskspace.cc:1561
 hdiskspace.cc:1562
 hdiskspace.cc:1563
 hdiskspace.cc:1564
 hdiskspace.cc:1565
 hdiskspace.cc:1566
 hdiskspace.cc:1567
 hdiskspace.cc:1568
 hdiskspace.cc:1569
 hdiskspace.cc:1570
 hdiskspace.cc:1571
 hdiskspace.cc:1572
 hdiskspace.cc:1573
 hdiskspace.cc:1574
 hdiskspace.cc:1575
 hdiskspace.cc:1576
 hdiskspace.cc:1577
 hdiskspace.cc:1578
 hdiskspace.cc:1579
 hdiskspace.cc:1580
 hdiskspace.cc:1581
 hdiskspace.cc:1582
 hdiskspace.cc:1583
 hdiskspace.cc:1584
 hdiskspace.cc:1585
 hdiskspace.cc:1586
 hdiskspace.cc:1587
 hdiskspace.cc:1588
 hdiskspace.cc:1589
 hdiskspace.cc:1590
 hdiskspace.cc:1591
 hdiskspace.cc:1592
 hdiskspace.cc:1593
 hdiskspace.cc:1594
 hdiskspace.cc:1595
 hdiskspace.cc:1596
 hdiskspace.cc:1597
 hdiskspace.cc:1598
 hdiskspace.cc:1599
 hdiskspace.cc:1600
 hdiskspace.cc:1601
 hdiskspace.cc:1602
 hdiskspace.cc:1603
 hdiskspace.cc:1604
 hdiskspace.cc:1605
 hdiskspace.cc:1606
 hdiskspace.cc:1607
 hdiskspace.cc:1608
 hdiskspace.cc:1609
 hdiskspace.cc:1610
 hdiskspace.cc:1611
 hdiskspace.cc:1612
 hdiskspace.cc:1613
 hdiskspace.cc:1614
 hdiskspace.cc:1615
 hdiskspace.cc:1616
 hdiskspace.cc:1617
 hdiskspace.cc:1618
 hdiskspace.cc:1619
 hdiskspace.cc:1620
 hdiskspace.cc:1621
 hdiskspace.cc:1622
 hdiskspace.cc:1623
 hdiskspace.cc:1624
 hdiskspace.cc:1625
 hdiskspace.cc:1626
 hdiskspace.cc:1627
 hdiskspace.cc:1628
 hdiskspace.cc:1629
 hdiskspace.cc:1630
 hdiskspace.cc:1631
 hdiskspace.cc:1632
 hdiskspace.cc:1633
 hdiskspace.cc:1634
 hdiskspace.cc:1635
 hdiskspace.cc:1636
 hdiskspace.cc:1637
 hdiskspace.cc:1638
 hdiskspace.cc:1639
 hdiskspace.cc:1640
 hdiskspace.cc:1641
 hdiskspace.cc:1642
 hdiskspace.cc:1643
 hdiskspace.cc:1644
 hdiskspace.cc:1645
 hdiskspace.cc:1646
 hdiskspace.cc:1647
 hdiskspace.cc:1648
 hdiskspace.cc:1649
 hdiskspace.cc:1650
 hdiskspace.cc:1651
 hdiskspace.cc:1652
 hdiskspace.cc:1653
 hdiskspace.cc:1654
 hdiskspace.cc:1655
 hdiskspace.cc:1656
 hdiskspace.cc:1657
 hdiskspace.cc:1658
 hdiskspace.cc:1659
 hdiskspace.cc:1660
 hdiskspace.cc:1661
 hdiskspace.cc:1662
 hdiskspace.cc:1663
 hdiskspace.cc:1664
 hdiskspace.cc:1665
 hdiskspace.cc:1666
 hdiskspace.cc:1667
 hdiskspace.cc:1668
 hdiskspace.cc:1669
 hdiskspace.cc:1670
 hdiskspace.cc:1671
 hdiskspace.cc:1672
 hdiskspace.cc:1673
 hdiskspace.cc:1674
 hdiskspace.cc:1675
 hdiskspace.cc:1676
 hdiskspace.cc:1677
 hdiskspace.cc:1678
 hdiskspace.cc:1679
 hdiskspace.cc:1680
 hdiskspace.cc:1681
 hdiskspace.cc:1682
 hdiskspace.cc:1683
 hdiskspace.cc:1684
 hdiskspace.cc:1685
 hdiskspace.cc:1686
 hdiskspace.cc:1687
 hdiskspace.cc:1688
 hdiskspace.cc:1689
 hdiskspace.cc:1690
 hdiskspace.cc:1691
 hdiskspace.cc:1692
 hdiskspace.cc:1693
 hdiskspace.cc:1694
 hdiskspace.cc:1695
 hdiskspace.cc:1696
 hdiskspace.cc:1697
 hdiskspace.cc:1698
 hdiskspace.cc:1699
 hdiskspace.cc:1700
 hdiskspace.cc:1701
 hdiskspace.cc:1702
 hdiskspace.cc:1703
 hdiskspace.cc:1704
 hdiskspace.cc:1705
 hdiskspace.cc:1706
 hdiskspace.cc:1707
 hdiskspace.cc:1708
 hdiskspace.cc:1709
 hdiskspace.cc:1710
 hdiskspace.cc:1711
 hdiskspace.cc:1712
 hdiskspace.cc:1713
 hdiskspace.cc:1714
 hdiskspace.cc:1715
 hdiskspace.cc:1716
 hdiskspace.cc:1717
 hdiskspace.cc:1718
 hdiskspace.cc:1719
 hdiskspace.cc:1720
 hdiskspace.cc:1721
 hdiskspace.cc:1722
 hdiskspace.cc:1723
 hdiskspace.cc:1724
 hdiskspace.cc:1725
 hdiskspace.cc:1726
 hdiskspace.cc:1727
 hdiskspace.cc:1728
 hdiskspace.cc:1729
 hdiskspace.cc:1730
 hdiskspace.cc:1731
 hdiskspace.cc:1732
 hdiskspace.cc:1733
 hdiskspace.cc:1734
 hdiskspace.cc:1735
 hdiskspace.cc:1736
 hdiskspace.cc:1737
 hdiskspace.cc:1738
 hdiskspace.cc:1739
 hdiskspace.cc:1740
 hdiskspace.cc:1741
 hdiskspace.cc:1742
 hdiskspace.cc:1743
 hdiskspace.cc:1744
 hdiskspace.cc:1745
 hdiskspace.cc:1746
 hdiskspace.cc:1747
 hdiskspace.cc:1748
 hdiskspace.cc:1749
 hdiskspace.cc:1750
 hdiskspace.cc:1751
 hdiskspace.cc:1752
 hdiskspace.cc:1753
 hdiskspace.cc:1754
 hdiskspace.cc:1755
 hdiskspace.cc:1756
 hdiskspace.cc:1757
 hdiskspace.cc:1758
 hdiskspace.cc:1759
 hdiskspace.cc:1760
 hdiskspace.cc:1761
 hdiskspace.cc:1762
 hdiskspace.cc:1763
 hdiskspace.cc:1764
 hdiskspace.cc:1765
 hdiskspace.cc:1766
 hdiskspace.cc:1767
 hdiskspace.cc:1768
 hdiskspace.cc:1769
 hdiskspace.cc:1770
 hdiskspace.cc:1771
 hdiskspace.cc:1772
 hdiskspace.cc:1773
 hdiskspace.cc:1774
 hdiskspace.cc:1775
 hdiskspace.cc:1776
 hdiskspace.cc:1777