Commit 4a859c17 authored by Jean-Francois Dockes's avatar Jean-Francois Dockes
Browse files

trcircache web cache mgmt utility/test driver: add option to append entries from other file

--HG--
branch : RECOLL_1_21_MAINT
parent 89e21cf9
...@@ -1327,12 +1327,58 @@ static bool inflateToDynBuf(void* inp, UINT inlen, void **outpp, UINT *outlenp) ...@@ -1327,12 +1327,58 @@ static bool inflateToDynBuf(void* inp, UINT inlen, void **outpp, UINT *outlenp)
using namespace std; using namespace std;
// Copy all entries from occ to ncc. Both are already open.
bool copyall(RefCntr<CirCache> occ, RefCntr<CirCache> ncc, int& nentries)
{
bool eof = false;
if (!occ->rewind(eof)) {
if (!eof) {
cerr << "Initial rewind failed" << endl;
return false;
}
}
nentries = 0;
while (!eof) {
string udi, sdic, data;
if (!occ->getCurrent(udi, sdic, data)) {
cerr << "getCurrent failed: " << occ->getReason() << endl;
return false;
}
// Shouldn't getcurrent deal with this ?
if (sdic.size() == 0) {
//cerr << "Skip empty entry" << endl;
occ->next(eof);
continue;
}
ConfSimple dic(sdic);
if (!dic.ok()) {
cerr << "Could not parse entry attributes dic" << endl;
return false;
}
//cerr << "UDI: " << udi << endl;
if (!ncc->put(udi, &dic, data)) {
cerr << "put failed: " << ncc->getReason() << " sdic [" << sdic <<
"]" << endl;
return false;
}
nentries++;
occ->next(eof);
}
return true;
}
// Resize circache. This can't be done easily if the write point is
// inside the file (we already reached the old max size). We create a
// new file with the new size and copy the old entries into it. The
// old file is then renamed into a backup and the new file renamed in
// place.
bool resizecc(const string& dir, int newmbs) bool resizecc(const string& dir, int newmbs)
{ {
// Create object for existing file and get the file name
RefCntr<CirCache> occ(new CirCache(dir)); RefCntr<CirCache> occ(new CirCache(dir));
string ofn = occ->getpath(); string ofn = occ->getpath();
// Check for previous backup
string backupfn = ofn + ".orig"; string backupfn = ofn + ".orig";
if (access(backupfn.c_str(), 0) >= 0) { if (access(backupfn.c_str(), 0) >= 0) {
cerr << "Backup file " << backupfn << cerr << "Backup file " << backupfn <<
...@@ -1340,10 +1386,12 @@ bool resizecc(const string& dir, int newmbs) ...@@ -1340,10 +1386,12 @@ bool resizecc(const string& dir, int newmbs)
return false; return false;
} }
if (!occ->open(CirCache::CC_OPWRITE)) { if (!occ->open(CirCache::CC_OPREAD)) {
cerr << "Open failed in " << dir << " : " << occ->getReason() << endl; cerr << "Open failed in " << dir << " : " << occ->getReason() << endl;
return false; return false;
} }
// Create the new empty file in a temporary directory
string tmpdir = path_cat(dir, "tmp"); string tmpdir = path_cat(dir, "tmp");
if (access(tmpdir.c_str(), 0) < 0) { if (access(tmpdir.c_str(), 0) < 0) {
if (mkdir(tmpdir.c_str(), 0700) < 0) { if (mkdir(tmpdir.c_str(), 0700) < 0) {
...@@ -1352,7 +1400,6 @@ bool resizecc(const string& dir, int newmbs) ...@@ -1352,7 +1400,6 @@ bool resizecc(const string& dir, int newmbs)
return false; return false;
} }
} }
RefCntr<CirCache> ncc(new CirCache(tmpdir)); RefCntr<CirCache> ncc(new CirCache(tmpdir));
string nfn = ncc->getpath(); string nfn = ncc->getpath();
if (!ncc->create(off_t(newmbs) * 1000 * 1024, if (!ncc->create(off_t(newmbs) * 1000 * 1024,
...@@ -1362,53 +1409,29 @@ bool resizecc(const string& dir, int newmbs) ...@@ -1362,53 +1409,29 @@ bool resizecc(const string& dir, int newmbs)
return false; return false;
} }
bool eof = false; int nentries;
if (!occ->rewind(eof)) { if (!copyall(occ, ncc, nentries)) {
if (!eof) { cerr << "Copy failed\n";
cerr << "Initial rewind failed" << endl;
return false; return false;
} }
}
int nentries = 0;
while (!eof) {
string udi, sdic, data;
if (!occ->getCurrent(udi, sdic, data)) {
cerr << "getCurrent failed: " << occ->getReason() << endl;
return false;
}
// Shouldn't getcurrent deal with this ?
if (sdic.size() == 0) {
//cerr << "Skip empty entry" << endl;
occ->next(eof);
continue;
}
ConfSimple dic(sdic);
if (!dic.ok()) {
cerr << "Could not parse entry attributes dic" << endl;
return false;
}
//cerr << "UDI: " << udi << endl;
if (!ncc->put(udi, &dic, data)) {
cerr << "put failed: " << ncc->getReason() << " sdic [" << sdic <<
"]" << endl;
return false;
}
nentries++;
occ->next(eof);
}
// Done with our objects here, there is no close() method, so delete them // Done with our objects here, there is no close() method, so
// delete them
occ.release(); occ.release();
ncc.release(); ncc.release();
// Create backup by renaming the old file
if (rename(ofn.c_str(), backupfn.c_str()) < 0) { if (rename(ofn.c_str(), backupfn.c_str()) < 0) {
cerr << "Could not create backup " << backupfn << " : "; cerr << "Could not create backup " << backupfn << " : ";
perror("rename"); perror("rename");
return false; return false;
} }
cout << "Created backup file " << backupfn << endl; cout << "Created backup file " << backupfn << endl;
// Move the new file in place.
if (rename(nfn.c_str(), ofn.c_str()) < 0) { if (rename(nfn.c_str(), ofn.c_str()) < 0) {
cerr << "Could not rename new file from " << nfn << " to " << ofn << " : "; cerr << "Could not rename new file from " << nfn << " to " <<
ofn << " : ";
perror("rename"); perror("rename");
return false; return false;
} }
...@@ -1416,6 +1439,34 @@ bool resizecc(const string& dir, int newmbs) ...@@ -1416,6 +1439,34 @@ bool resizecc(const string& dir, int newmbs)
return true; return true;
} }
// Append all entries from sdir to ddir
bool appendcc(const string ddir, const string& sdir)
{
// Open source file
RefCntr<CirCache> occ(new CirCache(sdir));
if (!occ->open(CirCache::CC_OPREAD)) {
cerr << "Open failed in " << sdir << " : " << occ->getReason() << endl;
return false;
}
// Open dest file
RefCntr<CirCache> ncc(new CirCache(ddir));
if (!ncc->open(CirCache::CC_OPWRITE)) {
cerr << "Open failed in " << ddir << " : " << ncc->getReason() << endl;
return false;
}
int nentries;
if (!copyall(occ, ncc, nentries)) {
cerr << "Copy failed\n";
return false;
}
occ.release();
ncc.release();
cout << "Copy done, copied " << nentries << " entries " << endl;
return true;
}
static char *thisprog; static char *thisprog;
...@@ -1427,7 +1478,11 @@ static char usage [] = ...@@ -1427,7 +1478,11 @@ static char usage [] =
" -D: also dump data\n" " -D: also dump data\n"
" -e <dirname> <udi> : erase\n" " -e <dirname> <udi> : erase\n"
" -s <dirname> <newmbs> : resize\n" " -s <dirname> <newmbs> : resize\n"
" -a <targetdir> <dir> [<dir> ...]: append old content to target\n"
" The target should be first resized to hold all the data, else only\n"
" as many entries as capacity permit will be retained\n"
; ;
static void static void
Usage(FILE *fp = stderr) Usage(FILE *fp = stderr)
{ {
...@@ -1446,6 +1501,7 @@ static int op_flags; ...@@ -1446,6 +1501,7 @@ static int op_flags;
#define OPT_u 0x100 #define OPT_u 0x100
#define OPT_e 0x200 #define OPT_e 0x200
#define OPT_s 0x400 #define OPT_s 0x400
#define OPT_a 0x800
int main(int argc, char **argv) int main(int argc, char **argv)
{ {
...@@ -1461,6 +1517,7 @@ int main(int argc, char **argv) ...@@ -1461,6 +1517,7 @@ int main(int argc, char **argv)
Usage(); Usage();
while (**argv) while (**argv)
switch (*(*argv)++) { switch (*(*argv)++) {
case 'a': op_flags |= OPT_a; break;
case 'c': op_flags |= OPT_c; break; case 'c': op_flags |= OPT_c; break;
case 'D': op_flags |= OPT_D; break; case 'D': op_flags |= OPT_D; break;
case 'd': op_flags |= OPT_d; break; case 'd': op_flags |= OPT_d; break;
...@@ -1504,6 +1561,16 @@ int main(int argc, char **argv) ...@@ -1504,6 +1561,16 @@ int main(int argc, char **argv)
if (!resizecc(dir, newmbs)) { if (!resizecc(dir, newmbs)) {
exit(1); exit(1);
} }
} else if (op_flags & OPT_a) {
if (argc < 1) {
Usage();
}
while (argc) {
if (!appendcc(dir, *argv++)) {
return 1;
}
argc--;
}
} else if (op_flags & OPT_p) { } else if (op_flags & OPT_p) {
if (argc < 1) if (argc < 1)
Usage(); Usage();
......
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment