RPM Package Manager, CVS Repository http://rpm5.org/cvs/ ____________________________________________________________________________
Server: rpm5.org Name: Jeff Johnson Root: /v/rpm/cvs Email: j...@rpm5.org Module: rpm Date: 07-Nov-2009 19:05:16 Branch: HEAD Handle: 2009110718051401 Modified files: rpm CHANGES rpm/rpmdb rpmdb.c Log: - rpmdb: eliminate the custom Basenames retrieval code. Summary: Revision Changes Path 1.3145 +1 -0 rpm/CHANGES 1.329 +9 -279 rpm/rpmdb/rpmdb.c ____________________________________________________________________________ patch -p0 <<'@@ .' Index: rpm/CHANGES ============================================================================ $ cvs diff -u -r1.3144 -r1.3145 CHANGES --- rpm/CHANGES 7 Nov 2009 16:07:05 -0000 1.3144 +++ rpm/CHANGES 7 Nov 2009 18:05:14 -0000 1.3145 @@ -1,5 +1,6 @@ 5.2b1 -> 5.3a1 + - jbj: rpmdb: eliminate the custom Basenames retrieval code. - jbj: rpmdb: eliminate the Basenames index. - jbj: rpmdb: abandon RPMTAG_BASENAMES lookup, use RPMTAG_FILEPATHS instead. - jbj: rpmts: stub-in a grandparent transaction. @@ . patch -p0 <<'@@ .' Index: rpm/rpmdb/rpmdb.c ============================================================================ $ cvs diff -u -r1.328 -r1.329 rpmdb.c --- rpm/rpmdb/rpmdb.c 7 Nov 2009 16:02:34 -0000 1.328 +++ rpm/rpmdb/rpmdb.c 7 Nov 2009 18:05:15 -0000 1.329 @@ -67,17 +67,6 @@ /*...@unchecked@*/ static int _rebuildinprogress = 0; -/* Use a path uniqifier in the upper 16 bits of tagNum? */ -/* XXX Note: one cannot just choose a value, rpmdb tagNum's need fixing too */ -#define _DB_TAGGED_FILE_INDICES 1 -/*...@unchecked@*/ -static int _db_tagged_file_indices = _DB_TAGGED_FILE_INDICES; - -/* Use a path uniqifier while doing -qf? */ -#define _DB_TAGGED_FINDBYFILE 1 -/*...@unchecked@*/ -static int _db_tagged_findbyfile = _DB_TAGGED_FINDBYFILE; - #define _DBI_FLAGS 0 #define _DBI_PERMS 0644 #define _DBI_MAJOR -1 @@ -124,23 +113,6 @@ return val; } -#ifdef DYING -/** - * Check key for printable characters. - * @param ptr key value pointer - * @param len key value length - * @return 1 if only ASCII, 0 otherwise. - */ -static int printable(const void * ptr, size_t len) /*...@*/ -{ - const char * s = ptr; - int i; - for (i = 0; i < len; i++, s++) - if (!(*s >= ' ' && *s <= '~')) return 0; - return 1; -} -#endif - /** * Return dbi index used for rpm tag. * @param db rpm database @@ -1447,241 +1419,6 @@ return rc; } -/** - * Return a tagnum with hash on the (directory) path in upper 16 bits. - * @param s (directory) path - * @return tagnum with (directory) path hash - */ -static inline unsigned taghash(const char * s) - /*...@*/ -{ - unsigned int r = 0; - int c; - while ((c = (int) *s++) != 0) { - /* XXX Excluding the '/' character may cause hash collisions. */ - if (c != (int) '/') - r += (r << 3) + c; - } - return ((r & 0x7fff) | 0x8000) << 16; -} - -/** - * Return the intersection of dirName <=> baseName index sets. - * @param tag dirName hash tag. - * @param dnset dirName's set. - * @baram bnset baseName's set. - * @retval *matches intersection of dnset and bnset (NULL if disjoint). - * @return no. of matches - */ -static int dbiIntersect(unsigned int tag, dbiIndexSet dnset, dbiIndexSet bnset, - dbiIndexSet *matches) - /*...@modifies *matches @*/ -{ - dbiIndexItem drec = dnset->recs; - dbiIndexItem brec = bnset->recs; - dbiIndexItem rec = alloca(sizeof(*rec)); - int i = 0; - int j = 0; - int xx; - - *matches = NULL; - while (i < dnset->count) { - while (j < bnset->count && brec->hdrNum <= drec->hdrNum) { - if (brec->hdrNum == drec->hdrNum - && tag == (brec->tagNum & 0xffff0000)) - break; - brec++; - j++; - } - if (j >= bnset->count) - break; - if (brec->hdrNum == drec->hdrNum - && tag == (brec->tagNum & 0xffff0000)) - { - *rec = *brec; /* structure assignment */ - rec->tagNum &= 0x0000ffff; - if (*matches == NULL) - *matches = xcalloc(1, sizeof(**matches)); - xx = dbiAppendSet(*matches, rec, 1, sizeof(*rec), 0); - brec++; - j++; - } - drec++; - i++; - } - return (*matches ? (*matches)->count : 0); -} - -/** - * Find file matches in database. - * @param db rpm database - * @param filespec - * @param keylen - * @param matches - * @return 0 on success, 1 on not found, -2 on error - */ -static int rpmdbFindByFile(rpmdb db, /*...@null@*/ const char * filespec, size_t keylen, - /*...@out@*/ dbiIndexSet * matches) - /*...@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState @*/ - /*...@modifies db, *matches, rpmGlobalMacroContext, - fileSystem, internalState @*/ - /*...@requires maxSet(matches) >= 0 @*/ -{ - const char * dirName; - const char * baseName; - dbiIndex dbi; - dbiIndexSet bnset = NULL; - int bingo; - int rc; - int xx; - int i; - - *matches = NULL; - if (filespec == NULL) return -2; - - if ((baseName = strrchr(filespec, '/')) != NULL) { - size_t len = baseName - filespec + 1; - char * t = strncpy(alloca(len + 1), filespec, len); - t[len] = '\0'; - dirName = t; - baseName++; - } else { - dirName = ""; - baseName = filespec; - } -assert(*dirName != '\0'); -assert(baseName != NULL); - - /* Load the basenames index set. */ - if ((dbi = dbiOpen(db, RPMTAG_BASENAMES, 0)) == NULL) - return -2; - - rc = _joinKeys(dbi, baseName, strlen(baseName), &bnset); - if ((rc && rc != DB_NOTFOUND) || bnset == NULL || bnset->count < 1) - return rc; -assert(bnset != NULL); -assert(bnset->count > 0); - - /* Check that all basenames are dir tagged. */ - if (_db_tagged_file_indices) { - bingo = 1; - for (i = 0; i < bnset->count; i++) { - if (bnset->recs[i].tagNum & 0x80000000) - continue; - bingo = 0; - break; - } - } else - bingo = 0; - - /* Plan A: Attempt dirName <-> baseName intersection using index keys. */ - if (bingo && (dbi = dbiOpen(db, RPMTAG_DIRNAMES, 0)) != NULL) { - dbiIndexSet dnset = NULL; - - rc = _joinKeys(dbi, dirName, strlen(dirName), &dnset); - - /* If dnset is non-empty, then attempt Plan A intersection. */ - if (rc == 0 && dnset && dnset->count > 0) { - unsigned int tag = taghash(dirName); - xx = dbiIntersect(tag, dnset, bnset, matches); - bnset = dbiFreeIndexSet(bnset); - dnset = dbiFreeIndexSet(dnset); - return (*matches != NULL ? 0 : 1); - } - dnset = dbiFreeIndexSet(dnset); - } - - /* Plan B: Reduce the size of the index set before loading headers. */ - if (_db_tagged_file_indices) { - if (_db_tagged_findbyfile && bnset->count > 1 && *dirName != '\0') { - unsigned int tag = taghash(dirName); - int j = 0; - - /* Prune the bnset using the directory tag. */ - for (i = 0; i < bnset->count; i++) { - if (bnset->recs[i].tagNum & 0x80000000) { - unsigned int ctag = (bnset->recs[i].tagNum & 0xffff0000); - bnset->recs[i].tagNum &= 0x0000ffff; - if (ctag != tag) - continue; - } - if (i > j) - bnset->recs[j] = bnset->recs[i]; /* structure assignment */ - j++; - } - /* If bnset was shortened by dir tagging, reset the count. */ - if (j > 0 && j < bnset->count) - bnset->count = j; - } else { - /* Strip off directory tags. */ - for (i = 0; i < bnset->count; i++) { - if (bnset->recs[i].tagNum & 0x80000000) - bnset->recs[i].tagNum &= 0x0000ffff; - } - } - } - - /* OK, find the file using fingerprints and loading headers. */ - { HE_t BN = memset(alloca(sizeof(*BN)), 0, sizeof(*BN)); - HE_t DN = memset(alloca(sizeof(*DN)), 0, sizeof(*DN)); - HE_t DI = memset(alloca(sizeof(*DI)), 0, sizeof(*DI)); - fingerPrintCache fpc = fpCacheCreate(20); - fingerPrint fp1 = fpLookup(fpc, dirName, baseName, 1); - rpmmi mi = NULL; - unsigned int prevoff = 0; - Header h; - - /* Create an iterator for the matches. */ - mi = rpmmiInit(db, RPMDBI_PACKAGES, NULL, 0); - mi->mi_set = bnset; - - prevoff = 0; - BN->tag = RPMTAG_BASENAMES; - DN->tag = RPMTAG_DIRNAMES; - DI->tag = RPMTAG_DIRINDEXES; - - /* Find the file(s) with the same fingerprint. */ - while ((h = rpmmiNext(mi)) != NULL) { - fingerPrint fp2; - int num; - - /* Reload tags when header changes. */ - if (prevoff != rpmmiInstance(mi)) { - prevoff = rpmmiInstance(mi); - BN->p.ptr = _free(BN->p.ptr); - xx = headerGet(h, BN, 0); - DN->p.ptr = _free(DN->p.ptr); - xx = headerGet(h, DN, 0); - DI->p.ptr = _free(DI->p.ptr); - xx = headerGet(h, DI, 0); - } - - num = dbiIndexRecordFileNumber(mi->mi_set, mi->mi_setx-1); -assert(num >= 0 && num < (int)BN->c); - fp2 = fpLookup(fpc, DN->p.argv[DI->p.ui32p[num]], BN->p.argv[num], 1); - - /*...@-nullpass@*/ - if (FP_EQUAL(fp1, fp2)) - /*...@=nullpass@*/ - { - dbiIndexItem rec = &mi->mi_set->recs[mi->mi_setx-1]; - if (*matches == NULL) - *matches = xcalloc(1, sizeof(**matches)); - xx = dbiAppendSet(*matches, rec, 1, sizeof(*rec), 0); - } - } - - BN->p.ptr = _free(BN->p.ptr); - DN->p.ptr = _free(DN->p.ptr); - DI->p.ptr = _free(DI->p.ptr); - mi = rpmmiFree(mi); - - fpc = fpCacheFree(fpc); - } - - return (*matches != NULL ? 0 : 1); -} - int rpmdbCount(rpmdb db, rpmTag tag, const void * keyp, size_t keylen) { DBC * dbcursor = NULL; @@ -2157,10 +1894,15 @@ size_t nb; int c; + /* XXX HACK to remove the existing complexity of RPMTAG_BASENAMES */ + if (tag == RPMTAG_BASENAMES) tag = RPMTAG_FILEPATHS; + switch (*modep) { default: case RPMMIRE_DEFAULT: - if (tag == RPMTAG_DIRNAMES || tag == RPMTAG_BASENAMES) { + if (tag == RPMTAG_DIRNAMES || tag == RPMTAG_BASENAMES + || tag == RPMTAG_FILEPATHS) + { *modep = RPMMIRE_GLOB; pat = xstrdup(pattern); break; @@ -2803,12 +2545,6 @@ for (i = j = 0; i < set->count; i++) { if (exclude && set->recs[i].hdrNum == exclude) continue; - if (_db_tagged_file_indices && set->recs[i].tagNum & 0x80000000) { - /* tagged entry */ - if ((set->recs[i].tagNum & 0xffff0000) != tag) - continue; - set->recs[i].tagNum &= 0x0000ffff; - } if (i > j) set->recs[j] = set->recs[i]; j++; @@ -2939,8 +2675,6 @@ if (isLabel) { rc = dbiFindByLabel(dbi, keyp, keylen, &set); - } else if (tag == RPMTAG_BASENAMES) { - rc = rpmdbFindByFile(db, keyp, keylen, &set); } else { rc = _joinKeys(dbi, keyp, keylen, &set); } @@ -3631,11 +3365,6 @@ */ rec->tagNum = i; switch (dbi->dbi_rpmtag) { - case RPMTAG_BASENAMES: - /* tag index entry with directory hash */ - if (_db_tagged_file_indices && i < 0x010000) - rec->tagNum |= taghash(dirNames[dirIndexes[i]]); - /*...@switchbreak@*/ break; case RPMTAG_PUBKEYS: /*...@switchbreak@*/ break; case RPMTAG_FILEDIGESTS: @@ -3651,6 +3380,7 @@ /*...@switchbreak@*/ break; case RPMTAG_DIRNAMES: case RPMTAG_TRIGGERNAME: + /* Uniqify dirnames and triggers. */ if (i > 0 && !strcmp(he->p.argv[i], he->p.argv[i-1])) /*...@innercontinue@*/ continue; /*...@switchbreak@*/ break; @@ -3853,8 +3583,8 @@ key->size = (UINT32_T) strlen((char *)key->data); if (key->size == 0) key->size++; /* XXX "/" fixup. */ - tag = (_db_tagged_file_indices ? taghash(fpList[i].entry->dirName) : 0); - xx = rpmdbGrowIterator(mi, i, exclude, tag); + /* XXX TODO: eliminate useless exclude/tag arguments. */ + xx = rpmdbGrowIterator(mi, i, exclude, 0); } @@ . ______________________________________________________________________ RPM Package Manager http://rpm5.org CVS Sources Repository rpm-cvs@rpm5.org