--- ./lib/backend/ndb/glue.c.orig +++ ./lib/backend/ndb/glue.c @@ -19,6 +19,8 @@ struct dbiCursor_s { const void *key; unsigned int keylen; unsigned int hdrNum; + void *data; + unsigned int datalen; int flags; unsigned int *list; @@ -33,7 +35,7 @@ struct ndbEnv_s { int refs; int dofsync; - unsigned int hdrNum; + unsigned int hdrNum; /* free for adoption */ void *data; unsigned int datalen; }; @@ -278,6 +280,40 @@ static int ndb_Ctrl(rpmdb rdb, dbCtrlOp ctrl) return 0; } +static void setenvdata(struct ndbEnv_s *ndbenv, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) +{ + if (ndbenv->data) + free(ndbenv->data); + ndbenv->hdrNum = hdrNum; + ndbenv->data = hdrBlob; + ndbenv->datalen = hdrLen; +} + +static void setdata(dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) +{ + struct ndbEnv_s *ndbenv = dbc->dbi->dbi_rpmdb->db_dbenv; + if (ndbenv->data) + setenvdata(ndbenv, 0, 0, 0); /* clear dbenv cache */ + if (dbc->data) + free(dbc->data); + dbc->hdrNum = hdrNum; + dbc->data = hdrBlob; + dbc->datalen = hdrLen; +} + +static void adoptdata(dbiCursor dbc) +{ + struct ndbEnv_s *ndbenv = dbc->dbi->dbi_rpmdb->db_dbenv; + if (dbc->data) + free(dbc->data); + dbc->hdrNum = ndbenv->hdrNum; + dbc->data = ndbenv->data; + dbc->datalen = ndbenv->datalen; + ndbenv->hdrNum = 0; + ndbenv->data = 0; + ndbenv->datalen = 0; +} + static dbiCursor ndb_CursorInit(dbiIndex dbi, unsigned int flags) { dbiCursor dbc = xcalloc(1, sizeof(*dbc)); @@ -293,21 +329,17 @@ static dbiCursor ndb_CursorFree(dbiIndex dbi, dbiCursor dbc) free(dbc->list); if (dbc->listdata) free(dbc->listdata); + if (dbc->data) { + /* release data into dbenv so that the next cursor can adopt it */ + struct ndbEnv_s *ndbenv = dbc->dbi->dbi_rpmdb->db_dbenv; + setenvdata(ndbenv, dbc->hdrNum, dbc->data, dbc->datalen); + } free(dbc); } return NULL; } -static void setdata(dbiCursor dbc, unsigned int hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) -{ - struct ndbEnv_s *ndbenv = dbc->dbi->dbi_rpmdb->db_dbenv; - if (ndbenv->data) - free(ndbenv->data); - ndbenv->hdrNum = hdrNum; - ndbenv->data = hdrBlob; - ndbenv->datalen = hdrLen; -} static rpmRC ndb_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, unsigned char *hdrBlob, unsigned int hdrLen) { @@ -324,7 +356,6 @@ static rpmRC ndb_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, un rc = rpmpkgPut(dbc->dbi->dbi_db, hnum, hdrBlob, hdrLen); if (!rc) { - dbc->hdrNum = hnum; setdata(dbc, hnum, 0, 0); *hdrNum = hnum; } @@ -333,7 +364,6 @@ static rpmRC ndb_pkgdbPut(dbiIndex dbi, dbiCursor dbc, unsigned int *hdrNum, un static rpmRC ndb_pkgdbDel(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum) { - dbc->hdrNum = 0; setdata(dbc, 0, 0, 0); return rpmpkgDel(dbc->dbi->dbi_db, hdrNum); } @@ -362,7 +392,6 @@ static rpmRC ndb_pkgdbIter(dbiIndex dbi, dbiCursor dbc, unsigned char **hdrBlob, break; dbc->ilist++; if (!rc) { - dbc->hdrNum = hdrNum; setdata(dbc, hdrNum, *hdrBlob, *hdrLen); break; } @@ -377,16 +406,16 @@ static rpmRC ndb_pkgdbGet(dbiIndex dbi, dbiCursor dbc, unsigned int hdrNum, unsi if (!hdrNum) return ndb_pkgdbIter(dbi, dbc, hdrBlob, hdrLen); - if (hdrNum == ndbenv->hdrNum && ndbenv->data) { - *hdrBlob = ndbenv->data; - *hdrLen = ndbenv->datalen; + if (!dbc->data && ndbenv->data) + adoptdata(dbc); + if (dbc->data && hdrNum == dbc->hdrNum) { + *hdrBlob = dbc->data; + *hdrLen = dbc->datalen; return RPMRC_OK; } rc = rpmpkgGet(dbc->dbi->dbi_db, hdrNum, hdrBlob, hdrLen); - if (!rc) { - dbc->hdrNum = hdrNum; + if (!rc) setdata(dbc, hdrNum, *hdrBlob, *hdrLen); - } return rc; }