Use fstreewalk-based du-like code to compute index size instead of executing du

This commit is contained in:
Jean-Francois Dockes 2019-01-30 13:43:36 +01:00
parent 2909eec062
commit d2c87318cb
5 changed files with 52 additions and 14 deletions

View File

@ -42,7 +42,7 @@ class RclConfig;
enum RclInitFlags {RCLINIT_NONE = 0, RCLINIT_DAEMON = 1, RCLINIT_IDX = 2};
extern RclConfig *recollinit(int flags,
void (*cleanup)(void), void (*sigcleanup)(int),
std::string& reason, const string *argcnf = 0);
std::string& reason, const std::string *argcnf = 0);
inline RclConfig *recollinit(void (*cleanup)(void), void (*sigcleanup)(int),
std::string& reason,
const std::string *argcnf = 0)

View File

@ -46,6 +46,7 @@
#include "wasatorcl.h"
#include "execmd.h"
#include "indexer.h"
#include "fstreewalk.h"
using std::list;
using std::multimap;
@ -319,16 +320,9 @@ void SpellW::showStats()
baseWordLE->setText(QString::fromLocal8Bit(theconfig->getDbDir().c_str()));
ExecCmd cmd;
vector<string> args;
int status;
args.push_back("-sk");
args.push_back(theconfig->getDbDir());
string output;
status = cmd.doexec("du", args, 0, &output);
long long dbkbytes = 0;
if (!status) {
dbkbytes = atoll(output.c_str());
int64_t dbkbytes = fsTreeBytes(theconfig->getDbDir()) / 1024;
if (dbkbytes < 0) {
dbkbytes = 0;
}
resTW->setRowCount(row+1);
resTW->setItem(row, 0,

View File

@ -476,7 +476,33 @@ FsTreeWalker::Status FsTreeWalker::iwalk(const string &top,
CLOSEDIR(d);
return status;
}
int64_t fsTreeBytes(const string& topdir)
{
class bytesCB : public FsTreeWalkerCB {
public:
FsTreeWalker::Status processone(const string &path,
const struct stat *st,
FsTreeWalker::CbFlag flg) {
if (flg == FsTreeWalker::FtwDirEnter ||
flg == FsTreeWalker::FtwRegular) {
totalbytes += st->st_blocks * 512;
}
return FsTreeWalker::FtwOk;
}
int64_t totalbytes{0};
};
FsTreeWalker walker;
bytesCB cb;
FsTreeWalker::Status status = walker.walk(topdir, cb);
if (status != FsTreeWalker::FtwOk) {
LOGERR("fsTreeBytes: walker failed: " << walker.getReason() << endl);
return -1;
}
return cb.totalbytes;
}
#else // TEST_FSTREEWALK
#include <stdio.h>
@ -504,7 +530,7 @@ static int op_flags;
#define OPT_w 0x200
#define OPT_M 0x400
#define OPT_D 0x800
#define OPT_k 0x1000
class myCB : public FsTreeWalkerCB {
public:
FsTreeWalker::Status processone(const string &path,
@ -556,6 +582,7 @@ static char usage [] =
" -w : unset default FNM_PATHNAME when using fnmatch() to match skipped paths\n"
" -M <depth>: limit depth (works with -b/m/d)\n"
" -D : skip dotfiles\n"
"-k : like du\n"
;
static void
Usage(void)
@ -583,6 +610,7 @@ int main(int argc, const char **argv)
case 'c': op_flags |= OPT_c; break;
case 'd': op_flags |= OPT_d; break;
case 'D': op_flags |= OPT_D; break;
case 'k': op_flags |= OPT_k; break;
case 'L': op_flags |= OPT_L; break;
case 'm': op_flags |= OPT_m; break;
case 'M': op_flags |= OPT_M; if (argc < 2) Usage();
@ -608,6 +636,17 @@ int main(int argc, const char **argv)
Usage();
string topdir = *argv++;argc--;
if (op_flags & OPT_k) {
int64_t bytes = fsTreeBytes(topdir);
if (bytes < 0) {
cerr << "fsTreeBytes failed\n";
return 1;
} else {
cout << bytes / 1024 << "\t" << topdir << endl;
return 0;
}
}
int opt = 0;
if (op_flags & OPT_r)
opt |= FsTreeWalker::FtwNoRecurse;
@ -645,4 +684,3 @@ int main(int argc, const char **argv)
}
#endif // TEST_FSTREEWALK

View File

@ -125,4 +125,8 @@ class FsTreeWalkerCB {
processone(const string &, const struct stat *, FsTreeWalker::CbFlag)
= 0;
};
// Utility function. Somewhat like du.
int64_t fsTreeBytes(const string& topdir);
#endif /* _FSTREEWALK_H_INCLUDED_ */

View File

@ -558,6 +558,8 @@ int path_fileprops(const std::string path, struct stat *stp, bool follow)
stp->st_dev = mst.st_dev;
stp->st_ctime = mst.st_ctime;
#endif
stp->st_blocks = mst.st_blocks;
stp->st_blksize = mst.st_blksize;
return 0;
}