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:   22-Nov-2009 15:33:04
  Branch: HEAD                             Handle: 2009112214330301

  Modified files:
    rpm                     CHANGES
    rpm/rpmdb               rpmdb.c

  Log:
    - rpmdb: don't recurse within dbiFindByLabel.
    - rpmdb: use PCRE patterns on Name index for package queries.

  Summary:
    Revision    Changes     Path
    1.3165      +2  -0      rpm/CHANGES
    1.343       +150 -160   rpm/rpmdb/rpmdb.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/CHANGES
  ============================================================================
  $ cvs diff -u -r1.3164 -r1.3165 CHANGES
  --- rpm/CHANGES       20 Nov 2009 13:46:15 -0000      1.3164
  +++ rpm/CHANGES       22 Nov 2009 14:33:03 -0000      1.3165
  @@ -1,5 +1,7 @@
   
   5.2b1 -> 5.3a1
  +    - jbj: rpmdb: don't recurse within dbiFindByLabel.
  +    - jbj: rpmdb: use PCRE patterns on Name index for package queries.
       - devzero2000: don't permit using b0rken configure option
       - jbj: rpmdb: fix: ensure Seqno h# counter is initialized to 1 when 
created.
       - proyvind: add %distepoch back to provideversion, leave legacy
  @@ .
  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/rpmdb.c
  ============================================================================
  $ cvs diff -u -r1.342 -r1.343 rpmdb.c
  --- rpm/rpmdb/rpmdb.c 17 Nov 2009 00:19:30 -0000      1.342
  +++ rpm/rpmdb/rpmdb.c 22 Nov 2009 14:33:04 -0000      1.343
  @@ -64,6 +64,8 @@
   /*...@unchecked@*/
   int _rpmdb_debug = 0;
   
  +static int _jbj_debug = 0;
  +
   /*...@unchecked@*/
   static int _rebuildinprogress = 0;
   
  @@ -1236,11 +1238,59 @@
       return ret;
   }
   
  +static void prtDBT(const char * msg, DBT * kp)
  +{
  +    if (msg) fprintf(stderr, "\t%s", msg);
  +    fprintf(stderr, " %p[%u:%u:%u] flags 0x%x\n",
  +     kp->data, (unsigned)kp->size, (unsigned)kp->doff, (unsigned)kp->dlen,
  +     kp->flags);
  +}
  +
  +#ifdef       NOTYET
  +/* Determine if the regular expression specification has any meta 
characters. */
  +static const char * stemEnd(const char * s)
  +     /*...@modifies sxp @*/
  +{
  +    int c;
  +
  +    /* Return pointer to first RE character (or NUL terminator) */
  +    while ((c = *s)) {
  +     switch (c) {
  +     case '.':
  +     case '^':
  +     case '$':
  +     case '?':
  +     case '*':
  +     case '+':
  +     case '|':
  +     case '[':
  +     case '(':
  +     case '{':
  +     case '\0':
  +         goto exit;
  +         /*...@notreached@*/ /*...@switchbreak@*/ break;
  +     case '\\':
  +         s++;
  +         if (*s == '\0') goto exit;
  +         /*...@fallthrough@*/
  +     default:
  +         /*...@switchbreak@*/ break;
  +     }
  +     s++;
  +    }
  +exit:
  +    return s;
  +}
  +#endif
  +
   static int rpmdbMireKeys(rpmdb db, rpmTag tag, rpmMireMode mode,
                const char * pat, dbiIndexSet * matches)
   {
       DBC * dbcursor = NULL;
       DBT k = DBT_INIT;
  +#ifdef       NOTYET
  +    DBT fk;
  +#endif
       DBT p = DBT_INIT;
       DBT v = DBT_INIT;
       dbiIndex dbi;
  @@ -1256,51 +1306,91 @@
        goto exit;
   
       if (pat) {
  -     mire = mireNew(mode, 0);
  -     xx = mireRegcomp(mire, pat);
  +     const char * b = pat;
  +#ifdef       NOTYET
  +     const char * be;
  +#endif
  +
  +        mire = mireNew(mode, 0);
  +        xx = mireRegcomp(mire, pat);
   
  -     /* Use the pattern stem to (partially) match on lookup. */
  -     /* XXX TODO: extend to other patterns. */
        switch (mode) {
        default:
            break;
  +     case RPMMIRE_PCRE:
  +#ifdef       NOTYET
  +         if (*b == '^') k.doff = 1;
  +         be = stemEnd(b + k.doff);
  +         /* If partial match on stem won't help, just iterate. */
  +         if (be == (b + k.doff)) {
  +             k.doff = 0;
  +             goto doit;
  +         }
  +         /* Set stem length for partial match retrieve. */
  +         k.dlen = (be - b) - k.doff;
  +         k.flags = DB_DBT_PARTIAL;
  +         k.data = (void *) b;
  +         _flags = DB_SET;
  +#else
  +         goto doit;
  +#endif
  +         break;
        case RPMMIRE_STRCMP:
  -         k.data = (void *) pat;
  -         k.size = (UINT32_T) strlen(pat);
  +         k.size = (UINT32_T) strlen(b);
  +         k.data = (void *) b;
            _flags = DB_SET;
            break;
        }
  +if (_jbj_debug) prtDBT("k", &k);
       }
   
  +doit:
       xx = dbiCopen(dbi, dbiTxnid(dbi), &dbcursor, 0);
   
       /* Iterate over all keys, collecting primary keys. */
       while ((rc = dbiPget(dbi, dbcursor, &k, &p, &v, _flags)) == 0) {
  -     size_t ns = k.size;
  -     /* XXX TODO: strdup malloc is necessary solely for argvAdd() */
  -     char * s = memcpy(xmalloc(ns+1), k.data, ns);
  -
  -     s[ns] = '\0';
  -     if (mire == NULL || mireRegexec(mire, s, ns) >= 0) {
  -         union _dbswap mi_offset;
  -         unsigned i;
  +     union _dbswap mi_offset;
  +unsigned ix;
   
  -         /* Get a native endian copy of the primary package key. */
  -         memcpy(&mi_offset, p.data, sizeof(mi_offset.ui));
  -         if (_endian.uc[0] == 0x44)
  -             _DBSWAP(mi_offset);
  +     if (_flags == DB_SET) _flags = DB_NEXT_DUP;
   
  -         /* Append primary package key to set. */
  -         if (set == NULL)
  -             set = xcalloc(1, sizeof(*set));
  -         i = set->count;
  -         /* XXX TODO: sort/uniqify set? */
  -         (void) dbiAppendSet(set, &mi_offset.ui, 1, sizeof(mi_offset.ui), 0);
  +if (_jbj_debug) prtDBT("k", &k);
  +if (_jbj_debug) prtDBT("p", &p);
  +if (_jbj_debug) prtDBT("v", &v);
  +
  +     if (mire) {
  +         const char * s;
  +         size_t ns;
  +
  +#ifdef       NOTYET
  +         /* Retrieve the full match key. */
  +         memset (&fk, 0, sizeof(fk));
  +         xx = dbiPget(dbi, dbcursor, &fk, &p, &v, DB_CURRENT);
  +         s = (const char * ) fk.data;
  +         ns = fk.size;
  +#else
  +         s = (const char * ) k.data;
  +         ns = k.size;
  +#endif
   
  +         /* Skip if not matched. */
  +         if (mireRegexec(mire, s, ns) < 0)
  +             continue;
        }
  -     s = _free(s);
  +         
  +     /* Get a native endian copy of the primary package key. */
  +     memcpy(&mi_offset, p.data, sizeof(mi_offset.ui));
  +     if (_endian.uc[0] == 0x44)
  +         _DBSWAP(mi_offset);
   
  -     if (_flags == DB_SET) _flags = DB_NEXT_DUP;
  +     /* Append primary package key to set. */
  +     if (set == NULL)
  +         set = xcalloc(1, sizeof(*set));
  +ix = set->count;
  +     /* XXX TODO: sort/uniqify set? */
  +     (void) dbiAppendSet(set, &mi_offset.ui, 1, sizeof(mi_offset.ui), 0);
  +if (_jbj_debug)
  +fprintf(stderr, "\tset[%u] = %u\n", ix, dbiIndexRecordOffset(set, ix));
       }
   
       xx = dbiCclose(dbi, dbcursor, 0);
  @@ -1318,6 +1408,8 @@
       }
   
   exit:
  +if (_jbj_debug)
  +fprintf(stderr, "<-- %s(%p, %s(%u), %d, \"%s\", %p) rc %d set %p[%u]\n", 
__FUNCTION__, db, tagName(tag), (unsigned)tag, mode, pat, matches, ret, (set ? 
set->recs : NULL), (set ? set->count : 0));
       if (ret == 0 && matches) {
        /* XXX TODO: sort/uniqify set? */
        *matches = set;
  @@ -1334,87 +1426,60 @@
    * @param dbcursor   index database cursor
    * @param key                search key/length/flags
    * @param data               search data/length/flags
  - * @param name               package name
  - * @param version    package version (can be a pattern)
  - * @param release    package release (can be a pattern)
  + * @param N          package name
  + * @param V          package version (can be a pattern)
  + * @param R          package release (can be a pattern)
    * @retval matches   set of header instances that match
    * @return           RPMRC_OK on match, RPMRC_NOMATCH or RPMRC_FAIL
    */
   static rpmRC dbiFindMatches(dbiIndex dbi, DBC * dbcursor,
                DBT * key, DBT * data,
  -             const char * name,
  -             /*...@null@*/ const char * version,
  -             /*...@null@*/ const char * release,
  +             const char * N,
  +             /*...@null@*/ const char * V,
  +             /*...@null@*/ const char * R,
                /*...@out@*/ dbiIndexSet * matches)
        /*...@globals rpmGlobalMacroContext, h_errno, fileSystem, internalState 
@*/
        /*...@modifies dbi, *dbcursor, *key, *data, *matches,
                rpmGlobalMacroContext, fileSystem, internalState @*/
        /*...@requires maxSet(matches) >= 0 @*/
   {
  -    int gotMatches = 0;
  -    int rc;
  -    unsigned i;
  +    rpmRC rc = RPMRC_FAIL;
  +    int ret;
   
  -    rc = rpmdbMireKeys(dbi->dbi_rpmdb, RPMTAG_NAME, RPMMIRE_STRCMP, name, 
matches);
  -    switch (rc) {
  +    {        rpmMireMode _mode = RPMMIRE_PCRE;
  +#ifdef       NOTYET
  +     rpmTag _tag = RPMTAG_NVRA;
  +#else
  +     rpmTag _tag = RPMTAG_NAME;
  +#endif
  +     /* XXX add ^...$ *RE anchors. */
  +     const char * _pat = N;
  +     ret = rpmdbMireKeys(dbi->dbi_rpmdb, _tag, _mode, _pat, matches);
  +    }
  +
  +    switch (ret) {
       case 0:
  -     if (version == NULL && release == NULL)
  -         return RPMRC_OK;
  +     if (V == NULL && R == NULL) {
  +         rc = RPMRC_OK;
  +         goto exit;
  +     }
        break;
       case DB_NOTFOUND:
  -     return RPMRC_NOTFOUND;
  +     rc = RPMRC_NOTFOUND;
  +     goto exit;
        /*...@notreached@*/ break;
       default:
  -     rpmlog(RPMLOG_ERR,
  -             _("error(%d) getting records from %s index\n"),
  -             rc, tagName(dbi->dbi_rpmtag));
  -     return RPMRC_FAIL;
  +     rpmlog(RPMLOG_ERR, _("error(%d) getting records from %s index\n"),
  +             ret, tagName(dbi->dbi_rpmtag));
  +     goto exit;
        /*...@notreached@*/ break;
       }
   
  -    /* Make sure the version and release match. */
  -    for (i = 0; i < dbiIndexSetCount(*matches); i++) {
  -     unsigned int recoff = dbiIndexRecordOffset(*matches, i);
  -     rpmmi mi;
  -     Header h;
  -
  -     if (recoff == 0)
  -         continue;
  -
  -     mi = rpmmiInit(dbi->dbi_rpmdb,
  -                     RPMDBI_PACKAGES, &recoff, sizeof(recoff));
  -
  -     /* Set iterator selectors for version/release if available. */
  -     if (version &&
  -         rpmmiAddPattern(mi, RPMTAG_VERSION, RPMMIRE_DEFAULT, version))
  -     {
  -         rc = RPMRC_FAIL;
  -         goto exit;
  -     }
  -     if (release &&
  -         rpmmiAddPattern(mi, RPMTAG_RELEASE, RPMMIRE_DEFAULT, release))
  -     {
  -         rc = RPMRC_FAIL;
  -         goto exit;
  -     }
  -
  -     h = rpmmiNext(mi);
  -     if (h)
  -         (*matches)->recs[gotMatches++] = (*matches)->recs[i];
  -     else
  -         (*matches)->recs[i].hdrNum = 0;
  -     mi = rpmmiFree(mi);
  -    }
  -
  -    if (gotMatches) {
  -     (*matches)->count = gotMatches;
  -     rc = RPMRC_OK;
  -    } else
  -     rc = RPMRC_NOTFOUND;
  -
   exit:
  +if (_jbj_debug)
  +fprintf(stderr, "<-- %s(%p, %p, %p, %p, \"%s\", \"%s\", \"%s\", %p) rc %d 
set %p[%u]\n", __FUNCTION__, dbi, dbcursor, key, data, N, V, R, matches, rc, 
(*matches ? (*matches)->recs : NULL), (*matches ? (*matches)->count : 0));
   /*...@-unqualifiedtrans@*/ /* FIX: double indirection */
  -    if (rc && matches && *matches)
  +    if (rc != RPMRC_OK && matches && *matches)
        *matches = dbiFreeIndexSet(*matches);
   /*...@=unqualifiedtrans@*/
       return rc;
  @@ -1440,11 +1505,6 @@
   DBC * dbcursor = NULL;
   DBT k = DBT_INIT, *key = &k;
   DBT v = DBT_INIT, *data = &v;
  -    const char * release;
  -    char * localarg;
  -    char * s;
  -    char c;
  -    int brackets;
       rpmRC rc;
       int xx;
   
  @@ -1452,78 +1512,8 @@
   
       xx = dbiCopen(dbi, dbiTxnid(dbi), &dbcursor, 0);
   
  -    /* did they give us just a name? */
       rc = dbiFindMatches(dbi, dbcursor, key, data, arg, NULL, NULL, matches);
  -    if (rc != RPMRC_NOTFOUND)
  -     goto exit;
  -
  -    /*...@-unqualifiedtrans@*/ /* FIX: double indirection */
  -    *matches = dbiFreeIndexSet(*matches);
  -    /*...@=unqualifiedtrans@*/
  -
  -    /* maybe a name and a release */
  -    localarg = alloca(strlen(arg) + 1);
  -    s = stpcpy(localarg, arg);
  -
  -    c = '\0';
  -    brackets = 0;
  -    for (s -= 1; s > localarg; s--) {
  -     switch (*s) {
  -     case '[':
  -         brackets = 1;
  -         /*...@switchbreak@*/ break;
  -     case ']':
  -         if (c != '[') brackets = 0;
  -         /*...@switchbreak@*/ break;
  -     }
  -     c = *s;
  -     if (!brackets && *s == '-')
  -         break;
  -    }
  -
  -    if (s == localarg) {
  -     rc = RPMRC_NOTFOUND;
  -     goto exit;
  -    }
  -
  -    *s = '\0';
  -    rc = dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, NULL, 
matches);
  -    if (rc != RPMRC_NOTFOUND)
  -     goto exit;
  -
  -    /*...@-unqualifiedtrans@*/ /* FIX: double indirection */
  -    *matches = dbiFreeIndexSet(*matches);
  -    /*...@=unqualifiedtrans@*/
  -    
  -    /* how about name-version-release? */
  -
  -    release = s + 1;
   
  -    c = '\0';
  -    brackets = 0;
  -    for (; s > localarg; s--) {
  -     switch (*s) {
  -     case '[':
  -         brackets = 1;
  -         /*...@switchbreak@*/ break;
  -     case ']':
  -         if (c != '[') brackets = 0;
  -         /*...@switchbreak@*/ break;
  -     }
  -     c = *s;
  -     if (!brackets && *s == '-')
  -         break;
  -    }
  -
  -    if (s == localarg) {
  -     rc = RPMRC_NOTFOUND;
  -     goto exit;
  -    }
  -
  -    *s = '\0';
  -    rc = dbiFindMatches(dbi, dbcursor, key, data, localarg, s + 1, release, 
matches);
  -
  -exit:
       xx = dbiCclose(dbi, dbcursor, 0);
       dbcursor = NULL;
   /*...@-nullstate@*/  /* FIX: *matches may be NULL. */
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to