Move common code to get a piece of data from cdb into its own function. Signed-off-by: Michael Tokarev <m...@tls.msk.ru> --- On top of the previous patch.
src/util/dict_cdb.c | 89 +++++++++++++++++++++++++++++++++++++-------- 1 file changed, 74 insertions(+), 15 deletions(-) diff --git a/src/util/dict_cdb.c b/src/util/dict_cdb.c index 9b4648b7..fb3e77d5 100644 --- a/src/util/dict_cdb.c +++ b/src/util/dict_cdb.c @@ -85,6 +85,10 @@ typedef struct { DICT dict; /* generic members */ struct cdb cdb; /* cdb structure */ VSTRING *val_buf; /* value result */ +#ifdef TINYCDB_VERSION + VSTRING *key_buf; /* key result */ + unsigned seq_cptr; /* current sequence pointer */ +#endif } DICT_CDBQ; /* query interface */ typedef struct { @@ -94,12 +98,29 @@ typedef struct { char *tmp_path; /* temporary pathname (.tmp) */ } DICT_CDBM; /* rebuild interface */ +/* dict_cdbq_getdata - get data out of the cdb using given buffer */ + +static const char *dict_cdbq_get_data(DICT_CDBQ *dict_cdbq, + VSTRING **bufp, unsigned len, unsigned pos) +{ + VSTRING *buf = *bufp; + if (!buf) + buf = *bufp = vstring_alloc(len < 20 ? 20 : len); + VSTRING_RESET(buf); + VSTRING_SPACE(buf, len); + + if (cdb_read(&dict_cdbq->cdb, vstring_str(buf), len, pos) < 0) + msg_fatal("error reading %s: %m", dict_cdbq->dict.name); + vstring_set_payload_size(buf, len); + VSTRING_TERMINATE(buf); + return vstring_str(buf); +} + /* dict_cdbq_lookup - find database entry, query mode */ static const char *dict_cdbq_lookup(DICT *dict, const char *name) { DICT_CDBQ *dict_cdbq = (DICT_CDBQ *) dict; - unsigned vlen; int status = 0; const char *result = 0; @@ -140,20 +161,8 @@ static const char *dict_cdbq_lookup(DICT *dict, const char *name) msg_fatal("error reading %s: %m", dict->name); if (status) { - vlen = cdb_datalen(&dict_cdbq->cdb); - if (!dict_cdbq->val_buf) - dict_cdbq->val_buf = vstring_alloc(vlen < 20 ? 20 : vlen); - else { - VSTRING_RESET(dict_cdbq->val_buf); - VSTRING_SPACE(dict_cdbq->val_buf, vlen); - } - if (cdb_read(&dict_cdbq->cdb, vstring_str(dict_cdbq->val_buf), - vlen, cdb_datapos(&dict_cdbq->cdb)) < 0) - msg_fatal("error reading %s: %m", dict->name); - vstring_set_payload_size(dict_cdbq->val_buf, vlen); - VSTRING_TERMINATE(dict_cdbq->val_buf); - - result = vstring_str(dict_cdbq->val_buf); + result = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->val_buf, + cdb_datalen(&dict_cdbq->cdb), cdb_datapos(&dict_cdbq->cdb)); } /* No locking so not release the lock. */ @@ -161,6 +170,49 @@ static const char *dict_cdbq_lookup(DICT *dict, const char *name) return (result); } +#ifdef TINYCDB_VERSION + +/* dict_cdbq_sequence - traverse the dictionary */ + +static int dict_cdbq_sequence(DICT *dict, int function, + const char **key, const char **value) +{ + const char *myname = "dict_cdbq_sequence"; + DICT_CDBQ *dict_cdbq = (DICT_CDBQ *)dict; + int status; + + switch (function) { + case DICT_SEQ_FUN_FIRST: + cdb_seqinit(&dict_cdbq->seq_cptr, &dict_cdbq->cdb); + break; + case DICT_SEQ_FUN_NEXT: + if (!dict_cdbq->seq_cptr) + msg_panic("%s: %s: no cursor", myname, dict_cdbq->dict.name); + break; + default: + msg_panic("%s: invalid function %d", myname, function); + } + + status = cdb_seqnext(&dict_cdbq->seq_cptr, &dict_cdbq->cdb); + + if (status < 0) + msg_fatal("error seeking %s: %m", dict_cdbq->dict.name); + + if (!status) { + dict_cdbq->seq_cpos = 0; + return -1; /* not found */ + } + + *key = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->key_buf, + cdb_keylen(&dict_cdbq->cdb), cdb_keypos(&dict_cdbq->cdb)); + *value = dict_cdbq_get_data(dict_cdbq, &dict_cdbq->val_buf, + cdb_datalen(&dict_cdbq->cdb), cdb_datapos(&dict_cdbq->cdb)); + + return 0; +} + +#endif /* TINYCDB_VERSION */ + /* dict_cdbq_close - close data base, query mode */ static void dict_cdbq_close(DICT *dict) @@ -173,6 +225,10 @@ static void dict_cdbq_close(DICT *dict) vstring_free(dict->fold_buf); if (dict_cdbq->val_buf) vstring_free(dict_cdbq->val_buf); +#ifdef TINYCDB_VERSION + if (dict_cdbq->key_buf) + vstring_free(dict_cdbq->key_buf); +#endif dict_free(dict); } @@ -205,8 +261,11 @@ static DICT *dict_cdbq_open(const char *path, int dict_flags) cdb_path, sizeof(*dict_cdbq)); dict_cdbq->val_buf = 0; #if defined(TINYCDB_VERSION) + dict_cdbq->key_buf = 0; + dict_cdbq->seq_cptr = 0; if (cdb_init(&(dict_cdbq->cdb), fd) != 0) msg_fatal("dict_cdbq_open: unable to init %s: %m", cdb_path); + dict_cdbq->dict.sequence = dict_cdbq_sequence; #else cdb_init(&(dict_cdbq->cdb), fd); #endif -- 2.39.5 _______________________________________________ Postfix-devel mailing list -- postfix-devel@postfix.org To unsubscribe send an email to postfix-devel-le...@postfix.org