Skip to content

Commit

Permalink
Implement a key-only rpmdb index iterator
Browse files Browse the repository at this point in the history
The regular index iterator grabs the associated data too, which we
don't always need. The data associated with indexes is relatively
lightweight, but as with everything, it adds up if in the millions scale.
  • Loading branch information
pmatilai committed Dec 5, 2019
1 parent 61ea5a8 commit 16d9d3a
Show file tree
Hide file tree
Showing 6 changed files with 51 additions and 20 deletions.
18 changes: 10 additions & 8 deletions lib/backend/db3.c
Expand Up @@ -1008,7 +1008,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
dbiIndexSet *set, int searchType)
{
rpmRC rc = RPMRC_FAIL; /* assume failure */
if (dbi != NULL && dbc != NULL && set != NULL) {
if (dbi != NULL && dbc != NULL) {
int cflags = DB_NEXT;
int dbrc;
DBT data, key;
Expand All @@ -1033,12 +1033,14 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
if (searchType == DBC_PREFIX_SEARCH &&
(key.size < keylen || memcmp(key.data, keyp, keylen) != 0))
break;
dbt2set(dbi, &data, &newset);
if (*set == NULL) {
*set = newset;
} else {
dbiIndexSetAppendSet(*set, newset, 0);
dbiIndexSetFree(newset);
if (set) {
dbt2set(dbi, &data, &newset);
if (*set == NULL) {
*set = newset;
} else {
dbiIndexSetAppendSet(*set, newset, 0);
dbiIndexSetFree(newset);
}
}
if (searchType != DBC_PREFIX_SEARCH)
break;
Expand All @@ -1048,7 +1050,7 @@ static rpmRC db3_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
}

/* fixup result status for prefix search */
if (searchType == DBC_PREFIX_SEARCH) {
if (searchType == DBC_PREFIX_SEARCH && set) {
if (dbrc == DB_NOTFOUND && *set != NULL && (*set)->count > 0)
dbrc = 0;
else if (dbrc == 0 && (*set == NULL || (*set)->count == 0))
Expand Down
18 changes: 10 additions & 8 deletions lib/backend/lmdb.c
Expand Up @@ -574,7 +574,7 @@ static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
dbiIndexSet *set, int searchType)
{
rpmRC rc = RPMRC_FAIL; /* assume failure */
if (dbi != NULL && dbc != NULL && set != NULL) {
if (dbi != NULL && dbc != NULL) {
int cflags = MDB_NEXT;
int dbrc;
MDB_val key = { 0, NULL };
Expand All @@ -598,12 +598,14 @@ static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
if (searchType == DBC_PREFIX_SEARCH &&
(key.mv_size < keylen || memcmp(key.mv_data, keyp, keylen) != 0))
break;
dbt2set(dbi, &data, &newset);
if (*set == NULL) {
*set = newset;
} else {
dbiIndexSetAppendSet(*set, newset, 0);
dbiIndexSetFree(newset);
if (set) {
dbt2set(dbi, &data, &newset);
if (*set == NULL) {
*set = newset;
} else {
dbiIndexSetAppendSet(*set, newset, 0);
dbiIndexSetFree(newset);
}
}
if (searchType != DBC_PREFIX_SEARCH)
break;
Expand All @@ -613,7 +615,7 @@ static rpmRC lmdb_idxdbGet(dbiIndex dbi, dbiCursor dbc, const char *keyp, size_t
}

/* fixup result status for prefix search */
if (searchType == DBC_PREFIX_SEARCH) {
if (searchType == DBC_PREFIX_SEARCH && set) {
if (dbrc == MDB_NOTFOUND && *set != NULL && (*set)->count > 0)
dbrc = 0;
else if (dbrc == 0 && (*set == NULL || (*set)->count == 0))
Expand Down
8 changes: 8 additions & 0 deletions lib/backend/ndb/glue.c
Expand Up @@ -409,6 +409,14 @@ static rpmRC ndb_idxdbIter(dbiIndex dbi, dbiCursor dbc, dbiIndexSet *set)
break;
}
#endif
if (set == NULL) {
dbc->key = k;
dbc->keylen = kl;
dbc->ilist += 2;
rc = RPMRC_OK;
break;
}

pkglist = 0;
pkglistn = 0;
rc = rpmidxGet(dbc->dbi->dbi_db, k, kl, &pkglist, &pkglistn);
Expand Down
8 changes: 5 additions & 3 deletions lib/backend/sqlite.c
Expand Up @@ -578,15 +578,17 @@ static rpmRC sqlite_idxdbIter(dbiIndex dbi, dbiCursor dbc, const char *keyp, siz
rc = sqlite3_step(dbc->stmt);

if (rc == SQLITE_ROW) {
dbiCursor kc = dbiCursorInit(dbi, 0);
if (dbc->ctype == SQLITE_TEXT) {
dbc->key = sqlite3_column_text(dbc->stmt, 0);
} else {
dbc->key = sqlite3_column_blob(dbc->stmt, 0);
}
dbc->keylen = sqlite3_column_bytes(dbc->stmt, 0);
rc = sqlite_idxdbByKey(dbi, kc, dbc->key, dbc->keylen, set);
dbiCursorFree(dbi, kc);
if (set) {
dbiCursor kc = dbiCursorInit(dbi, 0);
rc = sqlite_idxdbByKey(dbi, kc, dbc->key, dbc->keylen, set);
dbiCursorFree(dbi, kc);
}
rc = RPMRC_OK;
} else if (rc == SQLITE_DONE) {
if (searchType == DBC_PREFIX_SEARCH && (*set))
Expand Down
11 changes: 10 additions & 1 deletion lib/rpmdb.c
Expand Up @@ -298,6 +298,7 @@ struct rpmdbIndexIterator_s {
dbiCursor ii_dbc;
dbiIndexSet ii_set;
unsigned int *ii_hdrNums;
int skipdata;
};

static rpmdb rpmdbRock;
Expand Down Expand Up @@ -1885,6 +1886,13 @@ rpmdbIndexIterator rpmdbIndexIteratorInit(rpmdb db, rpmDbiTag rpmtag)
return ii;
}

rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag)
{
rpmdbIndexIterator ki = rpmdbIndexIteratorInit(db, rpmtag);
ki->skipdata = 1;
return ki;
}

int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * keylen)
{
int rc;
Expand All @@ -1899,7 +1907,8 @@ int rpmdbIndexIteratorNext(rpmdbIndexIterator ii, const void ** key, size_t * ke
/* free old data */
ii->ii_set = dbiIndexSetFree(ii->ii_set);

rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0, &ii->ii_set, DBC_NORMAL_SEARCH);
rc = idxdbGet(ii->ii_dbi, ii->ii_dbc, NULL, 0,
ii->skipdata ? NULL : &ii->ii_set, DBC_NORMAL_SEARCH);

*key = idxdbKey(ii->ii_dbi, ii->ii_dbc, &iikeylen);
*keylen = iikeylen;
Expand Down
8 changes: 8 additions & 0 deletions lib/rpmdb.h
Expand Up @@ -153,6 +153,14 @@ Header rpmdbNextIterator(rpmdbMatchIterator mi);
*/
rpmdbMatchIterator rpmdbFreeIterator(rpmdbMatchIterator mi);

/** \ingroup rpmdb
* Get an iterator for index keys
* @param db rpm database
* @param rpmtag the index to iterate over
* @return the index iterator
*/
rpmdbIndexIterator rpmdbIndexKeyIteratorInit(rpmdb db, rpmDbiTag rpmtag);

/** \ingroup rpmdb
* Get an iterator for an index
* @param db rpm database
Expand Down

0 comments on commit 16d9d3a

Please sign in to comment.