* Jrgen Htzel <juergen@hoetzel.info>
_alpm_db_load_pkgcache: use mergesort to improve performance
This commit is contained in:
parent
2ae56f4bc9
commit
2a457c5319
3 changed files with 87 additions and 3 deletions
|
@ -44,6 +44,7 @@
|
||||||
int _alpm_db_load_pkgcache(pmdb_t *db, unsigned char infolevel)
|
int _alpm_db_load_pkgcache(pmdb_t *db, unsigned char infolevel)
|
||||||
{
|
{
|
||||||
pmpkg_t *info;
|
pmpkg_t *info;
|
||||||
|
int count = 0;
|
||||||
/* The group cache needs INFRQ_DESC as well */
|
/* The group cache needs INFRQ_DESC as well */
|
||||||
/*unsigned char infolevel = INFRQ_DEPENDS | INFRQ_DESC;*/
|
/*unsigned char infolevel = INFRQ_DEPENDS | INFRQ_DESC;*/
|
||||||
|
|
||||||
|
@ -61,9 +62,11 @@ int _alpm_db_load_pkgcache(pmdb_t *db, unsigned char infolevel)
|
||||||
info->origin = PKG_FROM_CACHE;
|
info->origin = PKG_FROM_CACHE;
|
||||||
info->data = db;
|
info->data = db;
|
||||||
/* add to the collection */
|
/* add to the collection */
|
||||||
db->pkgcache = _alpm_list_add_sorted(db->pkgcache, info, _alpm_pkg_cmp);
|
db->pkgcache = _alpm_list_add(db->pkgcache, info);
|
||||||
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
db->pkgcache = _alpm_list_msort(db->pkgcache, count, _alpm_pkg_cmp);
|
||||||
return(0);
|
return(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -134,6 +134,84 @@ pmlist_t *_alpm_list_add_sorted(pmlist_t *list, void *data, _alpm_fn_cmp fn)
|
||||||
return(list);
|
return(list);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* return nth element from list (starting with 0) */
|
||||||
|
pmlist_t* _alpm_list_nth(pmlist_t *list, int n) {
|
||||||
|
while (n--)
|
||||||
|
list = list->next;
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* merge the two sorted sublists into one sorted list */
|
||||||
|
pmlist_t* _alpm_list_mmerge(pmlist_t *left, pmlist_t *right, _alpm_fn_cmp fn) {
|
||||||
|
pmlist_t *newlist;
|
||||||
|
pmlist_t *lp;
|
||||||
|
|
||||||
|
if (left == NULL)
|
||||||
|
return right;
|
||||||
|
if (right == NULL)
|
||||||
|
return left;
|
||||||
|
|
||||||
|
if (fn(left->data, right->data) <= 0) {
|
||||||
|
newlist = left;
|
||||||
|
left = left->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
newlist = right;
|
||||||
|
right = right->next;
|
||||||
|
}
|
||||||
|
newlist->prev = NULL;
|
||||||
|
newlist->next = NULL;
|
||||||
|
newlist->last = NULL;
|
||||||
|
lp = newlist;
|
||||||
|
|
||||||
|
while ((left != NULL) && (right != NULL)) {
|
||||||
|
if (fn(left->data, right->data) <= 0) {
|
||||||
|
lp->next = left;
|
||||||
|
left->prev = lp;
|
||||||
|
left = left->next;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
lp->next = right;
|
||||||
|
right->prev = lp;
|
||||||
|
right = right->next;
|
||||||
|
}
|
||||||
|
lp = lp->next;
|
||||||
|
lp->next = NULL;
|
||||||
|
newlist->last = lp;
|
||||||
|
}
|
||||||
|
if (left != NULL) {
|
||||||
|
lp->next = left;
|
||||||
|
left->prev = lp;
|
||||||
|
newlist->last = left->last;
|
||||||
|
}
|
||||||
|
else if (right != NULL) {
|
||||||
|
lp->next = right;
|
||||||
|
right->prev = lp;
|
||||||
|
newlist->last = right->last;
|
||||||
|
}
|
||||||
|
return newlist;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* sort an list of size n using mergesort algorithm */
|
||||||
|
pmlist_t* _alpm_list_msort(pmlist_t *list, int len, _alpm_fn_cmp fn) {
|
||||||
|
if (len > 1 ) {
|
||||||
|
pmlist_t *left = list;
|
||||||
|
pmlist_t *lastleft = _alpm_list_nth(list, len/2 - 1);
|
||||||
|
pmlist_t *right = lastleft->next;
|
||||||
|
/* update rights last element, to previous last element*/
|
||||||
|
right->last = left->last;
|
||||||
|
/* update lefts last element */
|
||||||
|
left->last = lastleft;
|
||||||
|
/* terminate first list */
|
||||||
|
lastleft->next = NULL;
|
||||||
|
|
||||||
|
left = _alpm_list_msort(left, len/2, fn);
|
||||||
|
right = _alpm_list_msort(right, len - (len/2), fn);
|
||||||
|
list = _alpm_list_mmerge(left, right, fn);
|
||||||
|
}
|
||||||
|
return list;
|
||||||
|
}
|
||||||
|
|
||||||
/* Remove an item in a list. Use the given comparaison function to find the
|
/* Remove an item in a list. Use the given comparaison function to find the
|
||||||
* item.
|
* item.
|
||||||
* If the item is found, 'data' is pointing to the removed element.
|
* If the item is found, 'data' is pointing to the removed element.
|
||||||
|
|
|
@ -43,6 +43,9 @@ pmlist_t *_alpm_list_new(void);
|
||||||
void _alpm_list_free(pmlist_t *list, _alpm_fn_free fn);
|
void _alpm_list_free(pmlist_t *list, _alpm_fn_free fn);
|
||||||
pmlist_t *_alpm_list_add(pmlist_t *list, void *data);
|
pmlist_t *_alpm_list_add(pmlist_t *list, void *data);
|
||||||
pmlist_t *_alpm_list_add_sorted(pmlist_t *list, void *data, _alpm_fn_cmp fn);
|
pmlist_t *_alpm_list_add_sorted(pmlist_t *list, void *data, _alpm_fn_cmp fn);
|
||||||
|
pmlist_t* _alpm_list_mmerge(pmlist_t *left, pmlist_t *right, _alpm_fn_cmp fn);
|
||||||
|
pmlist_t* _alpm_list_msort(pmlist_t *list, int len, _alpm_fn_cmp fn);
|
||||||
|
pmlist_t* _alpm_list_nth(pmlist_t *list, int n);
|
||||||
pmlist_t *_alpm_list_remove(pmlist_t *haystack, void *needle, _alpm_fn_cmp fn, void **data);
|
pmlist_t *_alpm_list_remove(pmlist_t *haystack, void *needle, _alpm_fn_cmp fn, void **data);
|
||||||
int _alpm_list_count(const pmlist_t *list);
|
int _alpm_list_count(const pmlist_t *list);
|
||||||
int _alpm_list_is_in(void *needle, pmlist_t *haystack);
|
int _alpm_list_is_in(void *needle, pmlist_t *haystack);
|
||||||
|
|
Loading…
Add table
Reference in a new issue