From c262a7255b723f1faecb9da80ddc432546fa824e Mon Sep 17 00:00:00 2001 From: Michiel Broek Date: Thu, 6 May 2004 17:38:19 +0000 Subject: [PATCH] mbfile completed for testing new fdb code --- ChangeLog | 2 + lib/dbfdb.c | 157 ++++++++++++++++++++++++++++++++++++++++++++++- mbfido/mbfsort.c | 28 +++++++-- 3 files changed, 180 insertions(+), 7 deletions(-) diff --git a/ChangeLog b/ChangeLog index 75a5e348..f36d7c64 100644 --- a/ChangeLog +++ b/ChangeLog @@ -47,6 +47,8 @@ v0.51.4 11-Apr-2004 corrupt. Mbfile check will now accept an area number to just check one single area. + Added new experimental files database code which will only be + used if configured with --enable-experiment. mbnntp: New program, news server to read echomail with a news client. diff --git a/lib/dbfdb.c b/lib/dbfdb.c index 668627fb..f524cc2b 100644 --- a/lib/dbfdb.c +++ b/lib/dbfdb.c @@ -418,11 +418,166 @@ int mbsedb_PackFDB(struct _fdbarea *fdb_area) } +typedef struct _fdbs { + struct _fdbs *next; + struct FILE_record filrec; +} fdbs; -int mbsedb_SortFDB(struct _fdbarea *fdb_area) + + +void fill_fdbs(struct FILE_record, fdbs **); +void fill_fdbs(struct FILE_record filrec, fdbs **fap) { + fdbs *tmp; + + tmp = (fdbs *)malloc(sizeof(fdbs)); + tmp->next = *fap; + tmp->filrec = filrec; + *fap = tmp; } +void tidy_fdbs(fdbs **); +void tidy_fdbs(fdbs **fap) +{ + fdbs *tmp, *old; + + for (tmp = *fap; tmp; tmp = old) { + old = tmp->next; + free(tmp); + } + *fap = NULL; +} + + +int comp_fdbs(fdbs **, fdbs **); + + +void sort_fdbs(fdbs **); +void sort_fdbs(fdbs **fap) +{ + fdbs *ta, **vector; + size_t n = 0, i; + + if (*fap == NULL) + return; + + for (ta = *fap; ta; ta = ta->next) + n++; + + vector = (fdbs **)malloc(n * sizeof(fdbs *)); + i = 0; + for (ta = *fap; ta; ta = ta->next) + vector[i++] = ta; + + qsort(vector, n, sizeof(fdbs *), (int(*)(const void*, const void *))comp_fdbs); + (*fap) = vector[0]; + i = 1; + + for (ta = *fap; ta; ta = ta->next) { + if (i < n) + ta->next = vector[i++]; + else + ta->next = NULL; + } + + free(vector); + return; +} + + + +int comp_fdbs(fdbs **fap1, fdbs **fap2) +{ + return strcasecmp((*fap1)->filrec.LName, (*fap2)->filrec.LName); +} + + + +/* + * Sort a files database using the long filenames. + */ +int mbsedb_SortFDB(struct _fdbarea *fdb_area) +{ + fdbs *fdx = NULL, *tmp; + char *temp, *temp2; + FILE *fp; + int count = 0, rc; + + Syslog('f', "SortFDB %ld", fdb_area->area); + + fseek(fdb_area->fp, 0, SEEK_END); + if (ftell(fdb_area->fp) <= (fdbhdr.hdrsize + fdbhdr.recsize)) { + Syslog('f', "0 or 1 records, nothing to sort"); + return 0; + } + + fseek(fdb_area->fp, fdbhdr.hdrsize, SEEK_SET); + + while (fread(&fdb, fdbhdr.recsize, 1, fdb_area->fp) == 1) { + fill_fdbs(fdb, &fdx); + Syslog('f', "Adding %s", fdb.LName); + } + + sort_fdbs(&fdx); + + /* + * Now the most timeconsuming part is done, lock the database and + * write the new sorted version. + */ + if (mbsedb_LockFDB(fdb_area, 30) == FALSE) { + tidy_fdbs(&fdx); + return -1; + } + + temp = calloc(PATH_MAX, sizeof(char)); + sprintf(temp, "%s/fdb/file%ld.temp", getenv("MBSE_ROOT"), fdb_area->area); + if ((fp = fopen(temp, "a+")) == NULL) { + WriteError("$Can't create %s", temp); + mbsedb_UnlockFDB(fdb_area); + tidy_fdbs(&fdx); + free(temp); + return -1; + } + fwrite(&fdbhdr, fdbhdr.hdrsize, 1, fp); + + /* + * Write sorted files to temp database + */ + for (tmp = fdx; tmp; tmp = tmp->next) { + Syslog('f', "Sorted %s", tmp->filrec.LName); + fwrite(&tmp->filrec, fdbhdr.recsize, 1, fp); + count++; + } + tidy_fdbs(&fdx); + + /* + * Now the trick, some might be waiting for a lock on the original file, + * we will give that a new name on disk. Then we move the temp in place. + * Finaly remove the old (still locked) original file. + */ + temp2 = calloc(PATH_MAX, sizeof(char)); + sprintf(temp2, "%s/fdb/file%ld.data", getenv("MBSE_ROOT"), fdb_area->area); + sprintf(temp, "%s/fdb/file%ld.xxxx", getenv("MBSE_ROOT"), fdb_area->area); + rc = rename(temp2, temp); + Syslog('f', "rename %s %s rc=%d", temp2, temp, rc); + sprintf(temp, "%s/fdb/file%ld.temp", getenv("MBSE_ROOT"), fdb_area->area); + rc = rename(temp, temp2); + Syslog('f', "rename %s %s rc=%d", temp, temp2, rc); + sprintf(temp, "%s/fdb/file%ld.xxxx", getenv("MBSE_ROOT"), fdb_area->area); + rc = unlink(temp); + Syslog('f', "unlink %s rc=%d", temp, rc); + + fdb_area->fp = fp; + fdb_area->locked = 0; + + free(temp); + free(temp2); + + Syslog('f', "success, sorted %d", count); + return count; +} + + #endif diff --git a/mbfido/mbfsort.c b/mbfido/mbfsort.c index 801dc424..71e90004 100644 --- a/mbfido/mbfsort.c +++ b/mbfido/mbfsort.c @@ -40,6 +40,7 @@ extern int do_quiet; /* Suppress screen output */ extern int do_index; /* Reindex filebases */ +#ifndef USE_EXPERIMENT typedef struct _fdbs { struct _fdbs *next; @@ -116,6 +117,7 @@ int comp_fdbs(fdbs **fap1, fdbs **fap2) return strcasecmp((*fap1)->filrec.LName, (*fap2)->filrec.LName); } +#endif /* @@ -123,14 +125,20 @@ int comp_fdbs(fdbs **fap1, fdbs **fap2) */ void SortFileBase(int Area) { - FILE *fp, *pAreas, *pFile; - int iAreas, iTotal = 0; - char *sAreas, *fAreas, *fTmp; + FILE *pAreas; + int iAreas; + char *sAreas; +#ifdef USE_EXPERIMENT + struct _fdbarea *fdb_area = NULL; +#else + FILE *fp, *pFile; + char *fAreas, *fTmp; fdbs *fdx = NULL, *tmp; - sAreas = calloc(PATH_MAX, sizeof(char)); fAreas = calloc(PATH_MAX, sizeof(char)); fTmp = calloc(PATH_MAX, sizeof(char)); +#endif + sAreas = calloc(PATH_MAX, sizeof(char)); IsDoing("Sort filebase"); if (!do_quiet) { @@ -166,6 +174,12 @@ void SortFileBase(int Area) fflush(stdout); } +#ifdef USE_EXPERIMENT + if ((fdb_area = mbsedb_OpenFDB(Area, 30))) { + mbsedb_SortFDB(fdb_area); + mbsedb_CloseFDB(fdb_area); + } +#else sprintf(fAreas, "%s/fdb/file%d.data", getenv("MBSE_ROOT"), Area); sprintf(fTmp, "%s/fdb/file%d.temp", getenv("MBSE_ROOT"), Area); @@ -192,7 +206,6 @@ void SortFileBase(int Area) * Fill the sort array */ while (fread(&fdb, fdbhdr.recsize, 1, pFile) == 1) { - iTotal++; fill_fdbs(fdb, &fdx); Syslog('f', "Adding %s", fdb.LName); } @@ -215,6 +228,7 @@ void SortFileBase(int Area) unlink(fTmp); chmod(fAreas, 00660); } +#endif Syslog('+', "Sorted file area %d: %s", Area, area.Name); do_index = TRUE; @@ -230,9 +244,11 @@ void SortFileBase(int Area) fflush(stdout); } +#ifndef USE_EXPERIMENT free(fTmp); - free(sAreas); free(fAreas); +#endif + free(sAreas); }