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-Jul-2017 22:11:05
  Branch: rpm-5_4                          Handle: 2017072220110500

  Modified files:           (Branch: rpm-5_4)
    rpm/rpmdb               lmdb.c

  Log:
    - lmdb: WIP.

  Summary:
    Revision    Changes     Path
    1.1.2.3     +391 -365   rpm/rpmdb/lmdb.c
  ____________________________________________________________________________

  patch -p0 <<'@@ .'
  Index: rpm/rpmdb/lmdb.c
  ============================================================================
  $ cvs diff -u -r1.1.2.2 -r1.1.2.3 lmdb.c
  --- rpm/rpmdb/lmdb.c  22 Jul 2017 14:19:33 -0000      1.1.2.2
  +++ rpm/rpmdb/lmdb.c  22 Jul 2017 20:11:05 -0000      1.1.2.3
  @@ -55,9 +55,18 @@
   
   struct rpmdbOps_s;
   
  -/** \ingroup rpmdb
  - * Describes the collection of index databases used by rpm.
  - */
  +struct dbiIndex_s {
  +    rpmdb dbi_rpmdb;            /*!< the parent rpm database */
  +    dbiIndexType dbi_type;      /*! Type of dbi (primary / index) */
  +    const char * dbi_file;      /*!< file component of path */
  +    int dbi_flags;
  +    int dbi_byteswapped;
  +
  +    struct dbiConfig_s cfg;
  +
  +    void * dbi_db;              /*!< Backend private handle */
  +};
  +
   struct rpmdb_s {
       char     * db_root;/*!< path prefix */
       char     * db_home;/*!< directory path */
  @@ -176,6 +185,37 @@
       }
   }
   
  +/* XXX assumes hdrNum is first int in dbiIndexItem */
  +static int hdrNumCmp(const void * one, const void * two)
  +{
  +    const unsigned int * a = one, * b = two;
  +    return (*a - *b);
  +}
  +
  +int dbiIndexSetAppendSet(dbiIndexSet dest, dbiIndexSet src, int sortset)
  +{
  +    if (dest == NULL || src == NULL || src->count == 0)
  +     return 1;
  +
  +    dbiIndexSetGrow(dest, src->count);
  +    memcpy(dest->recs + dest->count,
  +        src->recs, src->count * sizeof(*src->recs));
  +    dest->count += src->count;
  +
  +    if (sortset && dest->count > 1)
  +     qsort(dest->recs, dest->count, sizeof(*(dest->recs)), hdrNumCmp);
  +    return 0;
  +}
  +
  +dbiIndexSet dbiIndexSetFree(dbiIndexSet set)
  +{
  +    if (set) {
  +     free(set->recs);
  +     free(set);
  +    }
  +    return NULL;
  +}
  +
   dbiIndexSet dbiIndexSetNew(unsigned int sizehint)
   {
       dbiIndexSet set = xcalloc(1, sizeof(*set));
  @@ -197,154 +237,7 @@
   }
   
   /*==============================================================*/
  -typedef struct rpmpkgdb_s * rpmpkgdb;
  -
  -RPM_GNUC_CONST
  -void rpmpkgClose(rpmpkgdb pkgdb)
  -{
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgOpen(rpmpkgdb *pkgdbp, const char *filename, int flags, int mode)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -static int rpmpkgGetLock(rpmpkgdb pkgdb, int type)
  -{
  -#ifdef       NOTYET
  -    if (!pkgdb->fd)
  -     return RPMRC_FAIL;
  -    for (;;) {
  -     if (flock(pkgdb->fd, type)) {
  -         return RPMRC_FAIL;
  -     }
  -     if (!is_correct_db(pkgdb)) {
  -         if (reopen_db(pkgdb)) {
  -             return RPMRC_FAIL;
  -         }
  -         continue;
  -     }
  -     break;
  -    }
  -#endif
  -    return RPMRC_OK;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgLock(rpmpkgdb pkgdb, int excl)
  -{
  -#ifdef       NOTYET
  -    unsigned int *lockcntp = excl ? &pkgdb->locked_excl : 
&pkgdb->locked_shared;
  -    if (*lockcntp > 0 || (!excl && pkgdb->locked_excl)) {
  -     (*lockcntp)++;
  -     return RPMRC_OK;
  -    }
  -    pkgdb->header_ok = 0;
  -    if (rpmpkgGetLock(pkgdb, excl ? LOCK_EX : LOCK_SH)) {
  -     return RPMRC_FAIL;
  -    }
  -    (*lockcntp)++;
  -#endif
  -    return RPMRC_OK;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgUnlock(rpmpkgdb pkgdb, int excl)
  -{
  -#ifdef       NOTYET
  -    unsigned int *lockcntp = excl ? &pkgdb->locked_excl : 
&pkgdb->locked_shared;
  -    if (*lockcntp == 0) {
  -     return RPMRC_FAIL;
  -    }
  -    if (*lockcntp > 1 || (!excl && pkgdb->locked_excl)) {
  -     (*lockcntp)--;
  -     return RPMRC_OK;
  -    }
  -    if (excl && pkgdb->locked_shared) {
  -     /* excl -> shared switch */
  -     if (rpmpkgGetLock(pkgdb, LOCK_SH)) {
  -         return RPMRC_FAIL;
  -     }
  -     (*lockcntp)--;
  -     return RPMRC_OK;
  -    }
  -    flock(pkgdb->fd, LOCK_UN);
  -    (*lockcntp)--;
  -    pkgdb->header_ok = 0;
  -#endif
  -    return RPMRC_OK;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgGet(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char **blobp, 
unsigned int *bloblp)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgPut(rpmpkgdb pkgdb, unsigned int pkgidx, unsigned char *blob, 
unsigned int blobl)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgDel(rpmpkgdb pkgdb, unsigned int pkgidx)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgList(rpmpkgdb pkgdb, unsigned int **pkgidxlistp, unsigned int 
*npkgidxlistp)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgGeneration(rpmpkgdb pkgdb, unsigned int *generationp)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmpkgNextPkgIdx(rpmpkgdb pkgdb, unsigned int *pkgidxp)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -/*==============================================================*/
  -typedef struct rpmxdb_s * rpmxdb;
  -
  -RPM_GNUC_CONST
  -void rpmxdbClose(rpmxdb xdb)
  -{
  -}
  -
  -RPM_GNUC_CONST
  -int rpmxdbOpen(rpmxdb *xdbp, rpmpkgdb pkgdb, const char *filename, int 
flags, int mode)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmxdbLookupBlob(rpmxdb xdb, unsigned int *idp, unsigned int blobtag, 
unsigned int subtag, int flags)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmxdbIsRdonly(rpmxdb xdb)
  -{
  -    return 1;
  -}
  -
  -RPM_GNUC_CONST
  -int rpmxdbSetUserGeneration(rpmxdb xdb, unsigned int usergeneration)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -/*==============================================================*/
  +#ifndef      DYING
   typedef struct rpmidxdb_s *rpmidxdb;
   
   RPM_GNUC_CONST
  @@ -353,12 +246,6 @@
   }
   
   RPM_GNUC_CONST
  -int rpmidxOpen(rpmidxdb *idxdbp, rpmpkgdb pkgdb, const char *filename, int 
flags, int mode)
  -{
  -    return RPMRC_FAIL;
  -}
  -
  -RPM_GNUC_CONST
   int rpmidxGet(rpmidxdb idxdb, const unsigned char *key, unsigned int keyl, 
unsigned int **pkgidxlistp, unsigned int *pkgidxnump)
   {
       return RPMRC_FAIL;
  @@ -382,11 +269,7 @@
       return RPMRC_FAIL;
   }
   
  -RPM_GNUC_CONST
  -int rpmidxOpenXdb(rpmidxdb *idxdbp, rpmpkgdb pkgdb, rpmxdb xdb, unsigned int 
xdbtag)
  -{
  -    return RPMRC_FAIL;
  -}
  +#endif
   
   /*==============================================================*/
   
  @@ -396,47 +279,101 @@
       unsigned int keylen;
       unsigned int hdrNum;
       int flags;
  +    MDB_cursor * cursor;
  +};
   
  -    unsigned int *list;
  -    unsigned int nlist;
  -    unsigned int ilist;
  -    unsigned char *listdata;
  +struct lmdbDbi_s {
  +    MDB_dbi dbi;
   };
   
   struct lmdbEnv_s {
  -    rpmpkgdb pkgdb;
  -    rpmxdb xdb;
  +    MDB_env * env;
       int refs;
  -
  -    unsigned int hdrNum;
  -    void *data;
  -    unsigned int datalen;
   };
   
   static void closeEnv(rpmdb rdb)
   {
       struct lmdbEnv_s *lmdbenv = rdb->db_dbenv;
  -    if (--lmdbenv->refs == 0) {
  -     if (lmdbenv->xdb) {
  -         rpmxdbClose(lmdbenv->xdb);
  -         rpmlog(RPMLOG_DEBUG, "closed   db index       %s/Index.db\n", 
rpmdbHome(rdb));
  -     }
  -     if (lmdbenv->pkgdb) {
  -         rpmpkgClose(lmdbenv->pkgdb);
  -         rpmlog(RPMLOG_DEBUG, "closed   db index       %s/Packages.db\n", 
rpmdbHome(rdb));
  -     }
  -     if (lmdbenv->data)
  -         free(lmdbenv->data);
  +    if (--lmdbenv->refs <= 0) {
  +     const char *dbhome = rpmdbHome(rdb);
  +     MDB_env * env = (MDB_env *) lmdbenv->env;
  +     if (env)
  +         mdb_env_close(env);
  +     rpmlog(RPMLOG_DEBUG, "closed   db environment %s\n", dbhome);
  +     lmdbenv->env = NULL;
        free(lmdbenv);
  -     rdb->db_dbenv = 0;
  +     rdb->db_dbenv = NULL;
       }
   }
   
  +static void lmdb_assert(MDB_env *env, const char *msg)
  +{
  +    fprintf(stderr, "%s: %s\n", __FUNCTION__, msg);
  +}
  +
   static struct lmdbEnv_s *openEnv(rpmdb rdb)
   {
       struct lmdbEnv_s *lmdbenv = rdb->db_dbenv;
  -    if (!lmdbenv)
  +
  +    if (!lmdbenv) {
  +     const char *dbhome = rpmdbHome(rdb);
  +     unsigned int maxreaders = 16;
  +     MDB_dbi maxdbs = 64;
  +     mdb_size_t mapsize = 10 * 1024 * 1024;
  +     MDB_env * env = NULL;
  +     int rc;
  +
  +     if (mdb_env_create(&env)
  +      || mdb_env_set_maxreaders(env, maxreaders)
  +      || mdb_env_set_maxdbs(env, maxdbs)
  +      || mdb_env_set_mapsize(env, mapsize)
  +      || mdb_env_set_assert(env, lmdb_assert)
  +      || mdb_env_set_userctx(env, rdb))
  +         return NULL;
  +
  +     const char * path = dbhome;
  +
  +     int flags = (
  +#ifdef       REF
  +             MDB_FIXEDMAP |
  +             MDB_NOSUBDIR |
  +             MDB_RDONLY |
  +             MDB_WRITEMAP |
  +             MDB_WRITEMAP |
  +             MDB_NOMETASYNC |
  +             MDB_NOSYNC |
  +             MDB_MAPASYNC |
  +             MDB_NOTLS |
  +             MDB_NOLOCK |
  +             MDB_NORDAHEAD |
  +             MDB_MEMINIT |
  +#endif
  +             0
  +     );
  +     flags |= MDB_FIXEDMAP;
  +
  +     mode_t mode = 0644;
  +
  +     rpmlog(RPMLOG_DEBUG, "opening  db environment %s flags 0x%x mode 
0%o\n", path, flags, mode);
  +
  +     rc = mdb_env_open(env, path, flags, mode);
  +     switch (rc) {
  +     case MDB_SUCCESS:
  +         break;
  +     case MDB_VERSION_MISMATCH:
  +     case MDB_INVALID:
  +     case ENOENT:
  +     case EACCES:
  +     case EAGAIN:
  +     default:
  +         break;
  +     }
  +     if (rc)
  +         return NULL;
  +
        rdb->db_dbenv = lmdbenv = xcalloc(1, sizeof(struct lmdbEnv_s));
  +     lmdbenv->env = env;
  +    }
       lmdbenv->refs++;
       return lmdbenv;
   }
  @@ -444,22 +381,21 @@
   static int lmdb_Close(dbiIndex dbi, unsigned int flags)
   {
       rpmdb rdb = dbi->dbi_rpmdb;
  -    if (dbi->dbi_type != DBI_PRIMARY && dbi->dbi_db) {
  -     rpmidxClose(dbi->dbi_db);
  -     rpmlog(RPMLOG_DEBUG, "closed   db index       %s\n", dbi->dbi_file);
  -    }
  +    struct lmdbEnv_s * lmdbenv = rdb->db_dbenv;
  +    struct lmdbDbi_s * lmdbdbi = (struct lmdbDbi_s *) dbi->dbi_db;
  +    MDB_env * env = lmdbenv->env;
  +    mdb_dbi_close(env, lmdbdbi->dbi);
  +    rpmlog(RPMLOG_DEBUG, "closed   db index       %s\n", dbi->dbi_file);
       if (rdb->db_dbenv)
        closeEnv(rdb);
  -    dbi->dbi_db = 0;
  +    dbi->dbi_db = NULL;
       return 0;
   }
   
   static int lmdb_Open(rpmdb rdb, rpmDbiTagVal rpmtag, dbiIndex * dbip, int 
flags)
   {
       const char *dbhome = rpmdbHome(rdb);
  -    struct lmdbEnv_s *lmdbenv;
       dbiIndex dbi;
  -    int oflags, ioflags;
       int rc = -1;
   
       if (dbip)
  @@ -468,86 +404,80 @@
       if ((dbi = dbiNew(rdb, rpmtag)) == NULL)
        return 1;
   
  -    lmdbenv = openEnv(rdb);
  +    struct lmdbDbi_s * lmdbdbi = (struct lmdbDbi_s *) xcalloc(1, 
sizeof(*lmdbdbi));
  +    struct lmdbEnv_s * lmdbenv = openEnv(rdb);
  +    MDB_env * env = lmdbenv->env;
  +    char * path;
  +
  +    int oflags = (
  +#ifdef       REF
  +     MDB_REVERSEKEY |
  +     MDB_DUPSORT |
  +     MDB_INTEGERKEY |
  +     MDB_DUPFIXED |
  +     MDB_INTEGERDUP |
  +     MDB_REVERSEDUP |
  +     MDB_CREATE |
  +#endif
  +     0
  +     );
  +    oflags |= MDB_CREATE;
   
  -    oflags = O_RDWR;
  -    if ((rdb->db_mode & O_ACCMODE) == O_RDONLY)
  -     oflags = O_RDONLY;
  -    
       if (dbi->dbi_type == DBI_PRIMARY) {
  -     rpmpkgdb pkgdb = 0;
  -     char *path = rpmGetPath(dbhome, "/Packages.db", NULL);
  +     path = rpmGetPath(dbhome, "/Packages", NULL);
        rpmlog(RPMLOG_DEBUG, "opening  db index       %s mode=0x%x\n", path, 
rdb->db_mode);
  -     rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
  -     if (rc && errno == ENOENT) {
  -         oflags = O_RDWR|O_CREAT;
  -         dbi->dbi_flags |= DBI_CREATED;
  -         rc = rpmpkgOpen(&pkgdb, path, oflags, 0666);
  -     }
  -     if (rc) {
  -         perror("rpmpkgOpen");
  -         free(path);
  -         lmdb_Close(dbi, 0);
  -         return 1;
  -     }
  -     free(path);
  -     dbi->dbi_db = lmdbenv->pkgdb = pkgdb;
  -
  -     if ((oflags & (O_RDWR | O_RDONLY)) == O_RDONLY)
  -         dbi->dbi_flags |= DBI_RDONLY;
  +     oflags |= MDB_INTEGERKEY;
       } else {
  -     unsigned int id;
  -     rpmidxdb idxdb = 0;
  -     if (!lmdbenv->pkgdb) {
  -         lmdb_Close(dbi, 0);
  -         return 1;   /* please open primary first */
  -     }
  -     if (!lmdbenv->xdb) {
  -         char *path = rpmGetPath(dbhome, "/Index.db", NULL);
  -         rpmlog(RPMLOG_DEBUG, "opening  db index       %s mode=0x%x\n", 
path, rdb->db_mode);
  -
  -         /* Open indexes readwrite if possible */
  -         ioflags = O_RDWR;
  -         rc = rpmxdbOpen(&lmdbenv->xdb, rdb->db_pkgs->dbi_db, path, ioflags, 
0666);
  -         if (rc && errno == EACCES) {
  -             /* If it is not asked for rw explicitly, try to open ro */
  -             if (!(oflags & O_RDWR)) {
  -                 ioflags = O_RDONLY;
  -                 rc = rpmxdbOpen(&lmdbenv->xdb, rdb->db_pkgs->dbi_db, path, 
ioflags, 0666);
  -             }
  -         } else if (rc && errno == ENOENT) {
  -             ioflags = O_CREAT|O_RDWR;
  -             rc = rpmxdbOpen(&lmdbenv->xdb, rdb->db_pkgs->dbi_db, path, 
ioflags, 0666);
  -         }
  -         if (rc) {
  -             perror("rpmxdbOpen");
  -             free(path);
  -             lmdb_Close(dbi, 0);
  -             return 1;
  -         }
  -         free(path);
  -     }
  -     if (rpmxdbLookupBlob(lmdbenv->xdb, &id, rpmtag, 0, 0) == 
RPMRC_NOTFOUND) {
  -         dbi->dbi_flags |= DBI_CREATED;
  -     }
  -     rpmlog(RPMLOG_DEBUG, "opening  db index       %s tag=%d\n", 
dbiName(dbi), rpmtag);
  -     if (rpmidxOpenXdb(&idxdb, rdb->db_pkgs->dbi_db, lmdbenv->xdb, rpmtag)) {
  -         perror("rpmidxOpenXdb");
  -         lmdb_Close(dbi, 0);
  -         return 1;
  -     }
  -     dbi->dbi_db = idxdb;
  +     path = rpmGetPath(dbhome, dbi->dbi_file, NULL);
  +     oflags |= MDB_DUPSORT;
  +    }
   
  -     if (rpmxdbIsRdonly(lmdbenv->xdb))
  -         dbi->dbi_flags |= DBI_RDONLY;
  +    MDB_txn * parent = NULL;
  +    int tflags = (
  +#ifdef       REF
  +     MDB_RDONLY |
  +     MDB_NOSYNC |
  +     MDB_NOMETASYNC |
  +#endif
  +     0
  +    );
  +    MDB_txn * txn = NULL;
  +    rc = mdb_txn_begin(env, parent, tflags, &txn);
  +    switch (rc) {
  +    case MDB_SUCCESS:
  +     rc = RPMRC_OK;
  +     break;
  +    case MDB_PANIC:
  +    case MDB_MAP_RESIZED:
  +    case MDB_READERS_FULL:
  +    case ENOMEM:
  +    default:
  +     rc = RPMRC_FAIL;
  +     break;
  +    }
  +    if (rc)
  +     return rc;
  +
  +    rc = mdb_dbi_open(txn, path, oflags, &lmdbdbi->dbi);
  +    switch (rc) {
  +    case MDB_SUCCESS:
  +     rc = RPMRC_OK;
  +     break;
  +    case MDB_NOTFOUND:
  +    case MDB_DBS_FULL:
  +    default:
  +     rc = RPMRC_FAIL;
  +     break;
       }
  +    if (rc)
  +     return rc;
   
       if (dbip != NULL)
        *dbip = dbi;
       else
        lmdb_Close(dbi, 0);
   
  -    return 0;
  +    return rc;
   }
   
   static int lmdb_Verify(dbiIndex dbi, unsigned int flags)
  @@ -559,56 +489,8 @@
   {
   }
   
  -static int indexSync(rpmpkgdb pkgdb, rpmxdb xdb)
  -{
  -    int rc = 0;
  -    if (!pkgdb || !xdb)
  -        return 1;
  -    unsigned int generation = 0;
  -    if (rpmpkgLock(pkgdb, 1))
  -        return 1;
  -    if (rpmpkgGeneration(pkgdb, &generation)) {
  -        rpmpkgUnlock(pkgdb, 1);
  -        return 1;
  -    }
  -    rc = rpmxdbSetUserGeneration(xdb, generation);
  -    rpmpkgUnlock(pkgdb, 1);
  -    return rc;
  -}
  -
   static int lmdb_Ctrl(rpmdb rdb, dbCtrlOp ctrl)
   {
  -    struct lmdbEnv_s *lmdbenv = rdb->db_dbenv;
  -
  -    switch (ctrl) {
  -    case DB_CTRL_LOCK_RO:
  -     if (!rdb->db_pkgs)
  -         return 1;
  -     return rpmpkgLock(rdb->db_pkgs->dbi_db, 0);
  -     break;
  -    case DB_CTRL_LOCK_RW:
  -     if (!rdb->db_pkgs)
  -         return 1;
  -     return rpmpkgLock(rdb->db_pkgs->dbi_db, 1);
  -     break;
  -    case DB_CTRL_UNLOCK_RO:
  -     if (!rdb->db_pkgs)
  -         return 1;
  -     return rpmpkgUnlock(rdb->db_pkgs->dbi_db, 0);
  -     break;
  -    case DB_CTRL_UNLOCK_RW:
  -     if (!rdb->db_pkgs)
  -         return 1;
  -     return rpmpkgUnlock(rdb->db_pkgs->dbi_db, 1);
  -     break;
  -    case DB_CTRL_INDEXSYNC:
  -     if (!lmdbenv)
  -         return 1;
  -     return indexSync(lmdbenv->pkgdb, lmdbenv->xdb);
  -     break;
  -    default:
  -     break;
  -    }
       return 0;
   }
   
  @@ -622,53 +504,101 @@
   
   static dbiCursor lmdb_CursorFree(dbiIndex dbi, dbiCursor dbc)
   {
  -    if (dbc) {
  -     if (dbc->list)
  -         free(dbc->list);
  -     if (dbc->listdata)
  -         free(dbc->listdata);
  +    if (dbc)
        free(dbc);
  -    }
       return NULL;
   }
   
  -
  -static void setdata(dbiCursor dbc,  unsigned int hdrNum, unsigned char 
*hdrBlob, unsigned int hdrLen)
  -{
  -    struct lmdbEnv_s *lmdbenv = dbc->dbi->dbi_rpmdb->db_dbenv;
  -    if (lmdbenv->data)
  -     free(lmdbenv->data);
  -    lmdbenv->hdrNum  = hdrNum;
  -    lmdbenv->data    = hdrBlob;
  -    lmdbenv->datalen = hdrLen;
  -}
  -
  -static rpmRC lmdb_pkgdbNew(dbiIndex dbi, dbiCursor dbc,  unsigned int 
*hdrNum)
  -{
  -    int rc = RPMRC_FAIL;
  -    rc = rpmpkgNextPkgIdx(dbc->dbi->dbi_db, hdrNum);
  -    if (!rc)
  -     setdata(dbc, *hdrNum, 0, 0);
  -    return rc;
  -}
  -
   static rpmRC lmdb_pkgdbPut(dbiIndex dbi, dbiCursor dbc,  unsigned int 
hdrNum, unsigned char *hdrBlob, unsigned int hdrLen)
   {
       int rc = RPMRC_FAIL;
  -    rc = rpmpkgPut(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen);
  -    if (!rc) {
  -     dbc->hdrNum = hdrNum;
  -     setdata(dbc, hdrNum, 0, 0);
  +    MDB_cursor * cursor = dbc->cursor;
  +
  +    MDB_val key, data;
  +    key.mv_size = sizeof(hdrNum);
  +    key.mv_data = &hdrNum;
  +    data.mv_size = hdrLen;
  +    data.mv_data = hdrBlob;
  +
  +    int flags = (
  +#ifdef       REF
  +     MDB_CURRENT |
  +     MDB_NODUPDATA |
  +     MDB_NOOVERWRITE |
  +     MDB_RESERVE |
  +     MDB_APPEND |
  +     MDB_APPENDDUP |
  +     MDB_MULTIPLE |
  +#endif
  +     0
  +    );
  +
  +    flags |= MDB_APPEND;
  +    rc = mdb_cursor_put(cursor, &key, &data, flags);
  +    switch (rc) {
  +    case MDB_SUCCESS:
  +     rc = RPMRC_OK;
  +     break;
  +    case MDB_MAP_FULL:
  +    case MDB_TXN_FULL:
  +    case EACCES:
  +    case EINVAL:
  +    default:
  +     rc = RPMRC_FAIL;
  +     break;
       }
  +
       return rc;
   }
   
   static rpmRC lmdb_pkgdbDel(dbiIndex dbi, dbiCursor dbc,  unsigned int hdrNum)
   {
       int rc = RPMRC_FAIL;
  -    dbc->hdrNum = 0;
  -    setdata(dbc, 0, 0, 0);
  -    rc = rpmpkgDel(dbc->dbi->dbi_db, hdrNum);
  +    MDB_cursor * cursor = dbc->cursor;
  +
  +    MDB_val key, data;
  +    key.mv_size = sizeof(hdrNum);
  +    key.mv_data = &hdrNum;
  +    data.mv_size = 0;
  +    data.mv_data = NULL;
  +
  +    MDB_cursor_op op = MDB_SET;
  +
  +    rc = mdb_cursor_get(cursor, &key, &data, op);
  +    switch (rc) {
  +    case MDB_SUCCESS:
  +     rc = RPMRC_OK;
  +     break;
  +    case MDB_NOTFOUND:
  +     rc = RPMRC_NOTFOUND;
  +     break;
  +    case EINVAL:
  +    default:
  +     rc = RPMRC_FAIL;
  +     break;
  +    }
  +
  +    if (!rc) {
  +     unsigned int flags = (
  +#ifdef       REF
  +             MDB_NODUPDATA |
  +#endif
  +             0
  +     );
  +
  +     rc = mdb_cursor_del(cursor, flags);
  +     switch (rc) {
  +     case MDB_SUCCESS:
  +         rc = RPMRC_OK;
  +         break;
  +     case EACCES:
  +     case EINVAL:
  +     default:
  +         rc = RPMRC_FAIL;
  +         break;
  +     }
  +    }
  +
       return rc;
   }
   
  @@ -676,6 +606,8 @@
   static rpmRC lmdb_pkgdbIter(dbiIndex dbi, dbiCursor dbc, unsigned char 
**hdrBlob, unsigned int *hdrLen)
   {
       int rc = RPMRC_FAIL;
  +
  +#ifdef       FIXME
       unsigned int hdrNum;
   
       if (!dbc->list) {
  @@ -691,42 +623,57 @@
        }
        *hdrBlob = 0;
        hdrNum = dbc->list[dbc->ilist];
  +#ifdef       FIXME
        rc = rpmpkgGet(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen);
  +#endif
        if (rc && rc != RPMRC_NOTFOUND)
            break;
        dbc->ilist++;
  -     if (!rc) {
  -         dbc->hdrNum = hdrNum;
  -         setdata(dbc, hdrNum, *hdrBlob, *hdrLen);
  -         break;
  -     }
       }
  +#endif
  +
       return rc;
   }
   
   static rpmRC lmdb_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, 
unsigned char **hdrBlob, unsigned int *hdrLen)
   {
       int rc = RPMRC_FAIL;
  -    struct lmdbEnv_s *lmdbenv = dbc->dbi->dbi_rpmdb->db_dbenv;
   
  -    if (!hdrNum)
  -     return lmdb_pkgdbIter(dbi, dbc, hdrBlob, hdrLen);
  -    if (hdrNum == lmdbenv->hdrNum && lmdbenv->data) {
  -     *hdrBlob = lmdbenv->data;
  -     *hdrLen = lmdbenv->datalen;
  -     return RPMRC_OK;
  -    }
  -    rc = rpmpkgGet(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen);
  -    if (!rc) {
  -     dbc->hdrNum = hdrNum;
  -     setdata(dbc, hdrNum, *hdrBlob, *hdrLen);
  +    MDB_cursor * cursor = dbc->cursor;
  +
  +    MDB_val key, data;
  +    key.mv_size = sizeof(hdrNum);
  +    key.mv_data = &hdrNum;
  +    data.mv_size = 0;
  +    data.mv_data = 0;
  +
  +    MDB_cursor_op op = (hdrNum ? MDB_SET : MDB_NEXT);
  +
  +    rc = mdb_cursor_get(cursor, &key, &data, op);
  +    switch (rc) {
  +    case MDB_SUCCESS:
  +     dbc->key = key.mv_data;
  +     dbc->keylen = key.mv_size;
  +     if (hdrBlob)
  +         *hdrBlob = data.mv_data;
  +     if (hdrLen)
  +         *hdrLen = data.mv_size;
  +     rc = RPMRC_OK;
  +     break;
  +    case MDB_NOTFOUND:
  +     dbc->key = NULL;
  +     dbc->keylen = 0;
  +     rc = RPMRC_NOTFOUND;
  +     break;
  +    case EINVAL:
  +    default:
  +     dbc->key = NULL;
  +     dbc->keylen = 0;
  +     rc = RPMRC_FAIL;
  +     break;
       }
  -    return rc;
  -}
   
  -static unsigned int lmdb_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
  -{
  -    return dbc->hdrNum;
  +    return rc;
   }
   
   
  @@ -743,10 +690,8 @@
       if (pkglist)
        free(pkglist);
       if (*set) {
  -#ifdef       NOTYET
        dbiIndexSetAppendSet(*set, newset, 0);
        dbiIndexSetFree(newset);
  -#endif
       } else
        *set = newset;
   }
  @@ -755,6 +700,8 @@
   static rpmRC lmdb_idxdbIter(dbiIndex dbi, dbiCursor dbc, dbiIndexSet *set)
   {
       int rc = RPMRC_FAIL;
  +
  +#ifdef       FIXME
       if (!dbc->list) {
        /* setup iteration list on first call */
        rc = rpmidxList(dbc->dbi->dbi_db, &dbc->list, &dbc->nlist, 
&dbc->listdata);
  @@ -796,6 +743,8 @@
        if (pkglist)
            free(pkglist);
       }
  +#endif
  +
       return rc;
   }
   
  @@ -859,7 +808,84 @@
       return dbc->key;
   }
   
  +static unsigned int lmdb_pkgdbKey(dbiIndex dbi, dbiCursor dbc)
  +{
  +    if (dbc == NULL || dbc->key == NULL)
  +        return 0;
  +    unsigned int hdrNum = 0;
  +    memcpy(&hdrNum, dbc->key, sizeof(hdrNum));
  +    return hdrNum;   /* XXX byteswap */
   
  +}
  +
  +static unsigned int pkgInstance(dbiIndex dbi, int alloc)
  +{
  +    unsigned int hdrNum = 0;
  +
  +#ifdef       FIXME
  +    if (dbi != NULL && dbi->dbi_type == DBI_PRIMARY) {
  +     dbiCursor dbc;
  +     DBT key, data;
  +     unsigned int firstkey = 0;
  +     union _dbswap mi_offset;
  +     int ret;
  +
  +     memset(&key, 0, sizeof(key));
  +     memset(&data, 0, sizeof(data));
  +
  +     dbc = dbiCursorInit(dbi, alloc ? DBC_WRITE : 0);
  +
  +     /* Key 0 holds the current largest instance, fetch it */
  +     key.data = &firstkey;
  +     key.size = sizeof(firstkey);
  +     ret = dbiCursorGet(dbc, &key, &data, DB_SET);
  +
  +     if (ret == 0 && data.data) {
  +         memcpy(&mi_offset, data.data, sizeof(mi_offset.ui));
  +         if (dbiByteSwapped(dbi) == 1)
  +             _DBSWAP(mi_offset);
  +         hdrNum = mi_offset.ui;
  +     }
  +
  +     if (alloc) {
  +         /* Rather complicated "increment by one", bswapping as needed */
  +         ++hdrNum;
  +         mi_offset.ui = hdrNum;
  +         if (dbiByteSwapped(dbi) == 1)
  +             _DBSWAP(mi_offset);
  +         if (ret == 0 && data.data) {
  +             memcpy(data.data, &mi_offset, sizeof(mi_offset.ui));
  +         } else {
  +             data.data = &mi_offset;
  +             data.size = sizeof(mi_offset.ui);
  +         }
  +
  +         /* Unless we manage to insert the new instance number, we failed */
  +         ret = dbiCursorPut(dbc, &key, &data, DB_KEYLAST);
  +         if (ret) {
  +             hdrNum = 0;
  +             rpmlog(RPMLOG_ERR,
  +                 _("error(%d) allocating new package instance\n"), ret);
  +         }
  +     }
  +     dbiCursorFree(dbi, dbc);
  +    }
  +#endif
  +    
  +    return hdrNum;
  +}
  +
  +static rpmRC lmdb_pkgdbNew(dbiIndex dbi, dbiCursor dbc,  unsigned int 
*hdrNum)
  +{
  +    unsigned int num = 0;
  +    if (dbc == NULL)
  +     return RPMRC_FAIL;
  +    num = pkgInstance(dbc->dbi, 1);
  +    if (!num)
  +     return RPMRC_FAIL;
  +    *hdrNum = num;
  +    return RPMRC_OK;
  +}
   
   struct rpmdbOps_s lmdb_dbops = {
       .open    = lmdb_Open,
  @@ .
______________________________________________________________________
RPM Package Manager                                    http://rpm5.org
CVS Sources Repository                                rpm-cvs@rpm5.org

Reply via email to