On Sun, Jul 17, 2011 at 12:32 AM, Rémy Oudompheng <remyoudompheng@gmail.com> wrote:
Hello,
I am thinking an iterator-like interface for database reading could be useful. The most obvious example use is the pkgfile functionality. It could be a convenient tool to do one-pass work on databases without loading them completely in memory, which can be impossible for databases with files info (I don't think everyone can load the whole [community] database using libalpm standard structures).
Here's a patch that roughly shows what I am thinking about: only the code for the "local" backend is shown.
diff --git a/lib/libalpm/alpm.h b/lib/libalpm/alpm.h index 6e1e4bc..986e9a1 100644 --- a/lib/libalpm/alpm.h +++ b/lib/libalpm/alpm.h
[...]
+struct local_dbreader_t { + alpm_handle_t *handle; + alpm_pkg_t *(*getitem) (alpm_dbreader_t*); + DIR* dbdir; + const char *dbpath; + char finished; +};
How about refactoring this even more into a generic alpm_iterator_t? Something like: struct alpm_iterator_t { void *(*peek)(void *context); void *(*next)(void *context); void *context; }; The context member would reference something similar to your local_dbreader_t structure (just without the getitem member) which contains all the state, and gets passed into peek() and next(). Then you'd have a consistent API for any iterators alpm might use: void *alpm_iter_peek(struct alpm_iterator_t *iter) { // <insert sanity checks> return iter->peek(iter->context); } void *alpm_iter_next(struct alpm_iterator_t *iter) { // <insert sanity checks> return iter->next(iter->context); } struct *alpm_iter_t db_iter = alpm_open_dbdir(db->handle, dbpath); // or alpm_db_iter()? pmpkg_t *pkg; pkg = alpm_iter_peek(db_iter); // NULL pkg = alpm_iter_next(db_iter); // a pmpkg_t* pkg = alpm_iter_peek(db_iter); // same pkmpkg_t* as above